Release Tizen 2.0 beta
authorDonghee Ye <donghee.ye@samsung.com>
Tue, 21 Aug 2012 11:11:37 +0000 (20:11 +0900)
committerDonghee Ye <donghee.ye@samsung.com>
Tue, 21 Aug 2012 11:11:37 +0000 (20:11 +0900)
Change-Id: I821dca81bd498d4dde02d6fab091b80a6f00b110

65 files changed:
.CONTACTS_SVC_AB_CHANGED [deleted file]
.CONTACTS_SVC_DB_CHANGED [deleted file]
.CONTACTS_SVC_FAVOR_CHANGED [deleted file]
.CONTACTS_SVC_GROUP_CHANGED [deleted file]
CMakeLists.txt
build-util/generator.sh
debian/changelog
debian/contacts-service-bin.postinst.in
debian/control
debian/libcontacts-service.postinst.in
debian/rules
helper/CMakeLists.txt
helper/helper-socket.c
helper/internal.h
helper/normalize.c
helper/sim.c
helper/sim.h
helper/sqlite.c
helper/utils.c
packaging/contacts-service.spec
res/.CONTACTS_SVC_GROUP_REL_CHANGED [moved from .CONTACTS_SVC_SPEED_CHANGED with 100% similarity]
res/.CONTACTS_SVC_LINK_CHANGED [moved from .CONTACTS_SVC_PLOG_CHANGED with 100% similarity]
res/.CONTACTS_SVC_RESTRICTION_CHECK [moved from .CONTACTS_SVC_MISSED_CHANGED with 100% similarity]
schema.sql
src/cts-addressbook.c
src/cts-contact-read.c [new file with mode: 0755]
src/cts-contact-write.c [moved from src/cts-contact.c with 67% similarity]
src/cts-contact.h
src/cts-favorite.c
src/cts-favorite.h
src/cts-group.c
src/cts-im.c [new file with mode: 0755]
src/cts-im.h [new file with mode: 0755]
src/cts-list-filter.c [new file with mode: 0755]
src/cts-list-filter.h [new file with mode: 0755]
src/cts-list-info.c
src/cts-list.c
src/cts-list.h
src/cts-normalize.h
src/cts-person.c [new file with mode: 0755]
src/cts-person.h [new file with mode: 0755]
src/cts-phonelog.c
src/cts-phonelog.h
src/cts-restriction.c [new file with mode: 0755]
src/cts-restriction.h [new file with mode: 0755]
src/cts-schema.h
src/cts-service.c
src/cts-socket.c
src/cts-socket.h
src/cts-sqlite.c
src/cts-struct-ext.c
src/cts-struct.c
src/cts-struct.h
src/cts-types.h
src/cts-utils.c
src/cts-utils.h
test/Makefile
test/SIMexport-test.c [new file with mode: 0755]
test/change-noti-test.c
test/group-test.c
test/myprofile-test.c [new file with mode: 0755]
test/person-test.c [new file with mode: 0755]
test/phonelog-test.c
test/restriction-test.c [new file with mode: 0755]
test/test-log.h [new file with mode: 0755]

diff --git a/.CONTACTS_SVC_AB_CHANGED b/.CONTACTS_SVC_AB_CHANGED
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/.CONTACTS_SVC_DB_CHANGED b/.CONTACTS_SVC_DB_CHANGED
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/.CONTACTS_SVC_FAVOR_CHANGED b/.CONTACTS_SVC_FAVOR_CHANGED
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/.CONTACTS_SVC_GROUP_CHANGED b/.CONTACTS_SVC_GROUP_CHANGED
deleted file mode 100644 (file)
index e69de29..0000000
index 7870785..27eab50 100755 (executable)
@@ -14,7 +14,7 @@ SET(EXEC_PREFIX "\${prefix}")
 SET(LIBDIR "\${prefix}/lib")
 SET(INCLUDEDIR "\${prefix}/${DEST_INCLUDE_DIR}")
 SET(VERSION_MAJOR 0)
-SET(VERSION "${VERSION_MAJOR}.6.1")
+SET(VERSION "${VERSION_MAJOR}.6.12")
 
 EXECUTE_PROCESS(COMMAND build-util/generator.sh)
 
@@ -59,6 +59,8 @@ INSTALL(FILES ${NOTI_FILES} DESTINATION /opt/data/contacts-svc
                PERMISSIONS OWNER_WRITE OWNER_READ GROUP_WRITE GROUP_READ)
 
 INSTALL(DIRECTORY DESTINATION /opt/data/contacts-svc/img/vcard)
+INSTALL(DIRECTORY DESTINATION /opt/data/contacts-svc/img/my)
+INSTALL(DIRECTORY DESTINATION /opt/data/contacts-svc/img/group)
 
 ADD_SUBDIRECTORY(helper)
 
index 0bc0730..7078d54 100755 (executable)
@@ -31,8 +31,10 @@ cat ../include/contacts-svc.head > ../include/contacts-svc.h
 ./API-generator ../src/cts-errors.h >> ../include/contacts-svc.h
 ./API-generator ../src/cts-addressbook.h >> ../include/contacts-svc.h
 ./API-generator ../src/cts-contact.h >> ../include/contacts-svc.h
+./API-generator ../src/cts-person.h >> ../include/contacts-svc.h
 ./API-generator ../src/cts-normalize.h >> ../include/contacts-svc.h
 ./API-generator ../src/cts-list.h >> ../include/contacts-svc.h
+./API-generator ../src/cts-list-filter.h >> ../include/contacts-svc.h
 ./API-generator ../src/cts-utils.h >> ../include/contacts-svc.h
 ./API-generator ../src/cts-vcard.h >> ../include/contacts-svc.h
 cat ../include/contacts-svc.tail >> ../include/contacts-svc.h
index 89b5cd9..6bb3db3 100644 (file)
@@ -1,3 +1,11 @@
+contacts-service (0.6.12-1) unstable; urgency=low
+
+  * Release Tizen 2.0 beta
+  * Git: framework/pim/contacts-service
+  * Tag: contacts-service_0.6.12-1
+
+ -- DongHee Ye <donghee.ye@samsung.com>  Wed, 08 Aug 2012 10:34:40 +0900
+
 contacts-service (0.6.1-10) unstable; urgency=low
 
   * release
index 52e46f0..a853e91 100755 (executable)
@@ -25,4 +25,4 @@ chmod 660 /opt/dbspace/.contacts-svc.db-journal
 
 chmod 755 /etc/rc.d/init.d/contacts-svc-helper.sh
 
-vconftool set -t int db/service/contacts/default_lang 1
+vconftool set -t int file/private/contacts-service/default_lang 1
index e061d95..3d3eb07 100644 (file)
@@ -2,7 +2,7 @@ Source: contacts-service
 Section: devel
 Priority: extra
 Maintainer: Youngjae Shin <yj99.shin@samsung.com>, Donghee Ye <donghee.ye@samsung.com>
-Build-Depends: debhelper (>= 5), libslp-db-util-dev, libsqlite3-dev, libglib2.0-dev, dlog-dev, libvconf-dev, libvconf-keys-dev, libslp-tapi-dev, libicu-dev
+Build-Depends: debhelper (>= 5), libslp-db-util-dev, libsqlite3-dev, libglib2.0-dev, dlog-dev, libvconf-dev, libvconf-keys-dev, libtapi-dev, libicu-dev, libsystemd-daemon-dev
 Standards-Version: 3.7.2
 Homepage: N/A
 
index d76c3a6..5f04744 100755 (executable)
@@ -7,16 +7,19 @@ then
        #db_contact
    chown :6005 -R /opt/data/contacts-svc/img
    chown :6005 /opt/data/contacts-svc/.CONTACTS_SVC_*_CHANGED
-   vconftool set -t int db/service/contacts/name_sorting_order 0 -g 6005
-   vconftool set -t int db/service/contacts/name_display_order 0 -g 6005
+       #db_sns
+   chown :6016 /opt/data/contacts-svc/.CONTACTS_SVC_RESTRICTION_CHECK
+   vconftool set -t int db/contacts-svc/name_sorting_order 0 -g 6005
+   vconftool set -t int db/contacts-svc/name_display_order 0 -g 6005
 else
-   vconftool set -t int db/service/contacts/name_sorting_order 0
-   vconftool set -t int db/service/contacts/name_display_order 0
+   vconftool set -t int db/contacts-svc/name_sorting_order 0
+   vconftool set -t int db/contacts-svc/name_display_order 0
 fi
 
 # Change file permissions
 # chmod 644 /usr/lib/libcontacts-service.so
 chmod 660 /opt/data/contacts-svc/.CONTACTS_SVC_*_CHANGED
+chmod 660 /opt/data/contacts-svc/.CONTACTS_SVC_RESTRICTION_CHECK
 chmod 770 -R /opt/data/contacts-svc/img
 
 echo "Done"
index f2b94ce..5b1c2fe 100755 (executable)
@@ -55,7 +55,7 @@ clean:
        # Add here commands to clean up after the build process.
        -$(MAKE) clean
        rm -rf CMakeCache.txt CMakeFiles cmake_install.cmake Makefile install_manifest.txt
-       cd helper; rm -rf CMakeCache.txt CMakeFiles cmake_install.cmake Makefile install_manifest.txt
+       cd helper; rm -rf CMakeCache.txt CMakeFiles cmake_install.cmake Makefile install_manifest.txt contacts-svc-helper
 
        for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
                rm -f $${f%.in}; \
index 594c888..1de9483 100755 (executable)
@@ -7,7 +7,7 @@ SET(TARGET contacts-svc-helper)
 FILE(GLOB SRCS *.c)
 #SET(SRCS main.c schema-recovery.c)
 
-pkg_check_modules(helper_pkgs REQUIRED tapi icu-i18n)
+pkg_check_modules(helper_pkgs REQUIRED tapi icu-i18n libsystemd-daemon)
 
 UNSET(EXTRA_CFLAGS)
 FOREACH(flag ${helper_pkgs_CFLAGS})
index f66f0b1..a9aae70 100755 (executable)
@@ -26,6 +26,7 @@
 #include <sys/un.h>
 #include <errno.h>
 #include <contacts-svc.h>
+#include <sd-daemon.h>
 
 #include "internal.h"
 #include "cts-schema.h"
@@ -73,31 +74,32 @@ static inline int helper_safe_read(int fd, char *buf, int buf_size)
 }
 
 
-static void helper_discard_msg(int fd, int size)
+static void helper_discard_msg(GIOChannel *src, int size)
 {
-       int ret;
+       gsize len;
+       GError *gerr = NULL;
        char dummy[CTS_SQL_MAX_LEN];
 
        while (size) {
                if (sizeof(dummy) < size) {
-                       ret = read(fd, dummy, sizeof(dummy));
-                       if (-1 == ret) {
-                               if (EINTR == errno)
-                                       continue;
-                               else
-                                       return;
+                       g_io_channel_read_chars(src, dummy, sizeof(dummy), &len, &gerr);
+                       if (gerr) {
+                               ERR("g_io_channel_read_chars() Failed(%s)", gerr->message);
+                               g_error_free(gerr);
+                               return;
                        }
-                       size -= ret;
+
+                       size -= len;
                }
                else {
-                       ret = read(fd, dummy, size);
-                       if (-1 == ret) {
-                               if (EINTR == errno)
-                                       continue;
-                               else
-                                       return;
+                       g_io_channel_read_chars(src, dummy, size, &len, &gerr);
+                       if (gerr) {
+                               ERR("g_io_channel_read_chars() Failed(%s)", gerr->message);
+                               g_error_free(gerr);
+                               return;
                        }
-                       size -= ret;
+
+                       size -= len;
                }
        }
 }
@@ -141,6 +143,32 @@ static void helper_handle_import_sim(GIOChannel *src)
        }
 }
 
+static void helper_handle_export_sim(GIOChannel *src, int size)
+{
+       int ret;
+       gsize len;
+       GError *gerr = NULL;
+       char receiver[CTS_SQL_MAX_LEN];
+
+       g_io_channel_read_chars(src, receiver, size, &len, &gerr);
+       if (gerr) {
+               ERR("g_io_channel_read_chars() Failed(%s)", gerr->message);
+               g_error_free(gerr);
+               return;
+       }
+       HELPER_DBG("Receiver = %s(%d), read_size = %d", receiver, len, size);
+
+       if (len) {
+               receiver[len] = '\0';
+               HELPER_DBG("export contact %d", atoi(receiver));
+               ret = helper_sim_write_pb_record(src, atoi(receiver));
+               if (CTS_SUCCESS != ret) {
+                       ERR("helper_sim_write_pb_record() Failed(%d)", ret);
+                       helper_socket_return(src, ret, 0, NULL);
+               }
+       }
+}
+
 static int helper_normalize(GIOChannel *src, int read_size,
                char *dest, int dest_size)
 {
@@ -226,8 +254,7 @@ static void helper_handle_normalize_name(GIOChannel *src, int* sizes)
                                sizeof(normalized_first));
                if (ret < CTS_SUCCESS) {
                        ERR("helper_normalize() Failed(%d)", ret);
-                       helper_discard_msg(g_io_channel_unix_get_fd(src),
-                                       sizes[CTS_NN_LAST] + sizes[CTS_NN_SORTKEY]);
+                       helper_discard_msg(src, sizes[CTS_NN_LAST] + sizes[CTS_NN_SORTKEY]);
                        helper_socket_return(src, ret, 0, NULL);
                        return;
                }
@@ -242,7 +269,7 @@ static void helper_handle_normalize_name(GIOChannel *src, int* sizes)
                                sizeof(normalized_last));
                if (ret < CTS_SUCCESS) {
                        ERR("helper_normalize() Failed(%d)", ret);
-                       helper_discard_msg(g_io_channel_unix_get_fd(src), sizes[CTS_NN_SORTKEY]);
+                       helper_discard_msg(src, sizes[CTS_NN_SORTKEY]);
                        helper_socket_return(src, ret, 0, NULL);
                        return;
                }
@@ -288,15 +315,18 @@ static gboolean request_handler(GIOChannel *src, GIOCondition condition,
        ret = helper_safe_read(g_io_channel_unix_get_fd(src), (char *)&msg, sizeof(msg));
        h_retvm_if(-1 == ret, TRUE, "helper_safe_read() Failed(errno = %d)", errno);
 
-       HELPER_DBG("attach number = %d, attach1 = %d, attach2 = %d",
+       HELPER_DBG("attach number = %d, attach1 = %d, attach2 = %d, attach3 = %d",
                        msg.attach_num, msg.attach_sizes[CTS_NN_FIRST],
-                       msg.attach_sizes[CTS_NN_LAST]);
+                       msg.attach_sizes[CTS_NN_LAST], msg.attach_sizes[CTS_NN_SORTKEY]);
 
        switch (msg.type)
        {
        case CTS_REQUEST_IMPORT_SIM:
                helper_handle_import_sim(src);
                break;
+       case CTS_REQUEST_EXPORT_SIM:
+               helper_handle_export_sim(src, msg.attach_sizes[0]);
+               break;
        case CTS_REQUEST_NORMALIZE_STR:
                if (CTS_NS_ATTACH_NUM != msg.attach_num) {
                        ERR("Invalid CTS_NS_ATTACH_NUM = %d", msg.attach_num);
@@ -350,23 +380,27 @@ int helper_socket_init(void)
        struct sockaddr_un addr;
        GIOChannel *gio;
 
-       unlink(CTS_SOCKET_PATH);
+       if (sd_listen_fds(1) == 1 && sd_is_socket_unix(SD_LISTEN_FDS_START, SOCK_STREAM, -1, CTS_SOCKET_PATH, 0) > 0) {
+               sockfd = SD_LISTEN_FDS_START;
+       } else {
+               unlink(CTS_SOCKET_PATH);
 
-       bzero(&addr, sizeof(addr));
-       addr.sun_family = AF_UNIX;
-       snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", CTS_SOCKET_PATH);
+               bzero(&addr, sizeof(addr));
+               addr.sun_family = AF_UNIX;
+               snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", CTS_SOCKET_PATH);
 
-       sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
-       h_retvm_if(-1 == sockfd, CTS_ERR_SOCKET_FAILED, "socket() Failed(errno = %d)", errno);
+               sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
+               h_retvm_if(-1 == sockfd, CTS_ERR_SOCKET_FAILED, "socket() Failed(errno = %d)", errno);
 
-       ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
-       h_retvm_if(-1 == ret, CTS_ERR_SOCKET_FAILED, "bind() Failed(errno = %d)", errno);
+               ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
+               h_retvm_if(-1 == ret, CTS_ERR_SOCKET_FAILED, "bind() Failed(errno = %d)", errno);
 
-       chown(CTS_SOCKET_PATH, getuid(), CTS_SECURITY_FILE_GROUP);
-       chmod(CTS_SOCKET_PATH, CTS_SECURITY_DEFAULT_PERMISSION);
+               chown(CTS_SOCKET_PATH, getuid(), CTS_SECURITY_FILE_GROUP);
+               chmod(CTS_SOCKET_PATH, CTS_SECURITY_DEFAULT_PERMISSION);
 
-       ret = listen(sockfd, 30);
-       h_retvm_if(-1 == ret, CTS_ERR_SOCKET_FAILED, "listen() Failed(errno = %d)", errno);
+               ret = listen(sockfd, 30);
+               h_retvm_if(-1 == ret, CTS_ERR_SOCKET_FAILED, "listen() Failed(errno = %d)", errno);
+       }
 
        gio = g_io_channel_unix_new(sockfd);
        g_io_add_watch(gio, G_IO_IN, socket_handler, (gpointer)sockfd);
index 75a20e6..740fe93 100755 (executable)
@@ -43,7 +43,7 @@ enum {
 #include <dlog.h>
 #define DLOG(prio, fmt, arg...) \
        do { SLOG(prio, LOG_TAG, fmt, ##arg); } while (0)
-#define INFO(fmt, arg...) SLOGI(fmt, ##arg)
+#define INFO(fmt, arg...) SLOGI("%s:" fmt, __FUNCTION__, ##arg)
 #define ERR(fmt, arg...) SLOGE("%s(%d): " fmt, __FUNCTION__, __LINE__, ##arg)
 #define DBG(fmt, arg...) SLOGD("%s:" fmt, __FUNCTION__, ##arg)
 #else //HELPER_DLOG_OUT
index b27160c..fd1e394 100755 (executable)
@@ -72,8 +72,8 @@ int helper_normalize_str(const char *src, char *dest, int dest_size)
        int type = CTS_LANG_OTHERS;
        int32_t size;
        UErrorCode status = 0;
-       UChar tmp_result[CTS_SQL_MAX_LEN];
-       UChar result[CTS_SQL_MAX_LEN];
+       UChar tmp_result[CTS_SQL_MAX_LEN*2];
+       UChar result[CTS_SQL_MAX_LEN*2];
        int i = 0;
        int j = 0;
        int str_len = strlen(src);
index b99aa59..a65a1c6 100755 (executable)
  *
  */
 #include <string.h>
-#include <TapiCommon.h>
+#include <tapi_common.h>
 #include <ITapiSim.h>
+#include <ITapiPhonebook.h>
+#include <TapiUtility.h>
 #include <contacts-svc.h>
 
 #include "cts-addressbook.h"
 #define CTS_TAPI_SIM_PB_MAX 0xFFFF
 #define CTS_MIN(a, b) (a>b)?b:a
 
-static int helper_sim_read_record_cb(const TelTapiEvent_t *pdata, void *data);
-static int helper_sim_pb_count_cb(const TelTapiEvent_t *pdata, void *data);
+#define TAPI_PB_MAX_FILE_CNT TAPI_PB_3G_PBC+1
+#define TAPI_PB_NAME_INDEX TAPI_PB_3G_NAME
+#define TAPI_PB_NUMBER_INDEX TAPI_PB_3G_NUMBER
 
 static TelSimImsiInfo_t TAPI_imsi;
-static void *helper_import_sim_data = NULL;
-
-static unsigned int TAPI_SIM_EVENT_ID[CTS_SIM_EVENT_NUM];
-static const int TAPI_SIM_EVENT[CTS_SIM_EVENT_NUM] =
-{
-       TAPI_EVENT_SIM_PB_ACCESS_READ_CNF,
-       TAPI_EVENT_SIM_PB_STORAGE_COUNT_CNF
-};
-static const TelAppCallback TAPI_SIM_EVENT_CB[CTS_SIM_EVENT_NUM] =
-{
-       helper_sim_read_record_cb,
-       helper_sim_pb_count_cb
-};
-
+static void *helper_sim_data = NULL;
+static TapiHandle *handle;
 static int helper_register_tapi_cnt = 0;
-static int helper_register_tapi_sim_event(void)
-{
-       int i, ret;
+static TelSimPbType_t sim_type = TAPI_SIM_PB_UNKNOWNN;
+static int text_max_len[TAPI_PB_MAX_FILE_CNT];
+static int used_count[TAPI_PB_MAX_FILE_CNT];
+static int max_count[TAPI_PB_MAX_FILE_CNT];
 
-       if (0 == helper_register_tapi_cnt)
-       {
-               ret = tel_init();
-               h_retvm_if(TAPI_API_SUCCESS != ret, CTS_ERR_TAPI_FAILED,
-                               "tel_init() is Failed(%d)", ret);
-
-               ret = tel_register_app_name(CTS_DBUS_SERVICE);
-               h_retvm_if(TAPI_API_SUCCESS != ret, CTS_ERR_TAPI_FAILED,
-                               "tel_register_app_name(%s) is Failed(%d)", CTS_DBUS_SERVICE, ret);
-
-               for (i=0;i<CTS_SIM_EVENT_NUM;i++)
-               {
-                       ret = tel_register_event(TAPI_SIM_EVENT[i], &TAPI_SIM_EVENT_ID[i],
-                                       TAPI_SIM_EVENT_CB[i], NULL);
-                       h_retvm_if(TAPI_API_SUCCESS != ret, CTS_ERR_TAPI_FAILED,
-                                       "tel_register_event(Event[%d]) is Failed(%d)", i, ret);
-               }
+static int helper_register_tapi_init(void)
+{
+       if (0 == helper_register_tapi_cnt) {
+               handle = tel_init(NULL);
+               h_retvm_if(NULL == handle, CTS_ERR_TAPI_FAILED,
+                               "tel_init() is Failed()");
        }
        helper_register_tapi_cnt++;
 
        return CTS_SUCCESS;
 }
 
-static int helper_deregister_tapi_sim_event(void)
+static int helper_deregister_tapi_deinit(void)
 {
-       int ret, i;
-
-       if (1 == helper_register_tapi_cnt)
-       {
-               for (i=0;i<CTS_SIM_EVENT_NUM;i++)
-               {
-                       ret = tel_deregister_event(TAPI_SIM_EVENT_ID[i]);
-                       h_warn_if(TAPI_API_SUCCESS != ret,
-                                       "tel_register_event(Event[%d]) is Failed(%d)", i, ret);
-               }
-
-               ret = tel_deinit();
+       int ret;
+       if (1 == helper_register_tapi_cnt) {
+               ret = tel_deinit(handle);
                h_retvm_if(TAPI_API_SUCCESS != ret, CTS_ERR_TAPI_FAILED,
-                               "tel_deinti() Failed(%d)", ret);
+                               "tel_deinit() Failed(%d)", ret);
        }
        helper_register_tapi_cnt--;
 
        return CTS_SUCCESS;
 }
 
+#ifdef NO_USE_TAPI_DECODER
+static int helper_sim_data_to_utf8(TelSimTextEncrypt_t type,
+               char *src, int src_len, char *dest, int dest_size)
+{
+       h_retvm_if(0 == src_len || NULL == src, CTS_ERR_ARG_INVALID,
+                       "src(%p, len=%d) is invalid", src, src_len);
+       h_retvm_if(0 == dest_size || NULL == dest, CTS_ERR_ARG_INVALID,
+                       "dest(%p, len=%d) is invalid", dest, dest_size);
+
+       switch (type) {
+       case TAPI_SIM_TEXT_ENC_GSM7BIT:
+       case TAPI_SIM_TEXT_ENC_ASCII:
+               memcpy(dest, src, CTS_MIN(dest_size, src_len));
+               dest[CTS_MIN(dest_size-1, src_len)] = '\0';
+               break;
+       case TAPI_SIM_TEXT_ENC_UCS2:
+       case TAPI_SIM_TEXT_ENC_HEX:
+               return helper_unicode_to_utf8(src, src_len, dest, dest_size);
+       default:
+               ERR("Unknown Encryption Type(%d)", type);
+               return CTS_ERR_ARG_INVALID;
+       }
+
+       return CTS_SUCCESS;
+}
+#endif
+
 #define HELPER_SIM_DATA_MAX_LENGTH 1024
 
 static int helper_insert_SDN(TelSimPbRecord_t *pb2g_data)
@@ -277,159 +276,117 @@ static int helper_insert_3g_contact(TelSimPbRecord_t *pb3g_data)
        return ret;
 }
 
-static int helper_sim_read_record_cb(const TelTapiEvent_t *sim_event, void *data)
+static void helper_sim_read_record_cb(TapiHandle *handle, int result, void *data, void *user_data)
 {
-       int ret, saved_pb_num, i=0, req_id;
-       TelSimPbRecord_t *sim_info;
-
        HELPER_FN_CALL;
+       int ret;
+       TelSimPbAccessResult_t sec_rt = result;
+       TelSimPbRecord_t *sim_info = data;
 
-       h_retvm_if(TAPI_EVENT_CLASS_SIM != sim_event->EventClass ||
-                       TAPI_EVENT_SIM_PB_ACCESS_READ_CNF != sim_event->EventType,
-                       CTS_ERR_TAPI_FAILED,
-                       "Unknown Event(EventClass = 0x%X, EventType = 0x%X",
-                       sim_event->EventClass, sim_event->EventType);
-
-       sim_info = (TelSimPbRecord_t*)sim_event->pData;
        if (NULL == sim_info) {
-               ERR("sim_info is NULL, Status = %d", sim_event->Status);
+               ERR("sim_info is NULL, result = %d", sec_rt);
                goto ERROR_RETURN;
        }
 
-       if (TAPI_SIM_PB_SUCCESS != sim_event->Status) {
+       if (TAPI_SIM_PB_SUCCESS != sec_rt) {
                if (TAPI_SIM_PB_SDN == sim_info->phonebook_type &&
-                               TAPI_SIM_PB_INVALID_INDEX == sim_event->Status)
-               {
+                               TAPI_SIM_PB_INVALID_INDEX == sec_rt) {
                        HELPER_DBG("Index = %d", sim_info->index);
-                       ret = tel_read_sim_pb_record(sim_info->phonebook_type,
-                                       sim_info->index+1, &req_id);
+                       ret = tel_read_sim_pb_record(handle, sim_info->phonebook_type,
+                                       sim_info->index+1, helper_sim_read_record_cb, NULL);
                        if (TAPI_API_SUCCESS != ret) {
                                ERR("tel_read_sim_pb_record() Failed(%d)", ret);
                                goto ERROR_RETURN;
                        }
-                       return CTS_SUCCESS;
+                       return;
                }
-               ERR("SIM phonebook access Failed(%d)", sim_event->Status);
+               ERR("SIM phonebook access Failed(%d)", sec_rt);
                goto ERROR_RETURN;
        }
 
-       switch (sim_info->phonebook_type)
-       {
+       switch (sim_info->phonebook_type) {
        case TAPI_SIM_PB_SDN:
-               saved_pb_num = sim_event->pDataLen / sizeof(TelSimPbRecordData_t);
-               if (saved_pb_num <= 0 || TAPI_SIM_3G_PB_MAX_RECORD_COUNT < saved_pb_num) {
-                       ERR("received saved_pb_num is invalid(%d)", saved_pb_num);
-                       goto ERROR_RETURN;
-               }
-               while (true) {
-                       ret = helper_insert_SDN(sim_info);
-                       h_warn_if(ret < CTS_SUCCESS, "helper_insert_SDN() is Failed(%d)", ret);
-                       if (saved_pb_num == ++i) break;
-                       sim_info++;
-               }
-               //sim_info->NextIndex = sim_info->Index+1;
+               ret = helper_insert_SDN(sim_info);
+               h_warn_if(ret < CTS_SUCCESS, "helper_insert_SDN() is Failed(%d)", ret);
                break;
        case TAPI_SIM_PB_ADN:
-               saved_pb_num = sim_event->pDataLen / sizeof(TelSimPbRecordData_t);
-               if (saved_pb_num <= 0 || TAPI_SIM_3G_PB_MAX_RECORD_COUNT < saved_pb_num) {
-                       ERR("received saved_pb_num is invalid(%d)", saved_pb_num);
-                       goto ERROR_RETURN;
-               }
-               while (true) {
-                       ret = helper_insert_2g_contact(sim_info);
-                       h_warn_if(ret < CTS_SUCCESS, "helper_insert_2g_contact() is Failed(%d)", ret);
-                       if (saved_pb_num == ++i) break;
-                       sim_info++;
-               }
+               ret = helper_insert_2g_contact(sim_info);
+               h_warn_if(ret < CTS_SUCCESS, "helper_insert_2g_contact() is Failed(%d)", ret);
                break;
        case TAPI_SIM_PB_3GSIM:
-               saved_pb_num = sim_event->pDataLen / sizeof(TelSimPbRecordData_t);
-               HELPER_DBG("saved_pb_num = %d", saved_pb_num);
-               if (saved_pb_num <= 0 || TAPI_SIM_3G_PB_MAX_RECORD_COUNT < saved_pb_num) {
-                       ERR("received saved_pb_num is invalid(%d)", saved_pb_num);
-                       goto ERROR_RETURN;
-               }
-               while (true) {
-                       ret = helper_insert_3g_contact(sim_info);
-                       h_warn_if(ret < CTS_SUCCESS, "helper_insert_3g_contact() is Failed(%d)", ret);
-                       if (saved_pb_num == ++i) break;
-                       sim_info++;
-               }
+               ret = helper_insert_3g_contact(sim_info);
+               h_warn_if(ret < CTS_SUCCESS, "helper_insert_3g_contact() is Failed(%d)", ret);
                break;
        case TAPI_SIM_PB_FDN:
-       case TAPI_SIM_PB_MSISDN:
        default:
                ERR("Unknown storage type(%d)", sim_info->phonebook_type);
                goto ERROR_RETURN;
        }
+
        if (sim_info->next_index && CTS_TAPI_SIM_PB_MAX != sim_info->next_index) {
                HELPER_DBG("NextIndex = %d", sim_info->next_index);
-               ret = tel_read_sim_pb_record(sim_info->phonebook_type,
-                               sim_info->next_index, &req_id);
+               ret = tel_read_sim_pb_record(handle, sim_info->phonebook_type,
+                               sim_info->next_index, helper_sim_read_record_cb, NULL);
                if (TAPI_API_SUCCESS != ret) {
                        ERR("tel_read_sim_pb_record() Failed(%d)", ret);
                        goto ERROR_RETURN;
                }
        }
        else {
-               contacts_svc_end_trans(true);
-               if (helper_import_sim_data) {
-                       ret = helper_socket_return(helper_import_sim_data, CTS_SUCCESS, 0, NULL);
+               if (TAPI_SIM_PB_ADN == sim_info->phonebook_type ||
+                       TAPI_SIM_PB_3GSIM == sim_info->phonebook_type)
+                       contacts_svc_end_trans(true);
+               if (helper_sim_data) {
+                       ret = helper_socket_return(helper_sim_data, CTS_SUCCESS, 0, NULL);
                        h_warn_if(CTS_SUCCESS != ret, "helper_socket_return() Failed(%d)", ret);
-                       helper_import_sim_data = NULL;
+                       helper_sim_data = NULL;
                        memset(&TAPI_imsi, 0x00, sizeof(TelSimImsiInfo_t));
                }
 
-               helper_deregister_tapi_sim_event();
+               helper_deregister_tapi_deinit();
                helper_trim_memory();
        }
-       return CTS_SUCCESS;
+       return;
+
 ERROR_RETURN:
-       contacts_svc_end_trans(false);
-       if (helper_import_sim_data) {
-               ret = helper_socket_return(helper_import_sim_data, CTS_SUCCESS, 0, NULL);
+       if (TAPI_SIM_PB_ADN == sim_info->phonebook_type ||
+               TAPI_SIM_PB_3GSIM == sim_info->phonebook_type)
+               contacts_svc_end_trans(false);
+       if (helper_sim_data) {
+               ret = helper_socket_return(helper_sim_data, CTS_SUCCESS, 0, NULL);
                h_warn_if(CTS_SUCCESS != ret, "helper_socket_return() Failed(%d)", ret);
-               helper_import_sim_data = NULL;
+               helper_sim_data = NULL;
                memset(&TAPI_imsi, 0x00, sizeof(TelSimImsiInfo_t));
        }
-       helper_deregister_tapi_sim_event();
+       helper_deregister_tapi_deinit();
        helper_trim_memory();
-       return CTS_ERR_TAPI_FAILED;
+       return;
 }
 
-
-static int helper_sim_pb_count_cb(const TelTapiEvent_t *sim_event, void *data)
+static void helper_sim_aync_response_pb_count(TapiHandle *handle, int result, void *data, void *user_data)
 {
-       int ret, req_id;
-       TelSimPbStorageInfo_t *sim_info;
-
        HELPER_FN_CALL;
+       int ret = CTS_SUCCESS;
+       TelSimPbAccessResult_t access_rt = result;
+       TelSimPbStorageInfo_t *sim_info = data;
 
-       h_retvm_if(TAPI_EVENT_CLASS_SIM != sim_event->EventClass ||
-                       TAPI_EVENT_SIM_PB_STORAGE_COUNT_CNF != sim_event->EventType,
-                       CTS_ERR_TAPI_FAILED,
-                       "Unknown Event(EventClass = 0x%X, EventType = 0x%X",
-                       sim_event->EventClass, sim_event->EventType);
-
-       sim_info = (TelSimPbStorageInfo_t *)sim_event->pData;
        if (NULL == sim_info) {
-               ERR("sim_info is NULL, Status = %d", sim_event->Status);
+               ERR("sim_info is NULL");
                ret = CTS_ERR_TAPI_FAILED;
                goto ERROR_RETURN;
        }
 
-       if (TAPI_SIM_PB_SUCCESS != sim_event->Status) {
-               ERR("SIM phonebook access Failed(%d)", sim_event->Status);
+       if (TAPI_SIM_PB_SUCCESS != access_rt) {
+               ERR("SIM phonebook access Failed(%d)", access_rt);
                ret = CTS_ERR_TAPI_FAILED;
                goto ERROR_RETURN;
        }
 
-       switch (sim_info->StorageFileType)
-       {
+       switch (sim_info->StorageFileType) {
        case TAPI_SIM_PB_SDN:
                if (sim_info->UsedRecordCount) {
                        HELPER_DBG("SDN count = %d", sim_info->UsedRecordCount);
-                       ret = tel_read_sim_pb_record(sim_info->StorageFileType, 1, &req_id);
+                       ret = tel_read_sim_pb_record(handle, sim_info->StorageFileType, 1, helper_sim_read_record_cb, NULL);
                        if (TAPI_API_SUCCESS != ret) {
                                ERR("tel_read_sim_pb_record() Failed(%d)", ret);
                                ret = CTS_ERR_TAPI_FAILED;
@@ -441,7 +398,7 @@ static int helper_sim_pb_count_cb(const TelTapiEvent_t *sim_event, void *data)
        case TAPI_SIM_PB_3GSIM:
                if (sim_info->UsedRecordCount) {
                        HELPER_DBG("ADN count = %d", sim_info->UsedRecordCount);
-                       ret = tel_read_sim_pb_record(sim_info->StorageFileType, 1, &req_id);
+                       ret = tel_read_sim_pb_record(handle, sim_info->StorageFileType, 1, helper_sim_read_record_cb, NULL);
                        if (TAPI_API_SUCCESS != ret) {
                                ERR("tel_read_sim_pb_record() Failed(%d)", ret);
                                ret = CTS_ERR_TAPI_FAILED;
@@ -453,110 +410,572 @@ static int helper_sim_pb_count_cb(const TelTapiEvent_t *sim_event, void *data)
                                goto ERROR_RETURN;
                        }
                } else {
-                       helper_socket_return(helper_import_sim_data, CTS_ERR_NO_DATA, 0, NULL);
-                       ret = CTS_SUCCESS;
+                       ret = CTS_ERR_NO_DATA;
                        goto ERROR_RETURN;
                }
                break;
        case TAPI_SIM_PB_FDN:
-       case TAPI_SIM_PB_MSISDN:
        default:
                ERR("Unknown storage type(%d)", sim_info->StorageFileType);
-               return CTS_ERR_TAPI_FAILED;
+               ret = CTS_ERR_FAIL;
+               goto ERROR_RETURN;
        }
 
-       return CTS_SUCCESS;
+       return;
 
 ERROR_RETURN:
-       helper_deregister_tapi_sim_event();
-       return ret;
+       if (helper_sim_data) {
+               ret = helper_socket_return(helper_sim_data, ret, 0, NULL);
+               h_warn_if(CTS_SUCCESS != ret, "helper_socket_return() Failed(%d)", ret);
+               helper_sim_data = NULL;
+       }
+       helper_deregister_tapi_deinit();
 }
 
-
 int helper_sim_read_pb_record(void *data)
 {
-       int ret, req_id;
-       TelSimPbFileType_t storage;
+       int ret;
+       int sim_pb_inited;
+       TelSimPbList_t pb_list = {0};
        TelSimCardType_t cardInfo;
 
-       h_retvm_if(NULL != helper_import_sim_data, CTS_ERR_ENV_INVALID,
+       h_retvm_if(NULL != helper_sim_data, CTS_ERR_ENV_INVALID,
                        "Helper is already processing with sim");
 
-       ret = helper_register_tapi_sim_event();
-       h_retvm_if(TAPI_API_SUCCESS != ret, ret,
-                       "helper_register_tapi_sim_event() Failed(%d)", ret);
+       ret = helper_register_tapi_init();
+       h_retvm_if(CTS_SUCCESS != ret, ret,
+                       "helper_register_tapi_init() Failed(%d)", ret);
+
+       if (sim_type == TAPI_SIM_PB_UNKNOWNN) {
+               ret = tel_get_sim_type(handle, &cardInfo);
+               if(TAPI_API_SUCCESS != ret) {
+                       ERR("tel_get_sim_type() Failed(%d)", ret);
+                       goto ERROR_RETURN;
+               }
+
+               if (TAPI_SIM_CARD_TYPE_USIM == cardInfo)
+                       sim_type = TAPI_SIM_PB_3GSIM;
+               else
+                       sim_type = TAPI_SIM_PB_ADN;
+       }
+
+       ret = tel_get_sim_pb_init_info(handle, &sim_pb_inited, &pb_list);
+       if(TAPI_API_SUCCESS != ret) {
+               ERR("tel_get_sim_pb_init_info() Failed(%d)", ret);
+               HELPER_DBG("sim_pb_inited(%d)", sim_pb_inited);
+               goto ERROR_RETURN;
+       }
+
+       ret = tel_get_sim_imsi(handle, &TAPI_imsi);
+       if(TAPI_API_SUCCESS != ret) {
+               ERR("tel_get_sim_imsi() Failed(%d)", ret);
+               goto ERROR_RETURN;
+       }
+
+       if (sim_pb_inited) {
+               ret = tel_get_sim_pb_count(handle, sim_type, helper_sim_aync_response_pb_count, NULL);
+               if(TAPI_API_SUCCESS != ret) {
+                       ERR("tel_get_sim_pb_count() Failed(%d)", ret);
+                       goto ERROR_RETURN;
+               }
+       }
+
+       helper_sim_data = data;
+
+       return CTS_SUCCESS;
+
+ERROR_RETURN:
+       helper_deregister_tapi_deinit();
+       return CTS_ERR_TAPI_FAILED;
+}
+
+static void helper_sim_aync_response_pb_update(TapiHandle *handle, int result, void *data, void *user_data)
+{
+       HELPER_FN_CALL;
+       int ret;
+       TelSimPbAccessResult_t access_rt = result;
 
-       ret = tel_get_sim_type(&cardInfo);
-       h_retvm_if(TAPI_API_SUCCESS != ret, CTS_ERR_TAPI_FAILED,
-                       "tel_get_sim_type() Failed(%d)", ret);
+       if (TAPI_SIM_PB_SUCCESS != access_rt) {
+               ERR("SIM phonebook access Failed(%d)", access_rt);
+               ret = CTS_ERR_TAPI_FAILED;
+       }
+       else {
+               HELPER_DBG("Success");
+               ret = CTS_SUCCESS;
+       }
+
+       if (helper_sim_data) {
+               ret = helper_socket_return(helper_sim_data, ret, 0, NULL);
+               h_warn_if(CTS_SUCCESS != ret, "helper_socket_return() Failed(%d)", ret);
+               helper_sim_data = NULL;
+       }
+       helper_deregister_tapi_deinit();
+}
 
-       if (TAPI_SIM_CARD_TYPE_USIM == cardInfo)
-               storage = TAPI_SIM_PB_3GSIM;
+static inline int helper_sim_get_display_name(CTSvalue *name, char *dest, int dest_size)
+{
+       int len = 0;
+       const char *first, *last;
+
+       first = contacts_svc_value_get_str(name, CTS_NAME_VAL_FIRST_STR);
+       last = contacts_svc_value_get_str(name, CTS_NAME_VAL_LAST_STR);
+       if (!first && !last)
+               return 0;
+       else if (!last)
+               len = snprintf(dest, dest_size, "%s", first);
+       else if (!first)
+               len = snprintf(dest, dest_size, "%s", last);
+       else if (CTS_ORDER_NAME_FIRSTLAST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
+               len = snprintf(dest, dest_size, "%s %s", first, last);
        else
-               storage = TAPI_SIM_PB_ADN;
+               len = snprintf(dest, dest_size, "%s, %s", last, first);
+
+       return len;
+}
+
+static void helper_sim_write_contact(int index, TelSimPbType_t type, void *user_data)
+{
+       HELPER_FN_CALL;
+       int ret;
+       int text_len;
+       int pindex = (int)user_data;
+       TelSimPbRecord_t pb;
+       CTSstruct *person = NULL;
+       CTSvalue *value = NULL;
+       GSList *list = NULL;
+       GSList *cursor = NULL;
+       memset(&pb, 0, sizeof(TelSimPbRecord_t));
+
+       HELPER_DBG("person index : %d", pindex);
+
+       ret = contacts_svc_get_person(pindex, &person);
+       if(CTS_SUCCESS != ret) {
+               ERR("contacts_svc_get_person is failed(%d)", ret);
+               goto ERROR_RETURN;
+       }
+
+       pb.phonebook_type = type;
+       pb.index = index;
+
+       HELPER_DBG("phonebook_type[%d] 0:fdn, 1:adn, 2:sdn, 3:3gsim, 4:aas, 5:gas, index[%d]", pb.phonebook_type, pb.index);
+
+       ret = contacts_svc_struct_get_value(person, CTS_CF_NAME_VALUE, &value);
+       if (CTS_SUCCESS == ret) {
+               char name[HELPER_SIM_DATA_MAX_LENGTH] = {0};
+               text_len = MIN(sizeof(pb.number), text_max_len[TAPI_PB_NAME_INDEX]);
+               ret = helper_sim_get_display_name(value, name, text_len);
+               if (ret)
+                       snprintf((char*)pb.name, text_len, "%s", name);
+               HELPER_DBG("name : %s, pb_name : %s", name, (char *)pb.name);
+       }
+
+       ret = contacts_svc_struct_get_list(person, CTS_CF_NUMBER_LIST, &list);
+       if (CTS_SUCCESS == ret) {
+               text_len = MIN(sizeof(pb.number), text_max_len[TAPI_PB_NUMBER_INDEX]);
+               cursor = list;
+               snprintf((char*)pb.number, text_len, "%s", contacts_svc_value_get_str(cursor->data, CTS_NUM_VAL_NUMBER_STR));
+
+               if (TAPI_SIM_PB_3GSIM == type) {
+                       if (0 < max_count[TAPI_PB_3G_ANR1] - used_count[TAPI_PB_3G_ANR1]) {
+                               cursor = cursor->next;
+                               if (cursor) {
+                                       text_len = MIN(sizeof(pb.anr1), text_max_len[TAPI_PB_3G_ANR1]);
+                                       snprintf((char*)pb.anr1, text_len, "%s", contacts_svc_value_get_str(cursor->data, CTS_NUM_VAL_NUMBER_STR));
+                                       cursor = cursor->next;
+                               }
+                       }
+                       if (0 < max_count[TAPI_PB_3G_ANR2] - used_count[TAPI_PB_3G_ANR2]) {
+                               if (cursor) {
+                                       text_len = MIN(sizeof(pb.anr2), text_max_len[TAPI_PB_3G_ANR2]);
+                                       snprintf((char*)pb.anr2, text_len, "%s", contacts_svc_value_get_str(cursor->data, CTS_NUM_VAL_NUMBER_STR));
+                                       cursor = cursor->next;
+                               }
+                       }
+                       if (0 < max_count[TAPI_PB_3G_ANR3] - used_count[TAPI_PB_3G_ANR3]) {
+                               if (cursor) {
+                                       text_len = MIN(sizeof(pb.anr3), text_max_len[TAPI_PB_3G_ANR3]);
+                                       snprintf((char*)pb.anr3, text_len, "%s", contacts_svc_value_get_str(cursor->data, CTS_NUM_VAL_NUMBER_STR));
+                               }
+                       }
+               }
+               INFO("pb.nubmer : %s, pb.anr1 : %s, pb.anr2 : %s, pb.arn3 : %s", pb.number, pb.anr1, pb.anr2, pb.anr3);
+       }
+
+       if (TAPI_SIM_PB_3GSIM == type) {
+               ret = contacts_svc_struct_get_list(person, CTS_CF_EMAIL_LIST, &list);
+               if (CTS_SUCCESS == ret) {
+                       cursor = list;
+                       if (0 < max_count[TAPI_PB_3G_EMAIL1] - used_count[TAPI_PB_3G_EMAIL1]) {
+                               if (cursor) {
+                                       text_len = MIN(sizeof(pb.email1), text_max_len[TAPI_PB_3G_EMAIL1]);
+                                       snprintf((char*)pb.email1, text_len, "%s", contacts_svc_value_get_str(cursor->data, CTS_EMAIL_VAL_ADDR_STR));
+                                       cursor = cursor->next;
+                               }
+                       }
+                       if (0 < max_count[TAPI_PB_3G_EMAIL2] - used_count[TAPI_PB_3G_EMAIL2]) {
+                               if (cursor) {
+                                       text_len = MIN(sizeof(pb.email2), text_max_len[TAPI_PB_3G_EMAIL2]);
+                                       snprintf((char*)pb.email2, text_len, "%s", contacts_svc_value_get_str(cursor->data, CTS_EMAIL_VAL_ADDR_STR));
+                                       cursor = cursor->next;
+                               }
+                       }
+                       if (0 < max_count[TAPI_PB_3G_EMAIL3] - used_count[TAPI_PB_3G_EMAIL3]) {
+                               if (cursor) {
+                                       text_len = MIN(sizeof(pb.email3), text_max_len[TAPI_PB_3G_EMAIL3]);
+                                       snprintf((char*)pb.email3, text_len, "%s", contacts_svc_value_get_str(cursor->data, CTS_EMAIL_VAL_ADDR_STR));
+                                       cursor = cursor->next;
+                               }
+                       }
+                       if (0 < max_count[TAPI_PB_3G_EMAIL4] - used_count[TAPI_PB_3G_EMAIL4]) {
+                               if (cursor) {
+                                       text_len = MIN(sizeof(pb.email4), text_max_len[TAPI_PB_3G_EMAIL4]);
+                                       snprintf((char*)pb.email4, text_len, "%s", contacts_svc_value_get_str(cursor->data, CTS_EMAIL_VAL_ADDR_STR));
+                               }
+                       }
+                       INFO("pb.email1 : %s, pb.email2 : %s, pb.email3 : %s, pb.email4 : %s", pb.email1, pb.email2, pb.email3, pb.email4);
+               }
+       }
+
+       contacts_svc_struct_free(person);
+       ret = tel_update_sim_pb_record(handle, &pb, helper_sim_aync_response_pb_update, NULL);
+       if(TAPI_API_SUCCESS != ret) {
+               ERR("tel_update_sim_pb_record() Failed(%d)", ret);
+               goto ERROR_RETURN;
+       }
+
+       return;
+
+ERROR_RETURN:
+       if (helper_sim_data) {
+               ret = helper_socket_return(helper_sim_data, CTS_SUCCESS, 0, NULL);
+               h_warn_if(CTS_SUCCESS != ret, "helper_socket_return() Failed(%d)", ret);
+               helper_sim_data = NULL;
+       }
+       helper_deregister_tapi_deinit();
+       helper_trim_memory();
+       return;
+}
+
+static void helper_sim_find_empty_slot_cb(TapiHandle *handle, int result, void *data, void *user_data)
+{
+       HELPER_FN_CALL;
+       int ret;
+       TelSimPbAccessResult_t sec_rt = result;
+       TelSimPbRecord_t *sim_info = data;
+
+       if (NULL == sim_info) {
+               ERR("sim_info is NULL, result = %d", sec_rt);
+               goto ERROR_RETURN;
+       }
+
+       if (TAPI_SIM_PB_SUCCESS != sec_rt) {
+               if (TAPI_SIM_PB_INVALID_INDEX == sec_rt) {
+                       HELPER_DBG("Index = %d", sim_info->index);
+                       helper_sim_write_contact(sim_info->index, sim_info->phonebook_type, user_data);
+                       return;
+               }
+               ERR("SIM phonebook access Failed(%d)", sec_rt);
+               goto ERROR_RETURN;
+       }
 
-       int first_id, sim_pb_inited;
+       if (sim_info->next_index && CTS_TAPI_SIM_PB_MAX != sim_info->next_index) {
+               HELPER_DBG("NextIndex = %d", sim_info->next_index);
+               int diff = sim_info->next_index-sim_info->index;
+               if (1 == diff) {
+                       ret = tel_read_sim_pb_record(handle, sim_info->phonebook_type,
+                                       sim_info->next_index, helper_sim_find_empty_slot_cb, user_data);
+                       if (TAPI_API_SUCCESS != ret) {
+                               ERR("tel_read_sim_pb_record() Failed(%d)", ret);
+                               goto ERROR_RETURN;
+                       }
+               }
+               else if(1 < diff) {
+                       helper_sim_write_contact(sim_info->index+1, sim_info->phonebook_type, user_data);
+               }
+               else {
+                       ERR("There is no empty record");
+                       goto ERROR_RETURN;
+               }
+       }
+       else if (sim_info->index+1 && CTS_TAPI_SIM_PB_MAX != sim_info->index+1){
+               helper_sim_write_contact(sim_info->index+1, sim_info->phonebook_type, user_data);
+       }
+       else {
+               ERR("There is no empty record");
+               goto ERROR_RETURN;
+       }
+       return;
+
+ERROR_RETURN:
+       if (helper_sim_data) {
+               ret = helper_socket_return(helper_sim_data, CTS_SUCCESS, 0, NULL);
+               h_warn_if(CTS_SUCCESS != ret, "helper_socket_return() Failed(%d)", ret);
+               helper_sim_data = NULL;
+       }
+       helper_deregister_tapi_deinit();
+       return;
+}
+
+static void helper_sim_check_write_available(TapiHandle *handle, int result, void *data, void *user_data)
+{
+       HELPER_FN_CALL;
+       int ret;
+       TelSimPbAccessResult_t access_rt = result;
+       TelSimPbStorageInfo_t *ps = data;
+
+       if (NULL == ps) {
+               ERR("PbStorageInfo is NULL, result = %d", access_rt);
+               goto ERROR_RETURN;
+       }
+
+       INFO("StorageFileType[%d] 0:fdn, 1:adn, 2:sdn, 3:3gsim, 4:aas, 5:gas", ps->StorageFileType);
+       INFO("TotalRecordCount[%d]", ps->TotalRecordCount);
+       INFO("UsedRecordCount[%d]", ps->UsedRecordCount);
+
+       if (ps->UsedRecordCount < ps->TotalRecordCount) {
+               ret = tel_read_sim_pb_record(handle, ps->StorageFileType,
+                                               1, helper_sim_find_empty_slot_cb, user_data);
+               if(TAPI_API_SUCCESS != ret) {
+                       ERR("tel_read_sim_pb_record() Failed(%d)", ret);
+                       goto ERROR_RETURN;
+               }
+       }
+       else {
+               ERR("SIM phonebook(Type:%d) is full", ps->StorageFileType);
+               goto ERROR_RETURN;
+       }
+
+       return;
+
+ERROR_RETURN:
+       if (helper_sim_data) {
+               ret = helper_socket_return(helper_sim_data, CTS_SUCCESS, 0, NULL);
+               h_warn_if(CTS_SUCCESS != ret, "helper_socket_return() Failed(%d)", ret);
+               helper_sim_data = NULL;
+       }
+       helper_deregister_tapi_deinit();
+       return;
+}
+
+static bool helper_get_usim_meta_info(TelSimPbCapabilityInfo_t *capa)
+{
+       HELPER_FN_CALL;
+       int i;
+
+       for (i=0; i < TAPI_PB_MAX_FILE_CNT;i++) {
+               text_max_len[i] = 0;
+               used_count[i] = 0;
+               max_count[i] = 0;
+       }
+
+       for (i=0; i < capa->FileTypeCount; i++) {
+               INFO("======================================");
+               INFO(" capa->FileTypeInfo[%d].field_type[%d]",i, capa->FileTypeInfo[i].field_type);
+               INFO(" capa->FileTypeInfo[%d].index_max[%d]",i, capa->FileTypeInfo[i].index_max);
+               INFO(" capa->FileTypeInfo[%d].text_max[%d]",i, capa->FileTypeInfo[i].text_max);
+               INFO(" capa->FileTypeInfo[%d].used_count[%d]",i, capa->FileTypeInfo[i].used_count);
+               switch (capa->FileTypeInfo[i].field_type){
+               case TAPI_PB_3G_NAME:
+               case TAPI_PB_3G_NUMBER:
+               case TAPI_PB_3G_ANR1:
+               case TAPI_PB_3G_ANR2:
+               case TAPI_PB_3G_ANR3:
+               case TAPI_PB_3G_EMAIL1:
+               case TAPI_PB_3G_EMAIL2:
+               case TAPI_PB_3G_EMAIL3:
+               case TAPI_PB_3G_EMAIL4:
+               case TAPI_PB_3G_SNE :
+               case TAPI_PB_3G_GRP:
+               case TAPI_PB_3G_PBC:
+                       text_max_len[capa->FileTypeInfo[i].field_type] = capa->FileTypeInfo[i].text_max;
+                       used_count[capa->FileTypeInfo[i].field_type] += capa->FileTypeInfo[i].used_count;
+                       max_count[capa->FileTypeInfo[i].field_type] += capa->FileTypeInfo[i].index_max;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       for (i=0; i < TAPI_PB_MAX_FILE_CNT; i++) {
+               INFO(" field_type[%d] : index_max(%d), text_max(%d), used_count(%d)", i,
+                               max_count[i], text_max_len[i], used_count[i]);
+       }
+       return true;
+}
+
+static void helper_get_sim_pb_meta_info(TapiHandle *handle, int result, void *data, void *user_data)
+{
+       HELPER_FN_CALL;
+       int ret;
+       TelSimPbAccessResult_t access_rt = result;
+
+       if (TAPI_SIM_PB_3GSIM == sim_type) {
+               TelSimPbCapabilityInfo_t *capa = data;
+               if (NULL == capa) {
+                       ERR("PbCapabilityInfo_t is NULL, result = %d", access_rt);
+                       goto ERROR_RETURN;
+               }
+
+               if (!helper_get_usim_meta_info(capa))
+                       goto ERROR_RETURN;
+
+               if (0 < max_count[TAPI_PB_3G_NAME] - used_count[TAPI_PB_3G_NAME]){
+                       ret = tel_read_sim_pb_record(handle, sim_type,
+                                                       1, helper_sim_find_empty_slot_cb, user_data);
+                       if(TAPI_API_SUCCESS != ret) {
+                               ERR("tel_read_sim_pb_record() Failed(%d)", ret);
+                               goto ERROR_RETURN;
+                       }
+               }
+               else {
+                       ERR("SIM phonebook(Type:%d) is full", sim_type);
+                       goto ERROR_RETURN;
+               }
+       }
+       else {
+               TelSimPbEntryInfo_t *pe = data;
+               if (NULL == pe) {
+                       ERR("PbStorageInfo is NULL, result = %d", access_rt);
+                       goto ERROR_RETURN;
+               }
+
+               INFO("PbNumLenMax[%d]",pe->PbNumLenMax);
+               INFO("PbTextLenMax[%d]",pe->PbTextLenMax);
+               text_max_len[TAPI_PB_NAME_INDEX] = pe->PbTextLenMax;
+               text_max_len[TAPI_PB_NUMBER_INDEX] = pe->PbNumLenMax;
+
+               ret = tel_get_sim_pb_count(handle, sim_type, helper_sim_check_write_available, (void*)user_data);
+               if (TAPI_API_SUCCESS != ret) {
+                       ret = CTS_ERR_TAPI_FAILED;
+                       ERR("tel_get_sim_pb_count() Failed(%d)", ret);
+                       goto ERROR_RETURN;
+               }
+       }
+
+       return;
+
+ERROR_RETURN:
+       if (helper_sim_data) {
+               ret = helper_socket_return(helper_sim_data, CTS_SUCCESS, 0, NULL);
+               h_warn_if(CTS_SUCCESS != ret, "helper_socket_return() Failed(%d)", ret);
+               helper_sim_data = NULL;
+       }
+       helper_deregister_tapi_deinit();
+       return;
+}
+
+int helper_sim_write_pb_record(void *data, int index)
+{
+       int ret;
+       int sim_pb_inited;
        TelSimPbList_t pb_list = {0};
+       TelSimCardType_t cardInfo;
 
-       ret = tel_get_sim_pb_init_info(&sim_pb_inited, &pb_list, &first_id);
-       h_retvm_if(TAPI_API_SUCCESS != ret, CTS_ERR_TAPI_FAILED,
-                       "tel_get_sim_pb_init_info() Failed(%d)", ret);
-       HELPER_DBG("sim_pb_inited(%d), first_id(%d)", sim_pb_inited, first_id);
+       h_retvm_if(NULL != helper_sim_data, CTS_ERR_ENV_INVALID,
+                       "Helper is already processing with sim");
 
-       tel_get_sim_imsi(&TAPI_imsi);
-       h_retvm_if(CTS_SUCCESS != ret, ret, "tel_get_sim_imsi() Failed(%d)", ret);
+       ret = helper_register_tapi_init();
+       h_retvm_if(CTS_SUCCESS != ret, ret,
+                       "helper_register_tapi_init() Failed(%d)", ret);
 
-       if (sim_pb_inited) {
-               ret = tel_get_sim_pb_count(storage, &req_id);
-               h_retvm_if(TAPI_API_SUCCESS != ret, CTS_ERR_TAPI_FAILED,
-                               "tel_get_sim_pb_count() Failed(%d)", ret);
+       if (sim_type == TAPI_SIM_PB_UNKNOWNN) {
+               ret = tel_get_sim_type(handle, &cardInfo);
+               if(TAPI_API_SUCCESS != ret) {
+                       ret = CTS_ERR_TAPI_FAILED;
+                       ERR("tel_get_sim_type() Failed(%d)", ret);
+                       goto ERROR_RETURN;
+               }
+
+               if (TAPI_SIM_CARD_TYPE_USIM == cardInfo)
+                       sim_type = TAPI_SIM_PB_3GSIM;
+               else
+                       sim_type = TAPI_SIM_PB_ADN;
+       }
+
+       ret = tel_get_sim_pb_init_info(handle, &sim_pb_inited, &pb_list);
+       if (TAPI_API_SUCCESS != ret) {
+               ret = CTS_ERR_TAPI_FAILED;
+               ERR("tel_get_sim_pb_init_info() Failed(%d)", ret);
+               goto ERROR_RETURN;
        }
 
-       helper_import_sim_data = data;
+       if (sim_pb_inited) {
+               if (TAPI_SIM_PB_3GSIM == sim_type)
+                       ret = tel_get_sim_pb_usim_meta_info(handle, helper_get_sim_pb_meta_info, (void*)index);
+               else
+                       ret = tel_get_sim_pb_meta_info(handle, sim_type, helper_get_sim_pb_meta_info, (void*)index);
+
+               if (TAPI_API_SUCCESS != ret) {
+                       ret = CTS_ERR_TAPI_FAILED;
+                       ERR("tel_get_sim_pb_meta_info() Failed(%d)", ret);
+                       goto ERROR_RETURN;
+               }
+
+               helper_sim_data = data;
+       }
+       else {
+               ret = CTS_ERR_TAPI_FAILED;
+               ERR("SIM status is not enabled(%d)", sim_pb_inited);
+               goto ERROR_RETURN;
+       }
 
        return CTS_SUCCESS;
-}
 
+ERROR_RETURN:
+       helper_deregister_tapi_deinit();
+       return ret;
+}
 
 int helper_sim_read_SDN(void* data)
 {
-       int ret, req_id, card_changed=0;
-       TelSimCardStatus_t sim_status;
-
        HELPER_FN_CALL;
+       int ret, card_changed = 0;
+       TelSimCardStatus_t sim_status;
 
-       h_retvm_if(NULL != helper_import_sim_data, CTS_ERR_ENV_INVALID,
+       h_retvm_if(NULL != helper_sim_data, CTS_ERR_ENV_INVALID,
                        "Helper is already processing with sim");
+       sim_type = TAPI_SIM_PB_UNKNOWNN;
 
-       ret = helper_register_tapi_sim_event();
+       ret = helper_register_tapi_init();
        h_retvm_if(TAPI_API_SUCCESS != ret, ret,
-                       "helper_register_tapi_sim_event() Failed(%d)", ret);
+                       "helper_register_tapi_init() Failed(%d)", ret);
 
-       ret = tel_get_sim_init_info(&sim_status, &card_changed);
-       h_retvm_if(TAPI_API_SUCCESS != ret, CTS_ERR_TAPI_FAILED,
-                       "tel_get_sim_init_info() Failed(%d)", ret);
-       HELPER_DBG("sim_status = %d, card_changed = %d", sim_status, card_changed);
+       ret = tel_get_sim_init_info(handle, &sim_status, &card_changed);
+       if(TAPI_API_SUCCESS != ret) {
+               ERR("tel_get_sim_init_info() Failed(%d)", ret);
+               HELPER_DBG("sim_status = %d, card_changed = %d", sim_status, card_changed);
+               goto ERROR_RETURN;
+       }
 
        if (TAPI_SIM_STATUS_CARD_NOT_PRESENT == sim_status ||
-                       TAPI_SIM_STATUS_CARD_REMOVED == sim_status)
-       {
+                       TAPI_SIM_STATUS_CARD_REMOVED == sim_status) {
                ret = helper_delete_SDN_contact();
-               h_retvm_if(CTS_SUCCESS != ret, ret, "helper_delete_SDN_contact() Failed(%d)", ret);
+               if(CTS_SUCCESS != ret) {
+                       ERR("helper_delete_SDN_contact() Failed(%d)", ret);
+                       goto ERROR_RETURN;
+               }
+               helper_deregister_tapi_deinit();
        }
-       else if (TAPI_SIM_STATUS_SIM_INIT_COMPLETED == sim_status)
-       {
+       else if (TAPI_SIM_STATUS_SIM_INIT_COMPLETED == sim_status) {
                ret = helper_delete_SDN_contact();
-               h_retvm_if(CTS_SUCCESS != ret, ret, "helper_delete_SDN_contact() Failed(%d)", ret);
-
-               ret = tel_get_sim_pb_count(TAPI_SIM_PB_SDN, &req_id);
-               h_retvm_if(TAPI_API_SUCCESS != ret, CTS_ERR_TAPI_FAILED,
-                               "tel_get_sim_pb_count() Failed(%d)", ret);
-
-               //ret = contacts_svc_begin_trans();
-               //h_retvm_if(CTS_SUCCESS != ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
+               if(CTS_SUCCESS != ret) {
+                       ERR("helper_delete_SDN_contact() Failed(%d)", ret);
+                       goto ERROR_RETURN;
+               }
 
-               helper_import_sim_data = data;
+               ret = tel_read_sim_pb_record(handle, TAPI_SIM_PB_SDN,
+                                               1, helper_sim_read_record_cb, NULL);
+               if(TAPI_API_SUCCESS != ret) {
+                       ERR("tel_read_sim_pb_record() Failed(%d)", ret);
+                       ret = CTS_ERR_TAPI_FAILED;
+                       goto ERROR_RETURN;
+               }
        }
 
        return CTS_SUCCESS;
+
+ERROR_RETURN:
+       helper_deregister_tapi_deinit();
+       helper_trim_memory();
+       return ret;
 }
index 8b3c769..c94934c 100755 (executable)
@@ -22,6 +22,7 @@
 #define __CTS_HELPER_SIM_H__
 
 int helper_sim_read_pb_record(void* data);
+int helper_sim_write_pb_record(void* data, int index);
 int helper_sim_read_SDN(void* data);
 
 
index 63bccc5..65bbefd 100755 (executable)
@@ -130,8 +130,8 @@ int helper_update_default_language(int prev_lang, int new_lang)
        ret = helper_begin_trans();
        h_retvm_if(ret, ret, "helper_begin_trans() Failed(%d)", ret);
 
-       snprintf(query, sizeof(query), "UPDATE %s SET %s=%d WHERE %s=%d",
-                       CTS_TABLE_DATA, CTS_SCHEMA_DATA_NAME_LANG_INFO, prev_lang,
+       snprintf(query, sizeof(query), "UPDATE %s SET %s=%d WHERE datatype = %d AND %s=%d",
+                       CTS_TABLE_DATA, CTS_SCHEMA_DATA_NAME_LANG_INFO, prev_lang, CTS_DATA_NAME,
                        CTS_SCHEMA_DATA_NAME_LANG_INFO, CTS_LANG_DEFAULT);
 
        ret = sqlite3_exec(db, query, NULL, NULL, &errmsg);
@@ -143,8 +143,8 @@ int helper_update_default_language(int prev_lang, int new_lang)
                return CTS_ERR_DB_FAILED;
        }
 
-       snprintf(query, sizeof(query), "UPDATE %s SET %s=%d WHERE %s=%d",
-                       CTS_TABLE_DATA, CTS_SCHEMA_DATA_NAME_LANG_INFO, CTS_LANG_DEFAULT,
+       snprintf(query, sizeof(query), "UPDATE %s SET %s=%d WHERE datatype = %d AND %s=%d",
+                       CTS_TABLE_DATA, CTS_SCHEMA_DATA_NAME_LANG_INFO, CTS_LANG_DEFAULT, CTS_DATA_NAME,
                        CTS_SCHEMA_DATA_NAME_LANG_INFO, new_lang);
 
        ret = sqlite3_exec(db, query, NULL, NULL, &errmsg);
@@ -181,17 +181,20 @@ int helper_insert_SDN_contact(const char *name, const char *number)
                        CTS_TABLE_SIM_SERVICES);
 
        ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
-       h_retvm_if(SQLITE_OK != ret, CTS_ERR_DB_FAILED,
-                       "sqlite3_prepare_v2(%s) Failed(%s)", query, sqlite3_errmsg(db));
+       if(SQLITE_OK != ret) {
+               ERR("sqlite3_prepare_v2(%s) Failed(%s)", query, sqlite3_errmsg(db));
+               helper_db_close();
+               return CTS_ERR_DB_FAILED;
+       }
 
        sqlite3_bind_text(stmt, 1, name, strlen(name), SQLITE_STATIC);
        sqlite3_bind_text(stmt, 2, number, strlen(number), SQLITE_STATIC);
 
        ret = sqlite3_step(stmt);
-       if (SQLITE_DONE != ret)
-       {
+       if (SQLITE_DONE != ret) {
                ERR("sqlite3_step() Failed(%d)", ret);
                sqlite3_finalize(stmt);
+               helper_db_close();
                return CTS_ERR_DB_FAILED;
        }
        sqlite3_finalize(stmt);
@@ -213,14 +216,17 @@ int helper_delete_SDN_contact(void)
        snprintf(query, sizeof(query), "DELETE FROM %s", CTS_TABLE_SIM_SERVICES);
 
        ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
-       h_retvm_if(SQLITE_OK != ret, CTS_ERR_DB_FAILED,
-                       "sqlite3_prepare_v2(%s) Failed(%s)", query, sqlite3_errmsg(db));
+       if(SQLITE_OK != ret) {
+               ERR("sqlite3_prepare_v2(%s) Failed(%s)", query, sqlite3_errmsg(db));
+               helper_db_close();
+               return CTS_ERR_DB_FAILED;
+       }
 
        ret = sqlite3_step(stmt);
-       if (SQLITE_DONE != ret)
-       {
+       if (SQLITE_DONE != ret) {
                ERR("sqlite3_step() Failed(%d)", ret);
                sqlite3_finalize(stmt);
+               helper_db_close();
                return CTS_ERR_DB_FAILED;
        }
        sqlite3_finalize(stmt);
index b03857b..8cb968a 100755 (executable)
@@ -33,7 +33,7 @@
 
 static const char *HELPER_VCONF_TAPI_SIM_PB_INIT = VCONFKEY_TELEPHONY_SIM_PB_INIT;
 static const char *HELPER_VCONF_SYSTEM_LANGUAGE = VCONFKEY_LANGSET;
-static const char *HELPER_VCONF_DISPLAY_ORDER = CTS_VCONF_DISPLAY_ORDER_DEF;
+static const char *HELPER_VCONF_DISPLAY_ORDER = VCONFKEY_CONTACTS_SVC_NAME_DISPLAY_ORDER;
 
 static int default_language = -1;
 static int system_language = -1;
index e7aabfb..123ba70 100644 (file)
@@ -1,7 +1,7 @@
 Name:       contacts-service
 Summary:    Contacts Service
-Version: 0.6.1
-Release:    10
+Version: 0.6.12
+Release:    1
 Group:      TO_BE/FILLED_IN
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
@@ -18,6 +18,7 @@ BuildRequires:  pkgconfig(sqlite3)
 BuildRequires:  pkgconfig(tapi)
 BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(icu-i18n)
+BuildRequires:  pkgconfig(libsystemd-daemon)
 
 %description
 Contacts Service Library
@@ -57,17 +58,18 @@ contacts-svc-helper schema
 chown :6005 /opt/dbspace/.contacts-svc.db
 chown :6005 /opt/dbspace/.contacts-svc.db-journal
 chown :6005 -R /opt/data/contacts-svc/img
-chown :6005 /opt/data/contacts-svc/.CONTACTS_SVC_*
+chown :6005 /opt/data/contacts-svc/.CONTACTS_SVC_*_CHANGED
 
 chmod 660 /opt/dbspace/.contacts-svc.db
 chmod 660 /opt/dbspace/.contacts-svc.db-journal
 chmod 770 -R /opt/data/contacts-svc/img/
 chmod 660 /opt/data/contacts-svc/.CONTACTS_SVC_*
-vconftool set -t int db/service/contacts/default_lang 1
+vconftool set -t int file/private/contacts-service/default_lang 1
 
 # from libcontacts-service.postinst
-vconftool set -t int db/service/contacts/name_sorting_order 0 -g 6005
-vconftool set -t int db/service/contacts/name_display_order 0 -g 6005
+chown :6016 /opt/data/contacts-svc/.CONTACTS_SVC_RESTRICTION_CHECK
+vconftool set -t int db/contacts-svc/name_sorting_order 0 -g 6005
+vconftool set -t int db/contacts-svc/name_display_order 0 -g 6005
 
 
 %postun -p /sbin/ldconfig
index 0e48b31..7714c11 100755 (executable)
 --PRAGMA journal_mode = PERSIST;
 --PRAGMA journal_mode = TRUNCATE;
 
+CREATE TABLE persons
+(
+person_id INTEGER PRIMARY KEY AUTOINCREMENT,
+outgoing_count INTEGER DEFAULT 0
+);
+
 CREATE TABLE addressbooks
 (
 addrbook_id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -39,11 +45,13 @@ CREATE TRIGGER trg_addressbook_del AFTER DELETE ON addressbooks
    DELETE FROM groups WHERE addrbook_id = old.addrbook_id;
    DELETE FROM contacts WHERE addrbook_id = old.addrbook_id;
    DELETE FROM deleteds WHERE addrbook_id = old.addrbook_id;
+   DELETE FROM group_deleteds WHERE addrbook_id = old.addrbook_id;
  END;
 
 CREATE TABLE contacts
 (
 contact_id INTEGER PRIMARY KEY AUTOINCREMENT,
+person_id INTEGER,
 addrbook_id INTEGER NOT NULL DEFAULT 0,
 default_num INTEGER,
 default_email INTEGER,
@@ -52,7 +60,6 @@ is_favorite INTEGER DEFAULT 0,
 created_ver INTEGER NOT NULL,
 changed_ver INTEGER NOT NULL,
 changed_time INTEGER NOT NULL,
-outgoing_count INTEGER DEFAULT 0,
 uid TEXT,
 ringtone TEXT,
 note TEXT,
@@ -60,6 +67,7 @@ image0 TEXT, -- normal image
 image1 TEXT -- full image
 );
 CREATE INDEX contacts_ver_idx ON contacts(changed_ver);
+CREATE INDEX contacts_person_idx ON contacts(person_id);
 CREATE TRIGGER trg_contacts_del AFTER DELETE ON contacts
  BEGIN
    DELETE FROM data WHERE contact_id = old.contact_id;
@@ -106,6 +114,7 @@ CREATE TABLE data
 (
 id INTEGER PRIMARY KEY AUTOINCREMENT,
 contact_id INTEGER NOT NULL,
+is_restricted INTEGER,
 datatype INTEGER NOT NULL,
 data1 INTEGER,
 data2 TEXT,
@@ -142,14 +151,25 @@ CREATE TABLE groups
 group_id INTEGER PRIMARY KEY AUTOINCREMENT,
 addrbook_id INTEGER,
 group_name TEXT,
+created_ver INTEGER NOT NULL,
+changed_ver INTEGER NOT NULL,
 ringtone TEXT,
 UNIQUE(addrbook_id, group_name)
 );
 CREATE TRIGGER trg_groups_del AFTER DELETE ON groups
  BEGIN
    DELETE FROM group_relations WHERE group_id = old.group_id;
+   DELETE FROM group_relations_log WHERE group_id = old.group_id;
  END;
 
+CREATE TABLE group_deleteds
+(
+group_id INTEGER PRIMARY KEY,
+addrbook_id INTEGER,
+deleted_ver INTEGER
+);
+CREATE INDEX grp_deleteds_ver_idx ON group_deleteds(deleted_ver);
+
 CREATE TABLE group_relations
 (
 group_id INTEGER NOT NULL,
@@ -158,6 +178,15 @@ UNIQUE(group_id, contact_id)
 );
 CREATE INDEX group_idx1 ON group_relations(contact_id);
 
+CREATE TABLE group_relations_log
+(
+group_id INTEGER NOT NULL,
+--contact_id INTEGER NOT NULL,
+type INTEGER NOT NULL,
+ver INTEGER NOT NULL,
+UNIQUE(group_id, type, ver)
+);
+
 CREATE TABLE speeddials
 (
 speed_num INTEGER PRIMARY KEY NOT NULL,
@@ -177,12 +206,12 @@ CREATE INDEX idx2_favorites ON favorites(type, related_id);
 CREATE TRIGGER trg_favorite_del BEFORE DELETE ON favorites
  BEGIN
    UPDATE data SET data3 = 0 WHERE old.type = 1 AND id = old.related_id AND datatype = 8;
-   UPDATE contacts SET is_favorite = 0 WHERE old.type = 0 AND contact_id = old.related_id;
+   UPDATE contacts SET is_favorite = 0 WHERE old.type = 0 AND person_id = old.related_id;
  END;
 CREATE TRIGGER trg_favorite_insert AFTER INSERT ON favorites
  BEGIN
    UPDATE data SET data3 = 1 WHERE new.type = 1 AND id = new.related_id AND datatype = 8;
-   UPDATE contacts SET is_favorite = 1 WHERE new.type = 0 AND contact_id = new.related_id;
+   UPDATE contacts SET is_favorite = 1 WHERE new.type = 0 AND person_id = new.related_id;
  END;
 
 CREATE TABLE phonelogs
@@ -190,7 +219,7 @@ CREATE TABLE phonelogs
 id INTEGER PRIMARY KEY AUTOINCREMENT,
 number TEXT,
 normal_num TEXT,
-related_id INTEGER, --contact_id
+related_id INTEGER, --person_id
 log_type INTEGER,
 log_time INTEGER,
 data1 INTEGER, --duration, message_id
@@ -214,3 +243,19 @@ duration INTEGER
 );
 INSERT INTO phonelog_accumulation VALUES(1, 0, NULL, 0);
 INSERT INTO phonelog_accumulation VALUES(2, 0, NULL, 0); --total
+
+CREATE TABLE my_profiles
+(
+id INTEGER PRIMARY KEY AUTOINCREMENT,
+datatype INTEGER NOT NULL,
+data1 INTEGER,
+data2 TEXT,
+data3 TEXT,
+data4 TEXT,
+data5 TEXT,
+data6 TEXT,
+data7 TEXT,
+data8 TEXT,
+data9 TEXT,
+data10 TEXT
+);
\ No newline at end of file
index c032754..4769094 100755 (executable)
@@ -22,6 +22,7 @@
 #include "cts-schema.h"
 #include "cts-sqlite.h"
 #include "cts-utils.h"
+#include "cts-person.h"
 #include "cts-addressbook.h"
 
 static inline int cts_reset_internal_addressbook(void)
@@ -132,6 +133,13 @@ API int contacts_svc_delete_addressbook(int addressbook_id)
                return ret;
        }
 
+       ret = cts_person_garbagecollection();
+       if (CTS_SUCCESS != ret) {
+               ERR("cts_person_garbagecollection() Failed(%d)", ret);
+               contacts_svc_end_trans(false);
+               return ret;
+       }
+
        ret = cts_db_change();
 
        if (0 < ret) {
diff --git a/src/cts-contact-read.c b/src/cts-contact-read.c
new file mode 100755 (executable)
index 0000000..ec4fc94
--- /dev/null
@@ -0,0 +1,1020 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjae Shin <yj99.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <time.h>
+
+#include "cts-internal.h"
+#include "cts-schema.h"
+#include "cts-sqlite.h"
+#include "cts-utils.h"
+#include "cts-normalize.h"
+#include "cts-restriction.h"
+#include "cts-im.h"
+#include "cts-contact.h"
+
+#define CTS_MAIN_CTS_GET_UID (1<<0)
+#define CTS_MAIN_CTS_GET_RINGTON (1<<1)
+#define CTS_MAIN_CTS_GET_NOTE (1<<2)
+#define CTS_MAIN_CTS_GET_DEFAULT_NUM (1<<3)
+#define CTS_MAIN_CTS_GET_DEFAULT_EMAIL (1<<4)
+#define CTS_MAIN_CTS_GET_FAVOR (1<<5)
+#define CTS_MAIN_CTS_GET_IMG (1<<6)
+#define CTS_MAIN_CTS_GET_ALL (1<<0|1<<1|1<<2|1<<3|1<<4|1<<5|1<<6)
+
+static int cts_get_main_contacts_info(int op_code, int index, contact_t *contact)
+{
+       int ret, len;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       char *temp;
+
+       len = snprintf(query, sizeof(query), "SELECT ");
+
+       len += snprintf(query+len, sizeof(query)-len,
+                       "contact_id, person_id, addrbook_id, changed_time");
+
+       if(op_code & CTS_MAIN_CTS_GET_UID)
+               len += snprintf(query+len, sizeof(query)-len, ", uid");
+       if (op_code & CTS_MAIN_CTS_GET_RINGTON)
+               len += snprintf(query+len, sizeof(query)-len, ", ringtone");
+       if (op_code & CTS_MAIN_CTS_GET_NOTE)
+               len += snprintf(query+len, sizeof(query)-len, ", note");
+       if (op_code & CTS_MAIN_CTS_GET_DEFAULT_NUM)
+               len += snprintf(query+len, sizeof(query)-len, ", default_num");
+       if (op_code & CTS_MAIN_CTS_GET_DEFAULT_EMAIL)
+               len += snprintf(query+len, sizeof(query)-len, ", default_email");
+       if (op_code & CTS_MAIN_CTS_GET_FAVOR)
+               len += snprintf(query+len, sizeof(query)-len, ", is_favorite");
+       if (op_code & CTS_MAIN_CTS_GET_IMG) {
+               len += snprintf(query+len, sizeof(query)-len, ", image0");
+               len += snprintf(query+len, sizeof(query)-len, ", image1");
+       }
+
+       snprintf(query+len, sizeof(query)-len,
+                       " FROM %s WHERE contact_id = %d", CTS_TABLE_CONTACTS, index);
+
+       stmt = cts_query_prepare(query);
+       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+
+       ret = cts_stmt_step(stmt);
+       if (CTS_TRUE != ret)
+       {
+               ERR("cts_stmt_step() Failed(%d)", ret);
+               cts_stmt_finalize(stmt);
+               return CTS_ERR_DB_RECORD_NOT_FOUND;
+       }
+       int count=0;
+
+       contact->base = (cts_ct_base *)contacts_svc_value_new(CTS_VALUE_CONTACT_BASE_INFO);
+       if (NULL == contact->base) {
+               cts_stmt_finalize(stmt);
+               ERR("contacts_svc_value_new(CTS_VALUE_CONTACT_BASE_INFO) Failed");
+               return CTS_ERR_OUT_OF_MEMORY;
+       }
+
+       contact->base->id = cts_stmt_get_int(stmt, count++);
+       contact->base->person_id = cts_stmt_get_int(stmt, count++);
+       contact->base->addrbook_id = cts_stmt_get_int(stmt, count++);
+       contact->base->changed_time = cts_stmt_get_int(stmt, count++);
+
+       if (op_code & CTS_MAIN_CTS_GET_UID)
+       {
+               contact->base->embedded = true;
+               temp = cts_stmt_get_text(stmt, count++);
+               contact->base->uid = SAFE_STRDUP(temp);
+       }
+       if (op_code & CTS_MAIN_CTS_GET_RINGTON)
+       {
+               contact->base->embedded = true;
+               temp = cts_stmt_get_text(stmt, count++);
+               if (temp && CTS_SUCCESS == cts_exist_file(temp))
+                       contact->base->ringtone_path = strdup(temp);
+               else
+                       contact->base->ringtone_path = NULL;
+       }
+       if (op_code & CTS_MAIN_CTS_GET_NOTE)
+       {
+               contact->base->embedded = true;
+               temp = cts_stmt_get_text(stmt, count++);
+               contact->base->note = SAFE_STRDUP(temp);
+       }
+       if (op_code & CTS_MAIN_CTS_GET_DEFAULT_NUM)
+               contact->default_num = cts_stmt_get_int(stmt, count++);
+       if (op_code & CTS_MAIN_CTS_GET_DEFAULT_EMAIL)
+               contact->default_email = cts_stmt_get_int(stmt, count++);
+       if (op_code & CTS_MAIN_CTS_GET_FAVOR)
+               contact->base->is_favorite = cts_stmt_get_int(stmt, count++);
+
+       if (op_code & CTS_MAIN_CTS_GET_IMG) {
+               char tmp_path[CTS_IMG_PATH_SIZE_MAX];
+               contact->base->embedded = true;
+               temp = cts_stmt_get_text(stmt, count++);
+               if (temp) {
+                       snprintf(tmp_path, sizeof(tmp_path), "%s/%s", CTS_IMAGE_LOCATION, temp);
+                       contact->base->img_path = strdup(tmp_path);
+               }
+               temp = cts_stmt_get_text(stmt, count++);
+               if (temp) {
+                       snprintf(tmp_path, sizeof(tmp_path), "%s/%s", CTS_IMAGE_LOCATION, temp);
+                       contact->base->full_img_path = strdup(tmp_path);
+               }
+       }
+
+       cts_stmt_finalize(stmt);
+
+       return CTS_SUCCESS;
+}
+
+static inline int cts_get_data_info_number(cts_stmt stmt, contact_t *contact)
+{
+       cts_number *result;
+
+       result = (cts_number *)contacts_svc_value_new(CTS_VALUE_NUMBER);
+       if (result) {
+               int cnt = 1;
+               result->embedded = true;
+               cnt = cts_stmt_get_number(stmt, result, cnt);
+
+               if (result->id == contact->default_num)
+                       result->is_default = true;
+
+               result->is_favorite = cts_stmt_get_int(stmt, cnt);
+               contact->numbers = g_slist_append(contact->numbers, result);
+       }
+       return CTS_SUCCESS;
+}
+
+static inline int cts_get_data_info_email(cts_stmt stmt, contact_t *contact)
+{
+       cts_email *result;
+
+       result = (cts_email *)contacts_svc_value_new(CTS_VALUE_EMAIL);
+       if (result) {
+               result->embedded = true;
+               cts_stmt_get_email(stmt, result, 1);
+
+               if (result->id == contact->default_email)
+                       result->is_default = true;
+
+               contact->emails = g_slist_append(contact->emails, result);
+       }
+       return CTS_SUCCESS;
+}
+
+static inline cts_name* cts_get_data_info_name(cts_stmt stmt)
+{
+       cts_name *result;
+
+       result = (cts_name *)contacts_svc_value_new(CTS_VALUE_NAME);
+       if (result) {
+               result->embedded = true;
+               cts_stmt_get_name(stmt, result, 1);
+       }
+       return result;
+}
+
+static inline int cts_get_data_info_event(cts_stmt stmt, contact_t *contact)
+{
+       int cnt=1;
+       cts_event *result;
+
+       result = (cts_event *)contacts_svc_value_new(CTS_VALUE_EVENT);
+       if (result) {
+               result->embedded = true;
+               result->id = cts_stmt_get_int(stmt, cnt++);
+               result->type = cts_stmt_get_int(stmt, cnt++);
+               result->date = cts_stmt_get_int(stmt, cnt++);
+
+               contact->events = g_slist_append(contact->events, result);
+       }
+       return CTS_SUCCESS;
+}
+
+static inline int cts_get_data_info_messenger(cts_stmt stmt, contact_t *contact)
+{
+       int cnt=1;
+       cts_messenger *result;
+
+       result = (cts_messenger *)contacts_svc_value_new(CTS_VALUE_MESSENGER);
+       if (result) {
+               char *temp;
+               result->embedded = true;
+               result->id = cts_stmt_get_int(stmt, cnt++);
+               result->type = cts_stmt_get_int(stmt, cnt++);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->im_id = SAFE_STRDUP(temp);
+               if (CTS_IM_TYPE_NONE == result->type) {
+                       temp = cts_stmt_get_text(stmt, cnt++);
+                       result->svc_name = SAFE_STRDUP(temp);
+                       temp = cts_stmt_get_text(stmt, cnt++);
+                       result->svc_op = SAFE_STRDUP(temp);
+               }
+               contact->messengers = g_slist_append(contact->messengers, result);
+       }
+       return CTS_SUCCESS;
+}
+
+static inline int cts_get_data_info_postal(cts_stmt stmt, contact_t *contact)
+{
+       int cnt=1;
+       cts_postal *result;
+
+       result = (cts_postal *)contacts_svc_value_new(CTS_VALUE_POSTAL);
+       if (result) {
+               char *temp;
+               result->embedded = true;
+               result->id = cts_stmt_get_int(stmt, cnt++);
+               result->type = cts_stmt_get_int(stmt, cnt++);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->pobox= SAFE_STRDUP(temp);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->postalcode = SAFE_STRDUP(temp);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->region= SAFE_STRDUP(temp);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->locality = SAFE_STRDUP(temp);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->street = SAFE_STRDUP(temp);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->extended = SAFE_STRDUP(temp);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->country = SAFE_STRDUP(temp);
+
+               contact->postal_addrs = g_slist_append(contact->postal_addrs, result);
+       }
+       return CTS_SUCCESS;
+}
+
+static inline int cts_get_data_info_web(cts_stmt stmt, contact_t *contact)
+{
+       int cnt=1;
+       cts_web *result;
+
+       result = (cts_web *)contacts_svc_value_new(CTS_VALUE_WEB);
+       if (result) {
+               char *temp;
+               result->embedded = true;
+               result->id = cts_stmt_get_int(stmt, cnt++);
+               result->type = cts_stmt_get_int(stmt, cnt++);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->url = SAFE_STRDUP(temp);
+
+               contact->web_addrs = g_slist_append(contact->web_addrs, result);
+       }
+       return CTS_SUCCESS;
+}
+
+static inline int cts_get_data_info_nick(cts_stmt stmt, contact_t *contact)
+{
+       int cnt=1;
+       cts_nickname *result;
+
+       result = (cts_nickname *)contacts_svc_value_new(CTS_VALUE_NICKNAME);
+       if (result) {
+               char *temp;
+               result->embedded = true;
+               result->id = cts_stmt_get_int(stmt, cnt++);
+               temp = cts_stmt_get_text(stmt, cnt+1);
+               result->nick = SAFE_STRDUP(temp);
+
+               contact->nicknames = g_slist_append(contact->nicknames, result);
+       }
+       return CTS_SUCCESS;
+}
+
+static inline cts_company* cts_get_data_info_company(cts_stmt stmt)
+{
+       int cnt=1;
+       cts_company *result;
+
+       result = (cts_company *)contacts_svc_value_new(CTS_VALUE_COMPANY);
+       retvm_if(NULL == result, NULL, "contacts_svc_value_new() Failed");
+
+       char *temp;
+       result->embedded = true;
+       result->id = cts_stmt_get_int(stmt, cnt++);
+       cnt++;
+       temp = cts_stmt_get_text(stmt, cnt++);
+       result->name = SAFE_STRDUP(temp);
+       temp = cts_stmt_get_text(stmt, cnt++);
+       result->department = SAFE_STRDUP(temp);
+       temp = cts_stmt_get_text(stmt, cnt++);
+       result->jot_title = SAFE_STRDUP(temp);
+       temp = cts_stmt_get_text(stmt, cnt++);
+       result->role = SAFE_STRDUP(temp);
+       temp = cts_stmt_get_text(stmt, cnt++);
+       result->assistant_name = SAFE_STRDUP(temp);
+
+       if (result->name || result->department || result->jot_title || result->role ||  result->assistant_name)
+               return result;
+       else {
+               contacts_svc_value_free((CTSvalue *)result);
+               return NULL;
+       }
+}
+
+static cts_extend* cts_make_extend_data(cts_stmt stmt, int type, int cnt)
+{
+       cts_extend *result;
+       result = (cts_extend *)contacts_svc_value_new(CTS_VALUE_EXTEND);
+       if (result)
+       {
+               char *temp;
+               result->type = type;
+               result->id = cts_stmt_get_int(stmt, cnt++);
+               result->data1 = cts_stmt_get_int(stmt, cnt++);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->data2= SAFE_STRDUP(temp);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->data3 = SAFE_STRDUP(temp);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->data4= SAFE_STRDUP(temp);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->data5 = SAFE_STRDUP(temp);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->data6 = SAFE_STRDUP(temp);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->data7 = SAFE_STRDUP(temp);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->data8 = SAFE_STRDUP(temp);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->data9 = SAFE_STRDUP(temp);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->data10 = SAFE_STRDUP(temp);
+       }
+       return result;
+}
+
+static inline int cts_get_data_info_extend(cts_stmt stmt, int type,
+               contact_t *contact)
+{
+       cts_extend *result;
+
+       result = cts_make_extend_data(stmt, type, 1);
+       if (result) {
+               result->embedded = true;
+               contact->extended_values = g_slist_append(contact->extended_values, result);
+       }
+       else
+               return CTS_ERR_OUT_OF_MEMORY;
+
+       return CTS_SUCCESS;
+}
+
+
+int cts_get_data_info(int op_code, int field, int index, contact_t *contact)
+{
+       int ret, datatype, len;
+       const char *data;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
+       switch (op_code)
+       {
+       case CTS_GET_DATA_BY_CONTACT_ID:
+               len = snprintf(query, sizeof(query), "SELECT datatype, id, data1, data2,"
+                               "data3, data4, data5, data6, data7, data8, data9, data10 "
+                               "FROM %s WHERE contact_id = %d", data, index);
+               break;
+       case CTS_GET_DATA_BY_ID:
+       default:
+               ERR("Invalid parameter : The op_code(%d) is not supported", op_code);
+               return CTS_ERR_ARG_INVALID;
+       }
+
+       if (CTS_DATA_FIELD_ALL != field && CTS_DATA_FIELD_EXTEND_ALL != field)
+       {
+               bool first= true;
+               len += snprintf(query+len, sizeof(query)-len, " AND datatype IN (");
+
+               if (field & CTS_DATA_FIELD_NAME) {
+                       first=false;
+                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_NAME);
+               }
+               if (field & CTS_DATA_FIELD_EVENT) {
+                       if (first)
+                               first=false;
+                       else
+                               len += snprintf(query+len, sizeof(query)-len, ", ");
+                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_EVENT);
+               }
+               if (field & CTS_DATA_FIELD_MESSENGER) {
+                       if (first)
+                               first=false;
+                       else
+                               len += snprintf(query+len, sizeof(query)-len, ", ");
+                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_MESSENGER);
+               }
+               if (field & CTS_DATA_FIELD_POSTAL) {
+                       if (first)
+                               first=false;
+                       else
+                               len += snprintf(query+len, sizeof(query)-len, ", ");
+                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_POSTAL);
+               }
+               if (field & CTS_DATA_FIELD_WEB) {
+                       if (first)
+                               first=false;
+                       else
+                               len += snprintf(query+len, sizeof(query)-len, ", ");
+                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_WEB);
+               }
+               if (field & CTS_DATA_FIELD_NICKNAME) {
+                       if (first)
+                               first=false;
+                       else
+                               len += snprintf(query+len, sizeof(query)-len, ", ");
+                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_NICKNAME);
+               }
+               if (field & CTS_DATA_FIELD_COMPANY) {
+                       if (first)
+                               first=false;
+                       else
+                               len += snprintf(query+len, sizeof(query)-len, ", ");
+                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_COMPANY);
+               }
+               if (field & CTS_DATA_FIELD_NUMBER) {
+                       if (first)
+                               first=false;
+                       else
+                               len += snprintf(query+len, sizeof(query)-len, ", ");
+                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_NUMBER);
+               }
+               if (field & CTS_DATA_FIELD_EMAIL) {
+                       if (first)
+                               first=false;
+                       else
+                               len += snprintf(query+len, sizeof(query)-len, ", ");
+                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_EMAIL);
+               }
+
+               len += snprintf(query+len, sizeof(query)-len, ")");
+       }
+
+       if (CTS_DATA_FIELD_ALL != field && field & CTS_DATA_FIELD_EXTEND_ALL) {
+               len += snprintf(query+len, sizeof(query)-len, " AND datatype>=%d",
+                               CTS_DATA_EXTEND_START);
+       }
+
+       stmt = cts_query_prepare(query);
+       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+
+       ret = cts_stmt_step(stmt);
+       if (CTS_TRUE != ret)
+       {
+               ERR("cts_stmt_step() Failed(%d)", ret);
+               cts_stmt_finalize(stmt);
+               return CTS_ERR_DB_RECORD_NOT_FOUND;
+       }
+
+       do {
+               datatype = cts_stmt_get_int(stmt, 0);
+
+               switch (datatype)
+               {
+               case CTS_DATA_NAME:
+                       if (contact->name)
+                               ERR("name already Exist");
+                       else
+                               contact->name = cts_get_data_info_name(stmt);
+                       break;
+               case CTS_DATA_EVENT:
+                       cts_get_data_info_event(stmt, contact);
+                       break;
+               case CTS_DATA_MESSENGER:
+                       cts_get_data_info_messenger(stmt, contact);
+                       break;
+               case CTS_DATA_POSTAL:
+                       cts_get_data_info_postal(stmt, contact);
+                       break;
+               case CTS_DATA_WEB:
+                       cts_get_data_info_web(stmt, contact);
+                       break;
+               case CTS_DATA_NICKNAME:
+                       cts_get_data_info_nick(stmt, contact);
+                       break;
+               case CTS_DATA_NUMBER:
+                       cts_get_data_info_number(stmt, contact);
+                       break;
+               case CTS_DATA_EMAIL:
+                       cts_get_data_info_email(stmt, contact);
+                       break;
+               case CTS_DATA_COMPANY:
+                       if (contact->company)
+                               ERR("company already Exist");
+                       else
+                               contact->company = cts_get_data_info_company(stmt);
+                       break;
+               default:
+                       if (CTS_DATA_EXTEND_START <= datatype) {
+                               cts_get_data_info_extend(stmt, datatype, contact);
+                               break;
+                       }
+                       ERR("Unknown data type(%d)", datatype);
+                       continue;
+               }
+       }while(CTS_TRUE == cts_stmt_step(stmt));
+
+       cts_stmt_finalize(stmt);
+
+       return CTS_SUCCESS;
+}
+
+static inline int cts_get_groups_info(int index, contact_t *contact)
+{
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       GSList *result_list=NULL;
+
+       snprintf(query, sizeof(query), "SELECT group_id, addrbook_id,"
+                       " group_name"
+                       " FROM %s WHERE group_id IN (SELECT group_id"
+                       " FROM %s WHERE contact_id = %d)"
+                       " ORDER BY group_name COLLATE NOCASE",
+                       CTS_TABLE_GROUPS, CTS_TABLE_GROUPING_INFO, index);
+
+       stmt = cts_query_prepare(query);
+       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+
+       while (CTS_TRUE == cts_stmt_step(stmt))
+       {
+               cts_group *group_info;
+               group_info = (cts_group *)contacts_svc_value_new(CTS_VALUE_GROUP_RELATION);
+
+               if (group_info)
+               {
+                       group_info->id = cts_stmt_get_int(stmt, 0);
+                       group_info->addrbook_id = cts_stmt_get_int(stmt, 1);
+                       group_info->embedded = true;
+                       group_info->name = SAFE_STRDUP(cts_stmt_get_text(stmt, 2));
+                       group_info->img_loaded = false; //It will load at cts_value_get_str_group()
+
+                       result_list = g_slist_append(result_list, group_info);
+               }
+       }
+
+       cts_stmt_finalize(stmt);
+       contact->grouprelations = result_list;
+
+       return CTS_SUCCESS;
+
+}
+
+static inline int cts_get_number_value(int op_code, int id, CTSvalue **value)
+{
+       int ret;
+       cts_stmt stmt;
+       const char *data;
+       cts_number *number;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
+       if (CTS_GET_DEFAULT_NUMBER_VALUE == op_code) {
+               snprintf(query, sizeof(query),
+                               "SELECT B.id, B.data1, B.data2 FROM %s A, %s B "
+                               "WHERE A.contact_id = %d AND B.id=A.default_num AND B.datatype = %d",
+                               CTS_TABLE_CONTACTS, data, id, CTS_DATA_NUMBER);
+       }
+       else if (CTS_GET_NUMBER_VALUE == op_code) {
+               snprintf(query, sizeof(query),
+                               "SELECT id, data1, data2, contact_id FROM %s "
+                               "WHERE id = %d AND datatype = %d",
+                               data, id, CTS_DATA_NUMBER);
+       }
+       else {
+               ERR("Invalid op_code(%d)", op_code);
+               return CTS_ERR_ARG_INVALID;
+       }
+
+       stmt = cts_query_prepare(query);
+       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+
+       ret = cts_stmt_step(stmt);
+       if (CTS_TRUE != ret)
+       {
+               ERR("cts_stmt_step() Failed(%d)", ret);
+               cts_stmt_finalize(stmt);
+               return CTS_ERR_DB_RECORD_NOT_FOUND;
+       }
+
+       number = (cts_number *)contacts_svc_value_new(CTS_VALUE_NUMBER);
+       if (number) {
+               ret = CTS_SUCCESS;
+               number->v_type = CTS_VALUE_RDONLY_NUMBER;
+               number->embedded = true;
+               cts_stmt_get_number(stmt, number, 0);
+
+               if (CTS_GET_DEFAULT_NUMBER_VALUE == op_code)
+                       number->is_default = true;
+               else
+                       ret = cts_stmt_get_int(stmt, 3);
+
+               *value = (CTSvalue*) number;
+
+               cts_stmt_finalize(stmt);
+               return ret;
+       }
+       else {
+               ERR("contacts_svc_value_new() Failed");
+               cts_stmt_finalize(stmt);
+               return CTS_ERR_OUT_OF_MEMORY;
+       }
+}
+
+static inline int cts_get_email_value(int op_code, int id, CTSvalue **value)
+{
+       int ret;
+       cts_stmt stmt;
+       const char *data;
+       cts_email *email;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
+       if (CTS_GET_DEFAULT_EMAIL_VALUE == op_code) {
+               snprintf(query, sizeof(query),
+                               "SELECT B.id, B.data1, B.data2 FROM %s A, %s B "
+                               "WHERE A.contact_id = %d AND B.id=A.default_email AND B.datatype = %d",
+                               CTS_TABLE_CONTACTS, data, id, CTS_DATA_EMAIL);
+       }
+       else if (CTS_GET_EMAIL_VALUE == op_code) {
+               snprintf(query, sizeof(query),
+                               "SELECT id, data1, data2, contact_id FROM %s "
+                               "WHERE id = %d AND datatype = %d",
+                               data, id, CTS_DATA_EMAIL);
+       }
+       else {
+               ERR("Invalid op_code(%d)", op_code);
+               return CTS_ERR_ARG_INVALID;
+       }
+
+       stmt = cts_query_prepare(query);
+       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+
+       ret = cts_stmt_step(stmt);
+       if (CTS_TRUE != ret)
+       {
+               ERR("cts_stmt_step() Failed(%d)", ret);
+               cts_stmt_finalize(stmt);
+               return CTS_ERR_DB_RECORD_NOT_FOUND;
+       }
+
+       email = (cts_email *)contacts_svc_value_new(CTS_VALUE_EMAIL);
+       if (email)
+       {
+               ret = CTS_SUCCESS;
+               email->v_type = CTS_VALUE_RDONLY_EMAIL;
+               email->embedded = true;
+               cts_stmt_get_email(stmt, email, 0);
+
+               if (CTS_GET_DEFAULT_EMAIL_VALUE == op_code)
+                       email->is_default = true;
+               else
+                       ret = cts_stmt_get_int(stmt, 3);
+
+               *value = (CTSvalue*) email;
+
+               cts_stmt_finalize(stmt);
+               return ret;
+       }
+       else
+       {
+               ERR("contacts_svc_value_new() Failed");
+               cts_stmt_finalize(stmt);
+               return CTS_ERR_OUT_OF_MEMORY;
+       }
+}
+
+static inline int cts_get_extend_data(int type, int id, CTSvalue **value)
+{
+       int ret;
+       cts_stmt stmt;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query), "SELECT id, data1, data2,"
+                       "data3, data4, data5, data6, data7, data8, data9, data10 "
+                       "FROM %s WHERE datatype = %d AND contact_id = %d", CTS_TABLE_DATA, type, id);
+
+       stmt = cts_query_prepare(query);
+       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+
+       ret = cts_stmt_step(stmt);
+       if (CTS_TRUE != ret)
+       {
+               ERR("cts_stmt_step() Failed(%d)", ret);
+               cts_stmt_finalize(stmt);
+               return CTS_ERR_DB_RECORD_NOT_FOUND;
+       }
+
+       *value = (CTSvalue *)cts_make_extend_data(stmt, type, 0);
+       cts_stmt_finalize(stmt);
+
+       retvm_if(NULL == *value, CTS_ERR_OUT_OF_MEMORY, "cts_make_extend_data() return NULL");
+
+       return CTS_SUCCESS;
+}
+
+API int contacts_svc_get_contact_value(cts_get_contact_val_op op_code,
+               int id, CTSvalue **value)
+{
+       int ret;
+       contact_t temp={0};
+
+       retv_if(NULL == value, CTS_ERR_ARG_NULL);
+       CTS_START_TIME_CHECK;
+
+       if ((int)CTS_DATA_EXTEND_START <= op_code) {
+               ret = cts_get_extend_data(op_code, id, value);
+               retvm_if(CTS_SUCCESS != ret, ret, "cts_get_extend_data() Failed(%d)", ret);
+       }
+       else {
+               switch (op_code)
+               {
+               case CTS_GET_NAME_VALUE:
+                       ret = cts_get_data_info(CTS_GET_DATA_BY_CONTACT_ID,
+                                       CTS_DATA_FIELD_NAME, id, &temp);
+                       retvm_if(CTS_SUCCESS != ret, ret,
+                                       "cts_get_data_info(CTS_GET_DATA_BY_CONTACT_ID) Failed(%d)", ret);
+                       if (temp.name) {
+                               temp.name->v_type = CTS_VALUE_RDONLY_NAME;
+                               *value = (CTSvalue *)temp.name;
+                       }else
+                               *value = NULL;
+                       break;
+               case CTS_GET_DEFAULT_NUMBER_VALUE:
+               case CTS_GET_NUMBER_VALUE:
+                       ret = cts_get_number_value(op_code, id, value);
+                       retvm_if(ret < CTS_SUCCESS, ret,
+                                       "cts_get_number_value() Failed(%d)", ret);
+                       break;
+               case CTS_GET_DEFAULT_EMAIL_VALUE:
+               case CTS_GET_EMAIL_VALUE:
+                       ret = cts_get_email_value(op_code, id, value);
+                       retvm_if(ret < CTS_SUCCESS, ret, "cts_get_email_value() Failed(%d)", ret);
+                       break;
+               case CTS_GET_COMPANY_VALUE:
+                       ret = cts_get_data_info(CTS_GET_DATA_BY_CONTACT_ID,
+                                       CTS_DATA_FIELD_COMPANY, id, &temp);
+                       retvm_if(CTS_SUCCESS != ret, ret,
+                                       "cts_get_data_info(CTS_DATA_FIELD_COMPANY) Failed(%d)", ret);
+                       if (temp.company) {
+                               temp.company->v_type = CTS_VALUE_RDONLY_COMPANY;
+                               *value = (CTSvalue *)temp.company;
+                       }else
+                               *value = NULL;
+                       break;
+               default:
+                       ERR("Invalid parameter : The op_code(%d) is not supported", op_code);
+                       return CTS_ERR_ARG_INVALID;
+               }
+       }
+       if (NULL == *value) return CTS_ERR_NO_DATA;
+
+       CTS_END_TIME_CHECK();
+       return ret;
+}
+
+static inline cts_ct_base* cts_get_myprofile_base(cts_stmt stmt)
+{
+       cts_ct_base *result;
+
+       result = (cts_ct_base *)contacts_svc_value_new(CTS_VALUE_CONTACT_BASE_INFO);
+       if (result) {
+               char *temp;
+
+               result->embedded = true;
+               temp = cts_stmt_get_text(stmt, 2);
+               result->note = SAFE_STRDUP(temp);
+               result->img_path = cts_get_img(CTS_MY_IMAGE_LOCATION, 0, NULL, 0);
+       }
+       return result;
+}
+
+int cts_get_myprofile_data(contact_t *contact)
+{
+       int ret, datatype, len;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN];
+
+       len = snprintf(query, sizeof(query), "SELECT datatype, id, data1, data2,"
+                       "data3, data4, data5, data6, data7, data8, data9, data10 "
+                       "FROM %s ", CTS_TABLE_MY_PROFILES);
+
+       stmt = cts_query_prepare(query);
+       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+
+       ret = cts_stmt_step(stmt);
+       if (CTS_TRUE != ret) {
+               ERR("cts_stmt_step() Failed(%d)", ret);
+               cts_stmt_finalize(stmt);
+               return CTS_ERR_DB_RECORD_NOT_FOUND;
+       }
+
+       do {
+               datatype = cts_stmt_get_int(stmt, 0);
+
+               switch (datatype)
+               {
+               case 0:
+                       contact->base = cts_get_myprofile_base(stmt);
+                       break;
+               case CTS_DATA_NAME:
+                       if (contact->name)
+                               ERR("name already Exist");
+                       else
+                               contact->name = cts_get_data_info_name(stmt);
+                       break;
+               case CTS_DATA_EVENT:
+                       cts_get_data_info_event(stmt, contact);
+                       break;
+               case CTS_DATA_MESSENGER:
+                       cts_get_data_info_messenger(stmt, contact);
+                       break;
+               case CTS_DATA_POSTAL:
+                       cts_get_data_info_postal(stmt, contact);
+                       break;
+               case CTS_DATA_WEB:
+                       cts_get_data_info_web(stmt, contact);
+                       break;
+               case CTS_DATA_NICKNAME:
+                       cts_get_data_info_nick(stmt, contact);
+                       break;
+               case CTS_DATA_NUMBER:
+                       cts_get_data_info_number(stmt, contact);
+                       break;
+               case CTS_DATA_EMAIL:
+                       cts_get_data_info_email(stmt, contact);
+                       break;
+               case CTS_DATA_COMPANY:
+                       if (contact->company)
+                               ERR("company already Exist");
+                       else
+                               contact->company = cts_get_data_info_company(stmt);
+                       break;
+               default:
+                       if (CTS_DATA_EXTEND_START <= datatype) {
+                               cts_get_data_info_extend(stmt, datatype, contact);
+                               break;
+                       }
+                       ERR("Unknown data type(%d)", datatype);
+                       continue;
+               }
+       }while(CTS_TRUE == cts_stmt_step(stmt));
+
+       cts_stmt_finalize(stmt);
+
+       return CTS_SUCCESS;
+}
+
+int cts_get_myprofile(CTSstruct **contact)
+{
+       int ret;
+       contact_t *record;
+
+       retv_if(NULL == contact, CTS_ERR_ARG_NULL);
+
+       record = (contact_t *)contacts_svc_struct_new(CTS_STRUCT_CONTACT);
+
+       ret = cts_get_myprofile_data(record);
+       if (CTS_SUCCESS != ret) {
+               ERR("cts_get_myprofile_data() Failed(%d)", ret);
+               contacts_svc_struct_free((CTSstruct *)record);
+               return ret;
+       }
+
+       *contact = (CTSstruct *)record;
+       return CTS_SUCCESS;
+}
+
+API int contacts_svc_get_contact(int index, CTSstruct **contact)
+{
+       int ret;
+       contact_t *record;
+
+       retv_if(NULL == contact, CTS_ERR_ARG_NULL);
+       if (0 == index)
+               return cts_get_myprofile(contact);
+       CTS_START_TIME_CHECK;
+
+       record = (contact_t *)contacts_svc_struct_new(CTS_STRUCT_CONTACT);
+
+       ret = cts_get_main_contacts_info(CTS_MAIN_CTS_GET_ALL, index, record);
+       if (CTS_SUCCESS != ret) {
+               ERR("cts_get_main_contacts_info(ALL) Failed(%d)", ret);
+               goto CTS_RETURN_ERROR;
+       }
+
+       ret = cts_get_data_info(CTS_GET_DATA_BY_CONTACT_ID,
+                       CTS_DATA_FIELD_ALL, index, record);
+       if (CTS_SUCCESS != ret) {
+               ERR("cts_get_data_info(CTS_GET_DATA_BY_CONTACT_ID) Failed(%d)", ret);
+               goto CTS_RETURN_ERROR;
+       }
+
+       ret = cts_get_groups_info(index, record);
+       if (CTS_SUCCESS != ret) {
+               ERR("cts_get_group_info(CTS_GET_DATA_BY_CONTACT_ID) Failed(%d)", ret);
+               goto CTS_RETURN_ERROR;
+       }
+
+       *contact = (CTSstruct *)record;
+
+       CTS_END_TIME_CHECK();
+       return CTS_SUCCESS;
+
+CTS_RETURN_ERROR:
+       contacts_svc_struct_free((CTSstruct *)record);
+       return ret;
+}
+
+API int contacts_svc_find_contact_by(cts_find_op op_code,
+               const char *user_data)
+{
+       int ret;
+       const char *temp, *data;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       char normalized_val[CTS_SQL_MIN_LEN];
+
+       CTS_START_TIME_CHECK;
+       retv_if(NULL == user_data, CTS_ERR_ARG_NULL);
+
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
+       switch (op_code)
+       {
+       case CTS_FIND_BY_NUMBER:
+               ret = cts_clean_number(user_data, normalized_val, sizeof(normalized_val));
+               retvm_if(ret <= 0, CTS_ERR_ARG_INVALID, "Number(%s) is invalid", user_data);
+
+               temp = cts_normalize_number(normalized_val);
+               snprintf(query, sizeof(query), "SELECT contact_id "
+                               "FROM %s WHERE datatype = %d AND data3 = '%s' LIMIT 1",
+                               data, CTS_DATA_NUMBER, temp);
+               ret = cts_query_get_first_int_result(query);
+               break;
+       case CTS_FIND_BY_EMAIL:
+               snprintf(query, sizeof(query), "SELECT contact_id "
+                               "FROM %s WHERE datatype = %d AND data2 = '%s' LIMIT 1",
+                               data, CTS_DATA_EMAIL, user_data);
+               ret = cts_query_get_first_int_result(query);
+               break;
+       case CTS_FIND_BY_NAME:
+               ret = cts_normalize_str(user_data, normalized_val, sizeof(normalized_val));
+               retvm_if(ret < CTS_SUCCESS, ret, "cts_normalize_str() Failed(%d)", ret);
+
+               if (CTS_ORDER_NAME_LASTFIRST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
+                       temp = CTS_SCHEMA_DATA_NAME_REVERSE_LOOKUP;
+               else
+                       temp = CTS_SCHEMA_DATA_NAME_LOOKUP;
+
+               snprintf(query, sizeof(query), "SELECT contact_id FROM %s "
+                               "WHERE %s LIKE '%%%s%%' LIMIT 1",
+                               data, temp, normalized_val);
+
+               ret = cts_query_get_first_int_result(query);
+               break;
+       case CTS_FIND_BY_UID:
+               snprintf(query, sizeof(query), "SELECT contact_id "
+                               "FROM %s WHERE uid = '%s' LIMIT 1", CTS_TABLE_CONTACTS, user_data);
+               ret = cts_query_get_first_int_result(query);
+               break;
+       default:
+               ERR("Invalid parameter : The op_code(%d) is not supported", op_code);
+               return CTS_ERR_ARG_INVALID;
+       }
+
+       CTS_END_TIME_CHECK();
+       return ret;
+}
similarity index 67%
rename from src/cts-contact.c
rename to src/cts-contact-write.c
index ed997fe..590dd11 100755 (executable)
@@ -27,6 +27,9 @@
 #include "cts-group.h"
 #include "cts-types.h"
 #include "cts-normalize.h"
+#include "cts-person.h"
+#include "cts-restriction.h"
+#include "cts-im.h"
 #include "cts-contact.h"
 
 static const int CTS_UPDATE_ID_LOC = 11;
@@ -54,17 +57,13 @@ static inline int cts_insert_contact_data_number(cts_stmt stmt,
                        cnt = 1;
                        cts_stmt_bind_int(stmt, cnt++, CTS_DATA_NUMBER);
                        cts_stmt_bind_int(stmt, cnt++, number_data->type);
+                       cts_stmt_bind_text(stmt, cnt++, number_data->number);
                        ret = cts_clean_number(number_data->number, clean_num, sizeof(clean_num));
-                       if (ret <= 0) {
-                               ERR("Number(%s) is invalid", number_data->number);
-                               number_repeat = g_slist_next(number_repeat);
-                               continue;
+                       if (0 < ret) {
+                               normal_num = cts_normalize_number(clean_num);
+                               cts_stmt_bind_text(stmt, cnt++, normal_num);
                        }
 
-                       cts_stmt_bind_text(stmt, cnt++, clean_num);
-                       normal_num = cts_normalize_number(clean_num);
-                       cts_stmt_bind_text(stmt, cnt++, normal_num);
-
                        ret = cts_stmt_step(stmt);
                        retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
                        number_data->id = cts_db_get_last_insert_id();
@@ -127,6 +126,7 @@ static inline int cts_insert_contact_grouprel(int acc_id, int index,
 
        GSList *group_repeat = group_list;
        cts_group *group_data;
+       int rel_changed = 0;
 
        retv_if(NULL == group_list, CTS_ERR_ARG_NULL);
 
@@ -160,10 +160,15 @@ static inline int cts_insert_contact_grouprel(int acc_id, int index,
                if (group_data->id) {
                        int ret = cts_group_set_relation(group_data->id, index, acc_id);
                        retvm_if(ret < CTS_SUCCESS, ret, "cts_group_set_relation() Failed(%d)", ret);
+                       if (0 < ret)
+                               rel_changed += ret;
                }
        }while(group_repeat);
 
-       return CTS_SUCCESS;
+       if (rel_changed)
+               return rel_changed;
+       else
+               return CTS_SUCCESS;
 }
 
 static inline int cts_insert_contact_data_event(cts_stmt stmt,
@@ -371,9 +376,12 @@ static inline int cts_insert_contact_data_name(cts_stmt stmt,
        char display[CTS_SQL_MAX_LEN]={0};
        char lookup[CTS_SQL_MAX_LEN]={0};
        char reverse_lookup[CTS_SQL_MAX_LEN]={0};
+       char normal_name[CTS_NN_MAX][CTS_SQL_MAX_LEN]={{0},{0},{0}};    //insert name search info
 
-       //insert name search info
-       char normal_name[CTS_NN_MAX][CTS_SQL_MAX_LEN]={{0},{0},{0}};
+       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
+       retv_if(NULL == name, CTS_ERR_ARG_NULL);
+
+       cts_stmt_bind_int(stmt, 1, CTS_DATA_NAME);
 
        tmp_display = name->display;
        tmp_first = name->first;
@@ -431,11 +439,11 @@ static inline int cts_insert_contact_data_name(cts_stmt stmt,
        name->last = tmp_last;
 
        ret = cts_make_name_lookup(CTS_ORDER_NAME_FIRSTLAST, &normalize_name,
-                                                                               lookup, sizeof(lookup));
+                       lookup, sizeof(lookup));
        retvm_if(CTS_SUCCESS != ret, ret, "cts_make_name_lookup() Failed(%d)", ret);
 
        ret = cts_make_name_lookup(CTS_ORDER_NAME_LASTFIRST, &normalize_name,
-                                                                               reverse_lookup, sizeof(reverse_lookup));
+                       reverse_lookup, sizeof(reverse_lookup));
        retvm_if(CTS_SUCCESS != ret, ret, "cts_make_name_lookup() Failed(%d)", ret);
 
        CTS_DBG("lookup=%s(%d), reverse_lookup=%s(%d)",
@@ -445,7 +453,35 @@ static inline int cts_insert_contact_data_name(cts_stmt stmt,
        cts_stmt_bind_text(stmt, cnt++, reverse_lookup);
        cts_stmt_bind_text(stmt, cnt++, normal_name[CTS_NN_SORTKEY]);
 
-       return cnt;
+       ret = cts_stmt_step(stmt);
+       if (CTS_SUCCESS != ret) {
+               ERR("cts_stmt_step() Failed(%d)", ret);
+               cts_stmt_finalize(stmt);
+               return ret;
+       }
+       cts_stmt_reset(stmt);
+
+       return CTS_SUCCESS;
+}
+
+
+static inline int cts_insert_contact_data_company(cts_stmt stmt,
+               cts_company *com)
+{
+       int ret;
+
+       if (com->name || com->department || com->jot_title || com->role || com->assistant_name) {
+               cts_stmt_bind_int(stmt, 1, CTS_DATA_COMPANY);
+               cts_stmt_bind_company(stmt, 2, com);
+               ret = cts_stmt_step(stmt);
+               if (CTS_SUCCESS != ret) {
+                       ERR("cts_stmt_step() Failed(%d)", ret);
+                       cts_stmt_finalize(stmt);
+                       return ret;
+               }
+               cts_stmt_reset(stmt);
+       }
+       return CTS_SUCCESS;
 }
 
 static int cts_insert_contact_data(int field, contact_t *contact)
@@ -454,53 +490,32 @@ static int cts_insert_contact_data(int field, contact_t *contact)
        cts_stmt stmt = NULL;
        char query[CTS_SQL_MAX_LEN] = {0};
 
-       snprintf(query, sizeof(query), "INSERT INTO %s(contact_id, datatype, "
+       snprintf(query, sizeof(query), "INSERT INTO %s(contact_id, is_restricted, datatype, "
                        "data1, data2, data3, data4, data5, data6, data7, data8, data9, data10) "
-                       "VALUES(%d, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
-                       CTS_TABLE_DATA, contact->base->id);
+                       "VALUES(%d, %d, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+                       CTS_TABLE_DATA, contact->base->id, contact->is_restricted);
 
        stmt = cts_query_prepare(query);
        retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
 
        //Insert the name
-       if ((field & CTS_DATA_FIELD_NAME))
-       {
-               cts_stmt_bind_int(stmt, 1, CTS_DATA_NAME);
-
-               if (contact->name) {
-                       ret = cts_insert_contact_data_name(stmt, contact->name);
-                       if (ret < CTS_SUCCESS)
-                       {
-                               ERR("cts_insert_contact_data_name() Failed(%d)", ret);
-                               cts_stmt_finalize(stmt);
-                               return ret;
-                       }
-               }
-
-               ret = cts_stmt_step(stmt);
+       if (contact->name && (field & CTS_DATA_FIELD_NAME)) {
+               ret = cts_insert_contact_data_name(stmt, contact->name);
                if (CTS_SUCCESS != ret) {
-                       ERR("cts_stmt_step() Failed(%d)", ret);
+                       ERR("cts_insert_contact_data_name() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
                }
-               cts_stmt_reset(stmt);
        }
 
        //Insert the company
        if (contact->company && (field & CTS_DATA_FIELD_COMPANY))
        {
-               cts_company *com = contact->company;
-               if (com->name || com->department || com->jot_title || com->role || com->assistant_name) {
-                       cts_stmt_bind_int(stmt, 1, CTS_DATA_COMPANY);
-                       cts_stmt_bind_company(stmt, 2, com);
-
-                       ret = cts_stmt_step(stmt);
-                       if (CTS_SUCCESS != ret) {
-                               ERR("cts_stmt_step() Failed(%d)", ret);
-                               cts_stmt_finalize(stmt);
-                               return ret;
-                       }
-                       cts_stmt_reset(stmt);
+               cts_insert_contact_data_company(stmt, contact->company);
+               if (CTS_SUCCESS != ret) {
+                       ERR("cts_insert_contact_data_company() Failed(%d)", ret);
+                       cts_stmt_finalize(stmt);
+                       return ret;
                }
        }
 
@@ -508,9 +523,7 @@ static int cts_insert_contact_data(int field, contact_t *contact)
        if (contact->events && (field & CTS_DATA_FIELD_EVENT))
        {
                ret = cts_insert_contact_data_event(stmt, contact->events);
-
-               if (CTS_SUCCESS != ret)
-               {
+               if (CTS_SUCCESS != ret) {
                        ERR("cts_insert_contact_data_event() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
@@ -521,9 +534,7 @@ static int cts_insert_contact_data(int field, contact_t *contact)
        if (contact->messengers && (field & CTS_DATA_FIELD_MESSENGER))
        {
                ret = cts_insert_contact_data_messenger(stmt, contact->messengers);
-
-               if (CTS_SUCCESS != ret)
-               {
+               if (CTS_SUCCESS != ret) {
                        ERR("cts_insert_contact_data_messenger() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
@@ -534,9 +545,7 @@ static int cts_insert_contact_data(int field, contact_t *contact)
        if (contact->postal_addrs && (field & CTS_DATA_FIELD_POSTAL))
        {
                ret = cts_insert_contact_data_postal(stmt, contact->postal_addrs);
-
-               if (CTS_SUCCESS != ret)
-               {
+               if (CTS_SUCCESS != ret) {
                        ERR("cts_insert_contact_data_postal() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
@@ -547,9 +556,7 @@ static int cts_insert_contact_data(int field, contact_t *contact)
        if (contact->web_addrs && (field & CTS_DATA_FIELD_WEB))
        {
                ret = cts_insert_contact_data_web(stmt, contact->web_addrs);
-
-               if (CTS_SUCCESS != ret)
-               {
+               if (CTS_SUCCESS != ret) {
                        ERR("cts_insert_contact_data_web() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
@@ -560,9 +567,7 @@ static int cts_insert_contact_data(int field, contact_t *contact)
        if (contact->nicknames && (field & CTS_DATA_FIELD_NICKNAME))
        {
                ret = cts_insert_contact_data_nick(stmt, contact->nicknames);
-
-               if (CTS_SUCCESS != ret)
-               {
+               if (CTS_SUCCESS != ret) {
                        ERR("cts_insert_contact_data_nick() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
@@ -573,9 +578,7 @@ static int cts_insert_contact_data(int field, contact_t *contact)
        if (contact->numbers && (field & CTS_DATA_FIELD_NUMBER))
        {
                ret = cts_insert_contact_data_number(stmt, contact->numbers);
-
-               if (ret < CTS_SUCCESS)
-               {
+               if (ret < CTS_SUCCESS) {
                        ERR("cts_insert_contact_data_number() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
@@ -587,7 +590,6 @@ static int cts_insert_contact_data(int field, contact_t *contact)
        if (contact->emails && (field & CTS_DATA_FIELD_EMAIL))
        {
                ret = cts_insert_contact_data_email(stmt, contact->emails);
-
                if (ret < CTS_SUCCESS) {
                        ERR("cts_insert_contact_data_email() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
@@ -601,9 +603,7 @@ static int cts_insert_contact_data(int field, contact_t *contact)
        if (contact->extended_values && (field & CTS_DATA_FIELD_EXTEND_ALL))
        {
                ret = cts_insert_contact_data_extend(stmt, contact->extended_values);
-
-               if (CTS_SUCCESS != ret)
-               {
+               if (CTS_SUCCESS != ret) {
                        ERR("cts_insert_contact_data_extend() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
@@ -859,42 +859,16 @@ static inline void cts_contact_remove_dup_data_postal(GSList *postals)
        }
 }
 
-
-static void cts_contact_remove_dup_data(contact_t *contact)
-{
-       if (contact->numbers)
-               cts_contact_remove_dup_data_number(contact->numbers);
-
-       if (contact->emails)
-               cts_contact_remove_dup_data_email(contact->emails);
-
-       if (contact->events)
-               cts_contact_remove_dup_data_event(contact->events);
-
-       if (contact->messengers)
-               cts_contact_remove_dup_data_IM(contact->messengers);
-
-       if (contact->web_addrs)
-               cts_contact_remove_dup_data_web(contact->web_addrs);
-
-       if (contact->nicknames)
-               cts_contact_remove_dup_data_nick(contact->nicknames);
-
-       if (contact->postal_addrs)
-               cts_contact_remove_dup_data_postal(contact->postal_addrs);
-
-}
-
 static inline int cts_insert_contact(int addressbook_id, contact_t *contact)
 {
-       int ret;
+       int ret, ver;
        char query[CTS_SQL_MAX_LEN] = {0};
        char normal_img[CTS_SQL_MAX_LEN], full_img[CTS_SQL_MAX_LEN];
+       int rel_changed = 0;
 
        retv_if(NULL == contact, CTS_ERR_ARG_NULL);
 
        cts_insert_contact_handle_no_name(contact);
-       cts_contact_remove_dup_data(contact);
 
        //Insert Data
        ret = cts_insert_contact_data(CTS_DATA_FIELD_ALL, contact);
@@ -903,9 +877,9 @@ static inline int cts_insert_contact(int addressbook_id, contact_t *contact)
        //Insert group Info
        if (contact->grouprelations)
        {
-               ret = cts_insert_contact_grouprel(addressbook_id, contact->base->id,
+               rel_changed = cts_insert_contact_grouprel(addressbook_id, contact->base->id,
                                contact->grouprelations);
-               retvm_if(ret < CTS_SUCCESS, ret, "cts_insert_contact_grouprel() Failed(%d)", ret);
+               retvm_if(rel_changed < CTS_SUCCESS, rel_changed, "cts_insert_contact_grouprel() Failed(%d)", rel_changed);
        }
 
        // default setting
@@ -914,14 +888,18 @@ static inline int cts_insert_contact(int addressbook_id, contact_t *contact)
        retvm_if(CTS_SUCCESS != ret, ret, "cts_set_first_id_for_default() Failed(%d)", ret);
 
        //insert contact table
-       int input_ver = cts_get_next_ver();
+       ver = cts_get_next_ver();
+
+       ret = cts_insert_person(contact->base->id, 0);
+       retvm_if(CTS_SUCCESS != ret, ret, "cts_insert_person() Failed(%d)", ret);
+       contact->base->person_id = contact->base->id;
 
        snprintf(query, sizeof(query),
-                       "INSERT INTO %s(contact_id, addrbook_id, created_ver, changed_ver, "
+                       "INSERT INTO %s(contact_id, person_id, addrbook_id, created_ver, changed_ver, "
                        "changed_time, default_num, default_email, uid, ringtone, note, image0, image1) "
-                       "VALUES(%d, %d, %d, %d, %d, %d, %d, ?, ?, ?, ?, ?)",
-                       CTS_TABLE_CONTACTS, contact->base->id, addressbook_id, input_ver,
-                       input_ver, (int)time(NULL), contact->default_num, contact->default_email);
+                       "VALUES(%d, %d, %d, %d, %d, %d, %d, %d, ?, ?, ?, ?, ?)",
+                       CTS_TABLE_CONTACTS, contact->base->id, contact->base->person_id, addressbook_id, ver,
+                       ver, (int)time(NULL), contact->default_num, contact->default_email);
 
        cts_stmt stmt = cts_query_prepare(query);
        retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
@@ -935,25 +913,25 @@ static inline int cts_insert_contact(int addressbook_id, contact_t *contact)
 
        normal_img[0] = '\0';
        if (contact->base->img_path) {
-               ret = cts_add_image_file(CTS_IMG_NORMAL, contact->base->id, contact->base->img_path,
-                       normal_img, sizeof(normal_img));
+               ret = cts_contact_add_image_file(CTS_IMG_NORMAL, contact->base->id, contact->base->img_path,
+                               normal_img, sizeof(normal_img));
                if (CTS_SUCCESS != ret) {
-                       ERR("cts_add_image_file(NORMAL) Failed(%d)", ret);
+                       ERR("cts_contact_add_image_file(NORMAL) Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
                }
                cts_stmt_bind_text(stmt, 4, normal_img);
        }
        else if (contact->base->vcard_img_path) {
-               ret = cts_add_image_file(CTS_IMG_NORMAL, contact->base->id, contact->base->vcard_img_path,
-                       normal_img, sizeof(normal_img));
+               ret = cts_contact_add_image_file(CTS_IMG_NORMAL, contact->base->id, contact->base->vcard_img_path,
+                               normal_img, sizeof(normal_img));
                if (CTS_SUCCESS == ret)
                        cts_stmt_bind_text(stmt, 4, normal_img);
        }
 
        full_img[0] = '\0';
-       ret = cts_add_image_file(CTS_IMG_FULL, contact->base->id, contact->base->full_img_path,
-               full_img, sizeof(full_img));
+       ret = cts_contact_add_image_file(CTS_IMG_FULL, contact->base->id, contact->base->full_img_path,
+                       full_img, sizeof(full_img));
        if (CTS_SUCCESS == ret)
                cts_stmt_bind_text(stmt, 5, full_img);
 
@@ -965,7 +943,10 @@ static inline int cts_insert_contact(int addressbook_id, contact_t *contact)
        }
        cts_stmt_finalize(stmt);
 
-       return CTS_SUCCESS;
+       if (rel_changed)
+               return rel_changed;
+       else
+               return CTS_SUCCESS;
 }
 
 
@@ -982,6 +963,9 @@ API int contacts_svc_insert_contact(int addressbook_id, CTSstruct* contact)
 
        CTS_START_TIME_CHECK;
 
+       retvm_if(record->is_restricted && FALSE == cts_restriction_get_permit(),
+                       CTS_ERR_ENV_INVALID, "This process can not insert restriction contacts");
+
        ret = contacts_svc_begin_trans();
        retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
 
@@ -1009,7 +993,7 @@ API int contacts_svc_insert_contact(int addressbook_id, CTSstruct* contact)
        record->base->id = ret;
        record->base->addrbook_id = addressbook_id;
        ret = cts_insert_contact(addressbook_id, record);
-       if (CTS_SUCCESS != ret)
+       if (ret < CTS_SUCCESS)
        {
                ERR("cts_insert_contact() Failed(%d)", ret);
                contacts_svc_end_trans(false);
@@ -1017,6 +1001,8 @@ API int contacts_svc_insert_contact(int addressbook_id, CTSstruct* contact)
        }
 
        cts_set_contact_noti();
+       if (0 < ret)
+               cts_set_group_rel_noti();
        ret = contacts_svc_end_trans(true);
        retvm_if(ret < CTS_SUCCESS, ret, "contacts_svc_end_trans() Failed(%d)", ret);
 
@@ -1042,15 +1028,37 @@ API int contacts_svc_delete_contact(int index)
        ret = contacts_svc_begin_trans();
        retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
 
-       ret = cts_delete_image_file(CTS_IMG_NORMAL, index);
+       ret = cts_check_linked_contact(index);
+       if (ret < CTS_SUCCESS) {
+               ERR("cts_check_linked_contact() Failed(%d)", ret);
+               contacts_svc_end_trans(false);
+               return ret;
+       }
+       if (CTS_LINKED_PRIMARY == ret) {
+               ret = cts_person_change_primary_contact(index);
+               if (ret < CTS_SUCCESS) {
+                       ERR("cts_person_change_primary_contact() Failed(%d)", ret);
+                       contacts_svc_end_trans(false);
+                       return ret;
+               }
+       } else if (CTS_LINKED_NONE == ret) {
+               ret = cts_delete_person(index);
+               if (CTS_SUCCESS != ret) {
+                       ERR("cts_delete_person() Failed(%d)", ret);
+                       contacts_svc_end_trans(false);
+                       return ret;
+               }
+       }
+
+       ret = cts_contact_delete_image_file(CTS_IMG_NORMAL, index);
        if (CTS_SUCCESS != ret && CTS_ERR_DB_RECORD_NOT_FOUND != ret) {
-               ERR("cts_delete_image_file(NORMAL) Failed(%d)", ret);
+               ERR("cts_contact_delete_image_file(NORMAL) Failed(%d)", ret);
                contacts_svc_end_trans(false);
                return ret;
        }
-       ret = cts_delete_image_file(CTS_IMG_FULL, index);
+       ret = cts_contact_delete_image_file(CTS_IMG_FULL, index);
        warn_if(CTS_SUCCESS != ret && CTS_ERR_DB_RECORD_NOT_FOUND != ret,
-                       "cts_delete_image_file(FULL) Failed(%d)", ret);
+                       "cts_contact_delete_image_file(FULL) Failed(%d)", ret);
 
        snprintf(query, sizeof(query), "DELETE FROM %s WHERE contact_id = %d",
                        CTS_TABLE_CONTACTS, index);
@@ -1129,17 +1137,14 @@ static inline int cts_update_contact_data_number(
                                char clean_num[CTS_NUMBER_MAX_LEN];
 
                                cts_stmt_bind_int(stmt, cnt++, number_data->type);
+                               cts_stmt_bind_text(stmt, cnt++, number_data->number);
 
                                ret = cts_clean_number(number_data->number, clean_num, sizeof(clean_num));
-                               if (ret <= 0) {
-                                       ERR("Number(%s) is invalid", number_data->number);
-                                       number_repeat = g_slist_next(number_repeat);
-                                       continue;
+                               if (0 < ret) {
+                                       normal_num = cts_normalize_number(clean_num);
+                                       cts_stmt_bind_text(stmt, cnt++, normal_num);
                                }
-                               cts_stmt_bind_text(stmt, cnt++, clean_num);
 
-                               normal_num = cts_normalize_number(clean_num);
-                               cts_stmt_bind_text(stmt, cnt++, normal_num);
                                cts_stmt_bind_int(stmt, CTS_UPDATE_ID_LOC, number_data->id);
 
                                ret = cts_stmt_step(stmt);
@@ -1267,6 +1272,7 @@ static inline int cts_update_contact_grouprel(cts_ct_base *base_info,
        int ret;
        GSList *group_repeat = group_list;
        cts_group *group_data;
+       int rel_changed = 0;
 
        retv_if(NULL == group_list, CTS_ERR_ARG_NULL);
 
@@ -1306,11 +1312,16 @@ static inline int cts_update_contact_grouprel(cts_ct_base *base_info,
                                ret = cts_group_set_relation(group_data->id, base_info->id,
                                                base_info->addrbook_id);
                                retvm_if(ret < CTS_SUCCESS, ret, "cts_group_set_relation() Failed(%d)", ret);
+                               if (0 < ret)
+                                       rel_changed += ret;
                        }
                }
        }while(group_repeat);
 
-       return CTS_SUCCESS;
+       if (rel_changed)
+               return rel_changed;
+       else
+               return CTS_SUCCESS;
 }
 
 static inline int cts_update_contact_data_event(
@@ -1716,11 +1727,11 @@ static inline int cts_update_contact_data_name(cts_stmt stmt,
        name->last = tmp_last;
 
        ret = cts_make_name_lookup(CTS_ORDER_NAME_FIRSTLAST, &normalize_name,
-                                                                               lookup, sizeof(lookup));
+                       lookup, sizeof(lookup));
        retvm_if(CTS_SUCCESS != ret, ret, "cts_make_name_lookup() Failed(%d)", ret);
 
        ret = cts_make_name_lookup(CTS_ORDER_NAME_LASTFIRST, &normalize_name,
-                                                                               reverse_lookup, sizeof(reverse_lookup));
+                       reverse_lookup, sizeof(reverse_lookup));
        retvm_if(CTS_SUCCESS != ret, ret, "cts_make_name_lookup() Failed(%d)", ret);
 
        CTS_DBG("lookup=%s(%d), reverse_lookup=%s(%d)",
@@ -1796,9 +1807,7 @@ static inline int cts_update_contact_data(contact_t *contact)
        if (contact->events)
        {
                ret = cts_update_contact_data_event(stmt, contact->base->id, contact->events);
-
-               if (CTS_SUCCESS != ret)
-               {
+               if (CTS_SUCCESS != ret) {
                        ERR("cts_update_contact_data_event() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
@@ -1810,9 +1819,7 @@ static inline int cts_update_contact_data(contact_t *contact)
        {
                ret = cts_update_contact_data_messenger(stmt, contact->base->id,
                                contact->messengers);
-
-               if (CTS_SUCCESS != ret)
-               {
+               if (CTS_SUCCESS != ret) {
                        ERR("cts_update_contact_data_messenger() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
@@ -1824,9 +1831,7 @@ static inline int cts_update_contact_data(contact_t *contact)
        {
                ret = cts_update_contact_data_postal(stmt, contact->base->id,
                                contact->postal_addrs);
-
-               if (CTS_SUCCESS != ret)
-               {
+               if (CTS_SUCCESS != ret) {
                        ERR("cts_update_contact_data_postal() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
@@ -1837,9 +1842,7 @@ static inline int cts_update_contact_data(contact_t *contact)
        if (contact->web_addrs)
        {
                ret = cts_update_contact_data_web(stmt, contact->base->id, contact->web_addrs);
-
-               if (CTS_SUCCESS != ret)
-               {
+               if (CTS_SUCCESS != ret) {
                        ERR("cts_update_contact_data_web() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
@@ -1850,9 +1853,7 @@ static inline int cts_update_contact_data(contact_t *contact)
        if (contact->nicknames)
        {
                ret = cts_update_contact_data_nick(stmt, contact->base->id, contact->nicknames);
-
-               if (CTS_SUCCESS != ret)
-               {
+               if (CTS_SUCCESS != ret) {
                        ERR("cts_update_contact_data_nick() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
@@ -1863,9 +1864,7 @@ static inline int cts_update_contact_data(contact_t *contact)
        if (contact->numbers)
        {
                ret = cts_update_contact_data_number(stmt, contact->base->id, contact->numbers);
-
-               if (ret < CTS_SUCCESS)
-               {
+               if (ret < CTS_SUCCESS) {
                        ERR("cts_update_contact_data_number() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
@@ -1877,9 +1876,7 @@ static inline int cts_update_contact_data(contact_t *contact)
        if (contact->emails)
        {
                ret = cts_update_contact_data_email(stmt, contact->base->id, contact->emails);
-
-               if (ret < CTS_SUCCESS)
-               {
+               if (ret < CTS_SUCCESS) {
                        ERR("cts_update_contact_data_email() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
@@ -1892,9 +1889,7 @@ static inline int cts_update_contact_data(contact_t *contact)
        {
                ret = cts_update_contact_data_extend(stmt, contact->base->id,
                                contact->extended_values);
-
-               if (CTS_SUCCESS != ret)
-               {
+               if (CTS_SUCCESS != ret) {
                        ERR("cts_update_contact_data_extend() Failed(%d)", ret);
                        cts_stmt_finalize(stmt);
                        return ret;
@@ -1939,6 +1934,7 @@ static inline int cts_update_contact(contact_t *contact)
        char query[CTS_SQL_MAX_LEN] = {0};
        char normal_img[CTS_SQL_MIN_LEN];
        char full_img[CTS_SQL_MIN_LEN];
+       int rel_changed = 0;
 
        snprintf(query, sizeof(query),
                        "SELECT count(contact_id) FROM %s WHERE contact_id = %d",
@@ -1951,7 +1947,6 @@ static inline int cts_update_contact(contact_t *contact)
        retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
 
        cts_update_contact_handle_no_name(contact);
-       cts_contact_remove_dup_data(contact);
 
        //update data
        ret = cts_update_contact_data(contact);
@@ -1965,12 +1960,12 @@ static inline int cts_update_contact(contact_t *contact)
        //update group relation Info
        if (contact->grouprelations)
        {
-               ret = cts_update_contact_grouprel(contact->base, contact->grouprelations);
-               if (ret < CTS_SUCCESS)
+               rel_changed = cts_update_contact_grouprel(contact->base, contact->grouprelations);
+               if (rel_changed < CTS_SUCCESS)
                {
-                       ERR("cts_update_contact_grouprel() Failed(%d)", ret);
+                       ERR("cts_update_contact_grouprel() Failed(%d)", rel_changed);
                        contacts_svc_end_trans(false);
-                       return ret;
+                       return rel_changed;
                }
        }
 
@@ -2036,10 +2031,10 @@ static inline int cts_update_contact(contact_t *contact)
                        (NULL == contact->base->img_path && contact->base->vcard_img_path)) {
                normal_img[0] = '\0';
                if (contact->base->img_path) {
-                       ret = cts_update_image_file(CTS_IMG_NORMAL, contact->base->id, contact->base->img_path,
-                               normal_img, sizeof(normal_img));
+                       ret = cts_contact_update_image_file(CTS_IMG_NORMAL, contact->base->id, contact->base->img_path,
+                                       normal_img, sizeof(normal_img));
                        if (CTS_SUCCESS != ret) {
-                               ERR("cts_update_image_file() Failed(%d)", ret);
+                               ERR("cts_contact_update_image_file() Failed(%d)", ret);
                                cts_stmt_finalize(stmt);
                                contacts_svc_end_trans(false);
                                return ret;
@@ -2049,15 +2044,15 @@ static inline int cts_update_contact(contact_t *contact)
                        i++;
                } else {
                        if (contact->base->vcard_img_path) {
-                               ret = cts_update_image_file(CTS_IMG_NORMAL, contact->base->id, contact->base->vcard_img_path,
-                                       normal_img, sizeof(normal_img));
+                               ret = cts_contact_update_image_file(CTS_IMG_NORMAL, contact->base->id, contact->base->vcard_img_path,
+                                               normal_img, sizeof(normal_img));
                                if (CTS_SUCCESS == ret && *normal_img)
                                        cts_stmt_bind_text(stmt, i, normal_img);
                                i++;
                        } else {
-                               ret = cts_delete_image_file(CTS_IMG_NORMAL, contact->base->id);
+                               ret = cts_contact_delete_image_file(CTS_IMG_NORMAL, contact->base->id);
                                if (CTS_SUCCESS != ret) {
-                                       ERR("cts_delete_image_file() Failed(%d)", ret);
+                                       ERR("cts_contact_delete_image_file() Failed(%d)", ret);
                                        cts_stmt_finalize(stmt);
                                        contacts_svc_end_trans(false);
                                        return ret;
@@ -2068,8 +2063,8 @@ static inline int cts_update_contact(contact_t *contact)
 
        if (contact->base->full_img_changed) {
                full_img[0] = '\0';
-               ret = cts_update_image_file(CTS_IMG_FULL, contact->base->id, contact->base->full_img_path,
-                       full_img, sizeof(full_img));
+               ret = cts_contact_update_image_file(CTS_IMG_FULL, contact->base->id, contact->base->full_img_path,
+                               full_img, sizeof(full_img));
                if (CTS_SUCCESS == ret && *full_img)
                        cts_stmt_bind_text(stmt, i, full_img);
                i++;
@@ -2086,6 +2081,8 @@ static inline int cts_update_contact(contact_t *contact)
        cts_stmt_finalize(stmt);
 
        cts_set_contact_noti();
+       if (0 < rel_changed)
+               cts_set_group_rel_noti();
 
        ret = contacts_svc_end_trans(true);
        if (ret < CTS_SUCCESS)
@@ -2103,6 +2100,9 @@ API int contacts_svc_update_contact(CTSstruct* contact)
        retvm_if(CTS_STRUCT_CONTACT != contact->s_type, CTS_ERR_ARG_INVALID,
                        "The contact(%d) must be type of CTS_STRUCT_CONTACT.", contact->s_type);
 
+       retvm_if(record->is_restricted && FALSE == cts_restriction_get_permit(),
+                       CTS_ERR_ENV_INVALID, "This process can not update restriction contacts");
+
        CTS_START_TIME_CHECK;
 
        ret = cts_update_contact(record);
@@ -2176,9 +2176,6 @@ static inline int cts_put_number_val(int contact_id,
        retvm_if(CTS_VALUE_NUMBER != number->v_type, CTS_ERR_ARG_INVALID,
                        "value has unknown type");
 
-       ret = cts_clean_number(number->number, clean_num, sizeof(clean_num));
-       retvm_if(ret <= 0, CTS_ERR_ARG_INVALID, "Number(%s) is invalid", number->number);
-
        snprintf(query, sizeof(query),
                        "INSERT INTO %s(contact_id, datatype, data1, data2, data3) VALUES(%d, %d, %d, ?, ?)",
                        CTS_TABLE_DATA, contact_id, CTS_DATA_NUMBER, number->type);
@@ -2186,10 +2183,12 @@ static inline int cts_put_number_val(int contact_id,
        stmt = cts_query_prepare(query);
        retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
 
-       cts_stmt_bind_text(stmt, 1, clean_num);
-
-       normal_num = cts_normalize_number(clean_num);
-       cts_stmt_bind_text(stmt, 2, normal_num);
+       cts_stmt_bind_text(stmt, 1, number->number);
+       ret = cts_clean_number(number->number, clean_num, sizeof(clean_num));
+       if(0 < ret) {
+               normal_num = cts_normalize_number(clean_num);
+               cts_stmt_bind_text(stmt, 2, normal_num);
+       }
 
        ret = cts_stmt_step(stmt);
        if (CTS_SUCCESS != ret) {
@@ -2333,844 +2332,115 @@ API int contacts_svc_put_contact_value(cts_put_contact_val_op op_code,
                return CTS_SUCCESS;
 }
 
-#define CTS_MAIN_CTS_GET_RINGTON (1<<1)
-#define CTS_MAIN_CTS_GET_NOTE (1<<2)
-#define CTS_MAIN_CTS_GET_DEFAULT_NUM (1<<3)
-#define CTS_MAIN_CTS_GET_DEFAULT_EMAIL (1<<4)
-#define CTS_MAIN_CTS_GET_FAVOR (1<<5)
-#define CTS_MAIN_CTS_GET_IMG (1<<6)
-#define CTS_MAIN_CTS_GET_ALL (1<<1|1<<2|1<<3|1<<4|1<<5|1<<6)
-
-static int cts_get_main_contacts_info(int op_code, int index, contact_t *contact)
+static inline int cts_insert_myprofile_base(cts_stmt stmt, cts_ct_base *base)
 {
-       int ret, len;
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MAX_LEN] = {0};
-       char *temp;
-
-       len = snprintf(query, sizeof(query), "SELECT ");
-
-       len += snprintf(query+len, sizeof(query)-len,
-                       "contact_id, addrbook_id, changed_time");
+       int ret;
 
-       if (op_code & CTS_MAIN_CTS_GET_RINGTON)
-               len += snprintf(query+len, sizeof(query)-len, ", ringtone");
-       if (op_code & CTS_MAIN_CTS_GET_NOTE)
-               len += snprintf(query+len, sizeof(query)-len, ", note");
-       if (op_code & CTS_MAIN_CTS_GET_DEFAULT_NUM)
-               len += snprintf(query+len, sizeof(query)-len, ", default_num");
-       if (op_code & CTS_MAIN_CTS_GET_DEFAULT_EMAIL)
-               len += snprintf(query+len, sizeof(query)-len, ", default_email");
-       if (op_code & CTS_MAIN_CTS_GET_FAVOR)
-               len += snprintf(query+len, sizeof(query)-len, ", is_favorite");
-       if (op_code & CTS_MAIN_CTS_GET_IMG) {
-               len += snprintf(query+len, sizeof(query)-len, ", image0");
-               len += snprintf(query+len, sizeof(query)-len, ", image1");
-       }
+       retv_if(NULL == base, CTS_ERR_ARG_NULL);
 
-       snprintf(query+len, sizeof(query)-len,
-                       " FROM %s WHERE contact_id = %d", CTS_TABLE_CONTACTS, index);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+       cts_stmt_bind_int(stmt, 1, 0);
+       if (base->note)
+               cts_stmt_bind_text(stmt, 3, base->note);
 
        ret = cts_stmt_step(stmt);
-       if (CTS_TRUE != ret)
-       {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               return CTS_ERR_DB_RECORD_NOT_FOUND;
-       }
-       int count=0;
-
-       contact->base = (cts_ct_base *)contacts_svc_value_new(CTS_VALUE_CONTACT_BASE_INFO);
-       if (NULL == contact->base) {
-               cts_stmt_finalize(stmt);
-               ERR("contacts_svc_value_new(CTS_VALUE_CONTACT_BASE_INFO) Failed");
-               return CTS_ERR_OUT_OF_MEMORY;
-       }
-
-       contact->base->id = cts_stmt_get_int(stmt, count++);
-       contact->base->addrbook_id = cts_stmt_get_int(stmt, count++);
-       contact->base->changed_time = cts_stmt_get_int(stmt, count++);
-
-       if (op_code & CTS_MAIN_CTS_GET_RINGTON)
-       {
-               contact->base->embedded = true;
-               temp = cts_stmt_get_text(stmt, count++);
-               if (temp && CTS_SUCCESS == cts_exist_file(temp))
-                       contact->base->ringtone_path = strdup(temp);
-               else
-                       contact->base->ringtone_path = NULL;
-       }
-       if (op_code & CTS_MAIN_CTS_GET_NOTE)
-       {
-               contact->base->embedded = true;
-               temp = cts_stmt_get_text(stmt, count++);
-               contact->base->note = SAFE_STRDUP(temp);
-       }
-       if (op_code & CTS_MAIN_CTS_GET_DEFAULT_NUM)
-               contact->default_num = cts_stmt_get_int(stmt, count++);
-       if (op_code & CTS_MAIN_CTS_GET_DEFAULT_EMAIL)
-               contact->default_email = cts_stmt_get_int(stmt, count++);
-       if (op_code & CTS_MAIN_CTS_GET_FAVOR)
-               contact->base->is_favorite = cts_stmt_get_int(stmt, count++);
-
-       if (op_code & CTS_MAIN_CTS_GET_IMG) {
-               char tmp_path[CTS_IMG_PATH_SIZE_MAX];
-               contact->base->embedded = true;
-               temp = cts_stmt_get_text(stmt, count++);
-               if (temp) {
-                       snprintf(tmp_path, sizeof(tmp_path), "%s/%s", CTS_IMAGE_LOCATION, temp);
-                       contact->base->img_path = strdup(tmp_path);
-               }
-               temp = cts_stmt_get_text(stmt, count++);
-               if (temp) {
-                       snprintf(tmp_path, sizeof(tmp_path), "%s/%s", CTS_IMAGE_LOCATION, temp);
-                       contact->base->full_img_path = strdup(tmp_path);
-               }
-       }
-
-       cts_stmt_finalize(stmt);
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_get_data_info_number(cts_stmt stmt, contact_t *contact)
-{
-       cts_number *result;
-
-       result = (cts_number *)contacts_svc_value_new(CTS_VALUE_NUMBER);
-       if (result) {
-               int cnt = 1;
-               result->embedded = true;
-               cnt = cts_stmt_get_number(stmt, result, cnt);
-
-               if (result->id == contact->default_num)
-                       result->is_default = true;
-
-               result->is_favorite = cts_stmt_get_int(stmt, cnt);
-               contact->numbers = g_slist_append(contact->numbers, result);
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_get_data_info_email(cts_stmt stmt, contact_t *contact)
-{
-       cts_email *result;
-
-       result = (cts_email *)contacts_svc_value_new(CTS_VALUE_EMAIL);
-       if (result) {
-               result->embedded = true;
-               cts_stmt_get_email(stmt, result, 1);
-
-               if (result->id == contact->default_email)
-                       result->is_default = true;
-
-               contact->emails = g_slist_append(contact->emails, result);
-       }
-       return CTS_SUCCESS;
-}
-
-static inline cts_name* cts_get_data_info_name(cts_stmt stmt)
-{
-       cts_name *result;
-
-       result = (cts_name *)contacts_svc_value_new(CTS_VALUE_NAME);
-       if (result) {
-               result->embedded = true;
-               cts_stmt_get_name(stmt, result, 1);
-       }
-       return result;
-}
-
-static inline int cts_get_data_info_event(cts_stmt stmt, contact_t *contact)
-{
-       int cnt=1;
-       cts_event *result;
-
-       result = (cts_event *)contacts_svc_value_new(CTS_VALUE_EVENT);
-       if (result) {
-               result->embedded = true;
-               result->id = cts_stmt_get_int(stmt, cnt++);
-               result->type = cts_stmt_get_int(stmt, cnt++);
-               result->date = cts_stmt_get_int(stmt, cnt++);
-
-               contact->events = g_slist_append(contact->events, result);
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_get_data_info_messenger(cts_stmt stmt, contact_t *contact)
-{
-       int cnt=1;
-       cts_messenger *result;
-
-       result = (cts_messenger *)contacts_svc_value_new(CTS_VALUE_MESSENGER);
-       if (result) {
-               char *temp;
-               result->embedded = true;
-               result->id = cts_stmt_get_int(stmt, cnt++);
-               result->type = cts_stmt_get_int(stmt, cnt++);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->im_id = SAFE_STRDUP(temp);
-               if (0 == result->type) {
-                       temp = cts_stmt_get_text(stmt, cnt++);
-                       result->svc_name = SAFE_STRDUP(temp);
-                       temp = cts_stmt_get_text(stmt, cnt++);
-                       result->svc_op = SAFE_STRDUP(temp);
-               }
-               contact->messengers = g_slist_append(contact->messengers, result);
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_get_data_info_postal(cts_stmt stmt, contact_t *contact)
-{
-       int cnt=1;
-       cts_postal *result;
-
-       result = (cts_postal *)contacts_svc_value_new(CTS_VALUE_POSTAL);
-       if (result) {
-               char *temp;
-               result->embedded = true;
-               result->id = cts_stmt_get_int(stmt, cnt++);
-               result->type = cts_stmt_get_int(stmt, cnt++);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->pobox= SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->postalcode = SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->region= SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->locality = SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->street = SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->extended = SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->country = SAFE_STRDUP(temp);
-
-               contact->postal_addrs = g_slist_append(contact->postal_addrs, result);
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_get_data_info_web(cts_stmt stmt, contact_t *contact)
-{
-       int cnt=1;
-       cts_web *result;
-
-       result = (cts_web *)contacts_svc_value_new(CTS_VALUE_WEB);
-       if (result) {
-               char *temp;
-               result->embedded = true;
-               result->id = cts_stmt_get_int(stmt, cnt++);
-               result->type = cts_stmt_get_int(stmt, cnt++);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->url = SAFE_STRDUP(temp);
-
-               contact->web_addrs = g_slist_append(contact->web_addrs, result);
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_get_data_info_nick(cts_stmt stmt, contact_t *contact)
-{
-       int cnt=1;
-       cts_nickname *result;
-
-       result = (cts_nickname *)contacts_svc_value_new(CTS_VALUE_NICKNAME);
-       if (result) {
-               char *temp;
-               result->embedded = true;
-               result->id = cts_stmt_get_int(stmt, cnt++);
-               temp = cts_stmt_get_text(stmt, cnt+1);
-               result->nick = SAFE_STRDUP(temp);
-
-               contact->nicknames = g_slist_append(contact->nicknames, result);
-       }
-       return CTS_SUCCESS;
-}
-
-static inline cts_company* cts_get_data_info_company(cts_stmt stmt)
-{
-       int cnt=1;
-       cts_company *result;
-
-       result = (cts_company *)contacts_svc_value_new(CTS_VALUE_COMPANY);
-       retvm_if(NULL == result, NULL, "contacts_svc_value_new() Failed");
-
-       char *temp;
-       result->embedded = true;
-       result->id = cts_stmt_get_int(stmt, cnt++);
-       cnt++;
-       temp = cts_stmt_get_text(stmt, cnt++);
-       result->name = SAFE_STRDUP(temp);
-       temp = cts_stmt_get_text(stmt, cnt++);
-       result->department = SAFE_STRDUP(temp);
-       temp = cts_stmt_get_text(stmt, cnt++);
-       result->jot_title = SAFE_STRDUP(temp);
-       temp = cts_stmt_get_text(stmt, cnt++);
-       result->role = SAFE_STRDUP(temp);
-       temp = cts_stmt_get_text(stmt, cnt++);
-       result->assistant_name = SAFE_STRDUP(temp);
-
-       if (result->name || result->department || result->jot_title || result->role ||  result->assistant_name)
-               return result;
-       else {
-               contacts_svc_value_free((CTSvalue *)result);
-               return NULL;
-       }
-}
-
-static cts_extend* cts_make_extend_data(cts_stmt stmt, int type, int cnt)
-{
-       cts_extend *result;
-       result = (cts_extend *)contacts_svc_value_new(CTS_VALUE_EXTEND);
-       if (result)
-       {
-               char *temp;
-               result->type = type;
-               result->id = cts_stmt_get_int(stmt, cnt++);
-               result->data1 = cts_stmt_get_int(stmt, cnt++);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->data2= SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->data3 = SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->data4= SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->data5 = SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->data6 = SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->data7 = SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->data8 = SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->data9 = SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->data10 = SAFE_STRDUP(temp);
-       }
-       return result;
-}
-
-static inline int cts_get_data_info_extend(cts_stmt stmt, int type,
-               contact_t *contact)
-{
-       cts_extend *result;
+       retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
 
-       result = cts_make_extend_data(stmt, type, 1);
-       if (result) {
-               result->embedded = true;
-               contact->extended_values = g_slist_append(contact->extended_values, result);
-       }
-       else
-               return CTS_ERR_OUT_OF_MEMORY;
+       cts_stmt_reset(stmt);
 
        return CTS_SUCCESS;
 }
 
-
-int cts_get_data_info(int op_code, int field, int index, contact_t *contact)
+static inline int cts_set_myprofile(contact_t *contact)
 {
-       int ret, datatype, len;
+       int ret;
        cts_stmt stmt = NULL;
-       char query[CTS_SQL_MAX_LEN] = {0};
+       char query[CTS_SQL_MAX_LEN];
 
-       switch (op_code)
-       {
-       case CTS_GET_DATA_BY_CONTACT_ID:
-               len = snprintf(query, sizeof(query), "SELECT datatype, id, data1, data2,"
-                               "data3, data4, data5, data6, data7, data8, data9, data10 "
-                               "FROM %s WHERE contact_id = %d", CTS_TABLE_DATA, index);
-               break;
-       case CTS_GET_DATA_BY_ID:
-       default:
-               ERR("Invalid parameter : The op_code(%d) is not supported", op_code);
-               return CTS_ERR_ARG_INVALID;
-       }
-
-       if (CTS_DATA_FIELD_ALL != field && CTS_DATA_FIELD_EXTEND_ALL != field)
-       {
-               bool first= true;
-               len += snprintf(query+len, sizeof(query)-len, " AND datatype IN (");
-
-               if (field & CTS_DATA_FIELD_NAME) {
-                       first=false;
-                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_NAME);
-               }
-               if (field & CTS_DATA_FIELD_EVENT) {
-                       if (first)
-                               first=false;
-                       else
-                               len += snprintf(query+len, sizeof(query)-len, ", ");
-                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_EVENT);
-               }
-               if (field & CTS_DATA_FIELD_MESSENGER) {
-                       if (first)
-                               first=false;
-                       else
-                               len += snprintf(query+len, sizeof(query)-len, ", ");
-                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_MESSENGER);
-               }
-               if (field & CTS_DATA_FIELD_POSTAL) {
-                       if (first)
-                               first=false;
-                       else
-                               len += snprintf(query+len, sizeof(query)-len, ", ");
-                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_POSTAL);
-               }
-               if (field & CTS_DATA_FIELD_WEB) {
-                       if (first)
-                               first=false;
-                       else
-                               len += snprintf(query+len, sizeof(query)-len, ", ");
-                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_WEB);
-               }
-               if (field & CTS_DATA_FIELD_NICKNAME) {
-                       if (first)
-                               first=false;
-                       else
-                               len += snprintf(query+len, sizeof(query)-len, ", ");
-                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_NICKNAME);
-               }
-               if (field & CTS_DATA_FIELD_COMPANY) {
-                       if (first)
-                               first=false;
-                       else
-                               len += snprintf(query+len, sizeof(query)-len, ", ");
-                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_COMPANY);
-               }
-               if (field & CTS_DATA_FIELD_NUMBER) {
-                       if (first)
-                               first=false;
-                       else
-                               len += snprintf(query+len, sizeof(query)-len, ", ");
-                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_NUMBER);
-               }
-               if (field & CTS_DATA_FIELD_EMAIL) {
-                       if (first)
-                               first=false;
-                       else
-                               len += snprintf(query+len, sizeof(query)-len, ", ");
-                       len += snprintf(query+len, sizeof(query)-len, "%d", CTS_DATA_EMAIL);
-               }
-
-               len += snprintf(query+len, sizeof(query)-len, ")");
-       }
+       snprintf(query, sizeof(query), "DELETE FROM %s", CTS_TABLE_MY_PROFILES);
+       ret = cts_query_exec(query);
+       retvm_if(CTS_SUCCESS != ret, ret, "cts_query_exec() Failed(%d)", ret);
 
-       if (CTS_DATA_FIELD_ALL != field && field & CTS_DATA_FIELD_EXTEND_ALL) {
-               len += snprintf(query+len, sizeof(query)-len, " AND datatype>=%d",
-                               CTS_DATA_EXTEND_START);
-       }
+       snprintf(query, sizeof(query), "INSERT INTO %s(datatype, "
+                       "data1, data2, data3, data4, data5, data6, data7, data8, data9, data10) "
+                       "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CTS_TABLE_MY_PROFILES);
 
        stmt = cts_query_prepare(query);
        retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
 
-       ret = cts_stmt_step(stmt);
-       if (CTS_TRUE != ret)
-       {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               return CTS_ERR_DB_RECORD_NOT_FOUND;
+       if (contact->base) {
+               ret = cts_insert_myprofile_base(stmt, contact->base);
+               retvm_if(CTS_SUCCESS != ret, ret, "cts_insert_myprofile_base() Failed(%d)", ret);
        }
 
-       do {
-               datatype = cts_stmt_get_int(stmt, 0);
-
-               switch (datatype)
-               {
-               case CTS_DATA_NAME:
-                       if (contact->name)
-                               ERR("name already Exist");
-                       else
-                               contact->name = cts_get_data_info_name(stmt);
-                       break;
-               case CTS_DATA_EVENT:
-                       cts_get_data_info_event(stmt, contact);
-                       break;
-               case CTS_DATA_MESSENGER:
-                       cts_get_data_info_messenger(stmt, contact);
-                       break;
-               case CTS_DATA_POSTAL:
-                       cts_get_data_info_postal(stmt, contact);
-                       break;
-               case CTS_DATA_WEB:
-                       cts_get_data_info_web(stmt, contact);
-                       break;
-               case CTS_DATA_NICKNAME:
-                       cts_get_data_info_nick(stmt, contact);
-                       break;
-               case CTS_DATA_NUMBER:
-                       cts_get_data_info_number(stmt, contact);
-                       break;
-               case CTS_DATA_EMAIL:
-                       cts_get_data_info_email(stmt, contact);
-                       break;
-               case CTS_DATA_COMPANY:
-                       if (contact->company)
-                               ERR("company already Exist");
-                       else
-                               contact->company = cts_get_data_info_company(stmt);
-                       break;
-               default:
-                       if (CTS_DATA_EXTEND_START <= datatype) {
-                               cts_get_data_info_extend(stmt, datatype, contact);
-                               break;
-                       }
-                       ERR("Unknown data type(%d)", datatype);
-                       continue;
-               }
-       }while(CTS_TRUE == cts_stmt_step(stmt));
-
-       cts_stmt_finalize(stmt);
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_get_groups_info(int index, contact_t *contact)
-{
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MAX_LEN] = {0};
-       GSList *result_list=NULL;
-
-       snprintf(query, sizeof(query), "SELECT group_id, addrbook_id,"
-                       " group_name"
-                       " FROM %s WHERE group_id IN (SELECT group_id"
-                       " FROM %s WHERE contact_id = %d)"
-                       " ORDER BY group_name COLLATE NOCASE",
-                       CTS_TABLE_GROUPS, CTS_TABLE_GROUPING_INFO, index);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       while (CTS_TRUE == cts_stmt_step(stmt))
-       {
-               cts_group *group_info;
-               group_info = (cts_group *)contacts_svc_value_new(CTS_VALUE_GROUP_RELATION);
-
-               if (group_info)
-               {
-                       group_info->id = cts_stmt_get_int(stmt, 0);
-                       group_info->addrbook_id = cts_stmt_get_int(stmt, 1);
-                       group_info->embedded = true;
-                       group_info->name = SAFE_STRDUP(cts_stmt_get_text(stmt, 2));
-
-                       result_list = g_slist_append(result_list, group_info);
-               }
+       if (contact->name) {
+               ret = cts_insert_contact_data_name(stmt, contact->name);
+               retvm_if(CTS_SUCCESS != ret, ret, "cts_insert_contact_data_name() Failed(%d)", ret);
        }
 
-       cts_stmt_finalize(stmt);
-       contact->grouprelations = result_list;
-
-       return CTS_SUCCESS;
-
-}
-
-static inline int cts_get_number_value(int op_code, int id, CTSvalue **value)
-{
-       int ret;
-       cts_stmt stmt;
-       cts_number *number;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       if (CTS_GET_DEFAULT_NUMBER_VALUE == op_code) {
-               snprintf(query, sizeof(query),
-                               "SELECT B.id, B.data1, B.data2 FROM %s A, %s B "
-                               "WHERE A.contact_id = %d AND B.id=A.default_num AND B.datatype = %d",
-                               CTS_TABLE_CONTACTS, CTS_TABLE_DATA, id, CTS_DATA_NUMBER);
-       }
-       else if (CTS_GET_NUMBER_VALUE == op_code) {
-               snprintf(query, sizeof(query),
-                               "SELECT id, data1, data2, contact_id FROM %s "
-                               "WHERE id = %d AND datatype = %d",
-                               CTS_TABLE_DATA, id, CTS_DATA_NUMBER);
-       }
-       else {
-               ERR("Invalid op_code(%d)", op_code);
-               return CTS_ERR_ARG_INVALID;
+       if (contact->numbers) {
+               ret = cts_insert_contact_data_number(stmt, contact->numbers);
+               retvm_if(ret < CTS_SUCCESS, ret, "cts_insert_contact_data_number() Failed(%d)", ret);
        }
 
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_TRUE != ret)
-       {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               return CTS_ERR_DB_RECORD_NOT_FOUND;
+       if (contact->emails) {
+               ret = cts_insert_contact_data_email(stmt, contact->emails);
+               retvm_if(ret < CTS_SUCCESS, ret, "cts_insert_contact_data_email() Failed(%d)", ret);
        }
 
-       number = (cts_number *)contacts_svc_value_new(CTS_VALUE_NUMBER);
-       if (number) {
-               ret = CTS_SUCCESS;
-               number->v_type = CTS_VALUE_RDONLY_NUMBER;
-               number->embedded = true;
-               cts_stmt_get_number(stmt, number, 0);
-
-               if (CTS_GET_DEFAULT_NUMBER_VALUE == op_code)
-                       number->is_default = true;
-               else
-                       ret = cts_stmt_get_int(stmt, 3);
-
-               *value = (CTSvalue*) number;
-
-               cts_stmt_finalize(stmt);
-               return ret;
-       }
-       else {
-               ERR("contacts_svc_value_new() Failed");
-               cts_stmt_finalize(stmt);
-               return CTS_ERR_OUT_OF_MEMORY;
+       if (contact->events) {
+               ret = cts_insert_contact_data_event(stmt, contact->events);
+               retvm_if(CTS_SUCCESS != ret, ret, "cts_insert_contact_data_event() Failed(%d)", ret);
        }
-}
-
-static inline int cts_get_email_value(int op_code, int id, CTSvalue **value)
-{
-       int ret;
-       cts_stmt stmt;
-       cts_email *email;
-       char query[CTS_SQL_MAX_LEN] = {0};
 
-       if (CTS_GET_DEFAULT_EMAIL_VALUE == op_code) {
-               snprintf(query, sizeof(query),
-                               "SELECT B.id, B.data1, B.data2 FROM %s A, %s B "
-                               "WHERE A.contact_id = %d AND B.id=A.default_email AND B.datatype = %d",
-                               CTS_TABLE_CONTACTS, CTS_TABLE_DATA, id, CTS_DATA_EMAIL);
-       }
-       else if (CTS_GET_EMAIL_VALUE == op_code) {
-               snprintf(query, sizeof(query),
-                               "SELECT id, data1, data2, contact_id FROM %s "
-                               "WHERE id = %d AND datatype = %d",
-                               CTS_TABLE_DATA, id, CTS_DATA_EMAIL);
-       }
-       else {
-               ERR("Invalid op_code(%d)", op_code);
-               return CTS_ERR_ARG_INVALID;
+       if (contact->messengers) {
+               ret = cts_insert_contact_data_messenger(stmt, contact->messengers);
+               retvm_if(CTS_SUCCESS != ret, ret, "cts_insert_contact_data_messenger() Failed(%d)", ret);
        }
 
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_TRUE != ret)
-       {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               return CTS_ERR_DB_RECORD_NOT_FOUND;
+       if (contact->postal_addrs) {
+               ret = cts_insert_contact_data_postal(stmt, contact->postal_addrs);
+               retvm_if(CTS_SUCCESS != ret, ret, "cts_insert_contact_data_postal() Failed(%d)", ret);
        }
 
-       email = (cts_email *)contacts_svc_value_new(CTS_VALUE_EMAIL);
-       if (email)
-       {
-               ret = CTS_SUCCESS;
-               email->v_type = CTS_VALUE_RDONLY_EMAIL;
-               email->embedded = true;
-               cts_stmt_get_email(stmt, email, 0);
-
-               if (CTS_GET_DEFAULT_EMAIL_VALUE == op_code)
-                       email->is_default = true;
-               else
-                       ret = cts_stmt_get_int(stmt, 3);
-
-               *value = (CTSvalue*) email;
-
-               cts_stmt_finalize(stmt);
-               return ret;
-       }
-       else
-       {
-               ERR("contacts_svc_value_new() Failed");
-               cts_stmt_finalize(stmt);
-               return CTS_ERR_OUT_OF_MEMORY;
+       if (contact->web_addrs) {
+               ret = cts_insert_contact_data_web(stmt, contact->web_addrs);
+               retvm_if(CTS_SUCCESS != ret, ret, "cts_insert_contact_data_web() Failed(%d)", ret);
        }
-}
-
-static inline int cts_get_extend_data(int type, int id, CTSvalue **value)
-{
-       int ret;
-       cts_stmt stmt;
-       char query[CTS_SQL_MAX_LEN] = {0};
 
-       snprintf(query, sizeof(query), "SELECT id, data1, data2,"
-                       "data3, data4, data5, data6, data7, data8, data9, data10 "
-                       "FROM %s WHERE datatype = %d AND contact_id = %d", CTS_TABLE_DATA, type, id);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_TRUE != ret)
-       {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               return CTS_ERR_DB_RECORD_NOT_FOUND;
+       if (contact->nicknames) {
+               ret = cts_insert_contact_data_nick(stmt, contact->nicknames);
+               retvm_if(CTS_SUCCESS != ret, ret, "cts_insert_contact_data_nick() Failed(%d)", ret);
        }
 
-       *value = (CTSvalue *)cts_make_extend_data(stmt, type, 0);
-       cts_stmt_finalize(stmt);
-
-       retvm_if(NULL == *value, CTS_ERR_OUT_OF_MEMORY, "cts_make_extend_data() return NULL");
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_get_contact_value(cts_get_contact_val_op op_code,
-               int id, CTSvalue **value)
-{
-       int ret;
-       contact_t temp={0};
-
-       retv_if(NULL == value, CTS_ERR_ARG_NULL);
-       CTS_START_TIME_CHECK;
-
-       if ((int)CTS_DATA_EXTEND_START <= op_code) {
-               ret = cts_get_extend_data(op_code, id, value);
-               retvm_if(CTS_SUCCESS != ret, ret, "cts_get_extend_data() Failed(%d)", ret);
+       if (contact->company) {
+               ret = cts_insert_contact_data_company(stmt, contact->company);
+               retvm_if(CTS_SUCCESS != ret, ret, "cts_insert_contact_data_company() Failed(%d)", ret);
        }
-       else {
-               switch (op_code)
-               {
-               case CTS_GET_NAME_VALUE:
-                       ret = cts_get_data_info(CTS_GET_DATA_BY_CONTACT_ID,
-                                       CTS_DATA_FIELD_NAME, id, &temp);
-                       retvm_if(CTS_SUCCESS != ret, ret,
-                                       "cts_get_data_info(CTS_GET_DATA_BY_CONTACT_ID) Failed(%d)", ret);
-                       if (temp.name) {
-                               temp.name->v_type = CTS_VALUE_RDONLY_NAME;
-                               *value = (CTSvalue *)temp.name;
-                       }else
-                               *value = NULL;
-                       break;
-               case CTS_GET_DEFAULT_NUMBER_VALUE:
-               case CTS_GET_NUMBER_VALUE:
-                       ret = cts_get_number_value(op_code, id, value);
-                       retvm_if(ret < CTS_SUCCESS, ret,
-                                       "cts_get_number_value() Failed(%d)", ret);
-                       break;
-               case CTS_GET_DEFAULT_EMAIL_VALUE:
-               case CTS_GET_EMAIL_VALUE:
-                       ret = cts_get_email_value(op_code, id, value);
-                       retvm_if(ret < CTS_SUCCESS, ret, "cts_get_email_value() Failed(%d)", ret);
-                       break;
-               case CTS_GET_COMPANY_VALUE:
-                       ret = cts_get_data_info(CTS_GET_DATA_BY_CONTACT_ID,
-                                       CTS_DATA_FIELD_COMPANY, id, &temp);
-                       retvm_if(CTS_SUCCESS != ret, ret,
-                                       "cts_get_data_info(CTS_DATA_FIELD_COMPANY) Failed(%d)", ret);
-                       if (temp.company) {
-                               temp.company->v_type = CTS_VALUE_RDONLY_COMPANY;
-                               *value = (CTSvalue *)temp.company;
-                       }else
-                               *value = NULL;
-                       break;
-               default:
-                       ERR("Invalid parameter : The op_code(%d) is not supported", op_code);
-                       return CTS_ERR_ARG_INVALID;
-               }
+
+       if (contact->base) {
+               ret = cts_set_img(CTS_MY_IMAGE_LOCATION, 0, contact->base->img_path);
+               retvm_if(CTS_SUCCESS != ret, ret, "cts_set_img() Failed(%d)", ret);
        }
-       if (NULL == *value) return CTS_ERR_NO_DATA;
 
-       CTS_END_TIME_CHECK();
-       return ret;
+       return CTS_SUCCESS;
 }
 
-API int contacts_svc_get_contact(int index, CTSstruct **contact)
+API int contacts_svc_set_myprofile(CTSstruct *contact)
 {
        int ret;
-       contact_t *record;
-
-       retv_if(NULL == contact, CTS_ERR_ARG_NULL);
-       CTS_START_TIME_CHECK;
-
-       record = (contact_t *)contacts_svc_struct_new(CTS_STRUCT_CONTACT);
 
-       ret = cts_get_main_contacts_info(CTS_MAIN_CTS_GET_ALL, index, record);
-       if (CTS_SUCCESS != ret) {
-               ERR("cts_get_main_contacts_info(ALL) Failed(%d)", ret);
-               goto CTS_RETURN_ERROR;
-       }
-
-       ret = cts_get_data_info(CTS_GET_DATA_BY_CONTACT_ID,
-                       CTS_DATA_FIELD_ALL, index, record);
-       if (CTS_SUCCESS != ret) {
-               ERR("cts_get_data_info(CTS_GET_DATA_BY_CONTACT_ID) Failed(%d)", ret);
-               goto CTS_RETURN_ERROR;
-       }
+       ret = contacts_svc_begin_trans();
+       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
 
-       ret = cts_get_groups_info(index, record);
+       ret = cts_set_myprofile((contact_t *)contact);
        if (CTS_SUCCESS != ret) {
-               ERR("cts_get_group_info(CTS_GET_DATA_BY_CONTACT_ID) Failed(%d)", ret);
-               goto CTS_RETURN_ERROR;
+               ERR("cts_set_myprofile() Failed(%d)", ret);
+               contacts_svc_end_trans(false);
+               return ret;
        }
 
-       *contact = (CTSstruct *)record;
+       ret = contacts_svc_end_trans(true);
+       retvm_if(ret < CTS_SUCCESS, ret, "contacts_svc_end_trans() Failed(%d)", ret);
 
-       CTS_END_TIME_CHECK();
        return CTS_SUCCESS;
-
-CTS_RETURN_ERROR:
-       contacts_svc_struct_free((CTSstruct *)record);
-       return ret;
-}
-
-API int contacts_svc_find_contact_by(cts_find_op op_code,
-               const char *user_data)
-{
-       int ret;
-       const char *temp;
-       char query[CTS_SQL_MAX_LEN] = {0};
-       char normalized_val[CTS_SQL_MIN_LEN];
-
-       CTS_START_TIME_CHECK;
-       retv_if(NULL == user_data, CTS_ERR_ARG_NULL);
-
-       switch (op_code)
-       {
-       case CTS_FIND_BY_NUMBER:
-               ret = cts_clean_number(user_data, normalized_val, sizeof(normalized_val));
-               retvm_if(ret <= 0, CTS_ERR_ARG_INVALID, "Number(%s) is invalid", user_data);
-
-               temp = cts_normalize_number(normalized_val);
-               snprintf(query, sizeof(query), "SELECT contact_id "
-                               "FROM %s WHERE datatype = %d AND data3 = '%s' LIMIT 1",
-                               CTS_TABLE_DATA, CTS_DATA_NUMBER, temp);
-               ret = cts_query_get_first_int_result(query);
-               break;
-       case CTS_FIND_BY_EMAIL:
-               snprintf(query, sizeof(query), "SELECT contact_id "
-                               "FROM %s WHERE datatype = %d AND data2 = '%s' LIMIT 1",
-                               CTS_TABLE_DATA, CTS_DATA_EMAIL, user_data);
-               ret = cts_query_get_first_int_result(query);
-               break;
-       case CTS_FIND_BY_NAME:
-               ret = cts_normalize_str(user_data, normalized_val, sizeof(normalized_val));
-               retvm_if(ret < CTS_SUCCESS, ret, "cts_normalize_str() Failed(%d)", ret);
-
-               if (CTS_ORDER_NAME_LASTFIRST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
-                       temp = CTS_SCHEMA_DATA_NAME_REVERSE_LOOKUP;
-               else
-                       temp = CTS_SCHEMA_DATA_NAME_LOOKUP;
-
-               snprintf(query, sizeof(query), "SELECT contact_id FROM %s "
-                               "WHERE %s LIKE '%%%s%%' LIMIT 1",
-                               CTS_TABLE_DATA, temp, normalized_val);
-
-               ret = cts_query_get_first_int_result(query);
-               break;
-       case CTS_FIND_BY_UID:
-               snprintf(query, sizeof(query), "SELECT contact_id "
-                               "FROM %s WHERE uid = '%s' LIMIT 1", CTS_TABLE_CONTACTS, user_data);
-               ret = cts_query_get_first_int_result(query);
-               break;
-       default:
-               ERR("Invalid parameter : The op_code(%d) is not supported", op_code);
-               return CTS_ERR_ARG_INVALID;
-       }
-
-       CTS_END_TIME_CHECK();
-       return ret;
 }
index 0fd1531..f0dd35b 100755 (executable)
@@ -377,7 +377,7 @@ int contacts_svc_get_contact_value(cts_get_contact_val_op op_code,
 int contacts_svc_get_contact(int index, CTSstruct **contact);
 
 /**
- * Use for contacts_svc_find_contact_by().
+ * Use for contacts_svc_find_contact_by(), contacts_svc_find_person_by()
  */
 typedef enum {
        CTS_FIND_NONE,
index c2d2655..b43e436 100755 (executable)
@@ -22,6 +22,7 @@
 #include "cts-schema.h"
 #include "cts-sqlite.h"
 #include "cts-utils.h"
+#include "cts-restriction.h"
 #include "cts-favorite.h"
 
 API int contacts_svc_set_favorite(cts_favor_type op, int related_id)
@@ -31,7 +32,7 @@ API int contacts_svc_set_favorite(cts_favor_type op, int related_id)
        cts_stmt stmt;
        char query[CTS_SQL_MAX_LEN] = {0};
 
-       retvm_if(CTS_FAVOR_CONTACT != op && CTS_FAVOR_NUMBER != op, CTS_ERR_ARG_INVALID,
+       retvm_if(CTS_FAVOR_PERSON != op && CTS_FAVOR_NUMBER != op, CTS_ERR_ARG_INVALID,
                        "op(%d) is invalid", op);
 
        snprintf(query, sizeof(query),
@@ -57,8 +58,8 @@ API int contacts_svc_set_favorite(cts_favor_type op, int related_id)
 
        prio = prio + 1.0;
        snprintf(query, sizeof(query),
-                       "INSERT INTO %s(type, related_id, favorite_prio) VALUES(%d, %d, %f)",
-                       CTS_TABLE_FAVORITES, op, related_id, prio);
+                       "INSERT INTO %s SELECT NULL, %d, contact_id, %f FROM %s WHERE person_id = %d",
+                       CTS_TABLE_FAVORITES, op, prio, CTS_TABLE_CONTACTS, related_id);
 
        ret = cts_query_exec(query);
        if (CTS_SUCCESS != ret)
@@ -83,11 +84,17 @@ API int contacts_svc_unset_favorite(cts_favor_type op, int related_id)
        cts_stmt stmt;
        char query[CTS_SQL_MIN_LEN] = {0};
 
-       retvm_if(CTS_FAVOR_CONTACT != op && CTS_FAVOR_NUMBER != op, CTS_ERR_ARG_INVALID,
-                       "op(%d) is invalid", op);
-
-       snprintf(query, sizeof(query), "DELETE FROM %s WHERE type = %d AND related_id = %d",
-                       CTS_TABLE_FAVORITES, op, related_id);
+       if (CTS_FAVOR_PERSON == op) {
+               snprintf(query, sizeof(query), "DELETE FROM %s WHERE type = %d AND related_id IN "
+                               "(SELECT contact_id FROM %s WHERE person_id = %d)",
+                               CTS_TABLE_FAVORITES, CTS_FAVOR_PERSON, CTS_TABLE_CONTACTS, related_id);
+       } else if (CTS_FAVOR_NUMBER == op) {
+               snprintf(query, sizeof(query), "DELETE FROM %s WHERE type = %d AND related_id = %d",
+                               CTS_TABLE_FAVORITES, CTS_FAVOR_NUMBER, related_id);
+       } else {
+               ERR("op(%d) is invalid", op);
+               return CTS_ERR_ARG_INVALID;
+       }
 
        stmt = cts_query_prepare(query);
        retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
@@ -314,13 +321,19 @@ API int contacts_svc_get_speeddial(int speed_num, CTSvalue **value)
 {
        int ret;
        cts_stmt stmt;
+       const char *data;
        cts_number *number;
        char query[CTS_SQL_MAX_LEN] = {0};
 
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
        snprintf(query, sizeof(query),
                        "SELECT A.id, A.data1, A.data2, A.contact_id FROM %s A, %s B "
                        "WHERE A.datatype = %d AND B.speed_num = %d AND A.id = B.number_id",
-                       CTS_TABLE_DATA, CTS_TABLE_SPEEDDIALS, CTS_DATA_NUMBER, speed_num);
+                       data, CTS_TABLE_SPEEDDIALS, CTS_DATA_NUMBER, speed_num);
 
        stmt = cts_query_prepare(query);
        retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
index f62c02f..59e0f9d 100755 (executable)
 //<!--
 
 /**
+ * favorite type
+ */
+typedef enum{
+       CTS_FAVOR_PERSON, /**< Favorite for a contact */
+       CTS_FAVOR_NUMBER /**< Favorite for a number */
+}cts_favor_type;
+
+/** deprecated */
+#define CTS_FAVOR_CONTACT CTS_FAVOR_PERSON
+
+/**
  * @defgroup   CONTACTS_SVC_FAVORITE Favorite(speeddial) Modification
  * @ingroup    CONTACTS_SVC
  * @addtogroup CONTACTS_SVC_FAVORITE
  */
 
 /**
- * favorite type
- */
-typedef enum{
-       CTS_FAVOR_CONTACT, /**< Favorite for a contact */
-       CTS_FAVOR_NUMBER /**< Favorite for a number */
-}cts_favor_type;
-
-/**
  * This function marks a number or a contact as "favorite".
  * @param[in] op favorite type(#cts_favor_type).
  * @param[in] related_id a contact or number id which is related op.
index 41d5de7..6277f74 100755 (executable)
@@ -23,6 +23,7 @@
 #include "cts-sqlite.h"
 #include "cts-utils.h"
 #include "cts-list.h"
+#include "cts-person.h"
 #include "cts-group.h"
 
 API int contacts_svc_find_group(int addressbook_id, const char *name)
@@ -38,7 +39,6 @@ API int contacts_svc_find_group(int addressbook_id, const char *name)
        return cts_query_get_first_int_result(query);
 }
 
-
 API int contacts_svc_get_group(int index, CTSvalue **retgroup)
 {
        int ret;
@@ -64,13 +64,13 @@ API int contacts_svc_get_group(int index, CTSvalue **retgroup)
        cts_group *group;
        group = (cts_group *)contacts_svc_value_new(CTS_VALUE_GROUP);
 
-       if (group)
-       {
+       if (group) {
                group->embedded = true;
                group->id = cts_stmt_get_int(stmt, 0);
                group->addrbook_id = cts_stmt_get_int(stmt, 1);
                group->name = SAFE_STRDUP(cts_stmt_get_text(stmt, 2));
                group->ringtone_path = SAFE_STRDUP(cts_stmt_get_text(stmt, 3));
+               group->img_loaded = false; //It will load at cts_value_get_str_group()
        }
        cts_stmt_finalize(stmt);
 
@@ -92,12 +92,12 @@ API int contacts_svc_update_group(CTSvalue *group)
        retvm_if(NULL == record->name, CTS_ERR_ARG_INVALID,
                        "The name of group is empty.");
 
-       snprintf(query, sizeof(query), "UPDATE %s SET group_name=?, ringtone=? "
-                       "WHERE group_id=%d", CTS_TABLE_GROUPS, record->id);
-
        ret = contacts_svc_begin_trans();
        retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
 
+       snprintf(query, sizeof(query), "UPDATE %s SET group_name=?, changed_ver=%d, ringtone=? "
+                       "WHERE group_id=%d", CTS_TABLE_GROUPS, cts_get_next_ver(), record->id);
+
        stmt = cts_query_prepare(query);
        if (NULL == stmt) {
                ERR("cts_query_prepare() Failed");
@@ -119,6 +119,15 @@ API int contacts_svc_update_group(CTSvalue *group)
        }
        cts_stmt_finalize(stmt);
 
+       if (record->img_loaded) {
+               ret = cts_set_img(CTS_GROUP_IMAGE_LOCATION, record->id, record->img_path);
+               if(CTS_SUCCESS != ret) {
+                       ERR("cts_set_img() Failed(%d)", ret);
+                       ret = contacts_svc_end_trans(false);
+                       return ret;
+               }
+       }
+
        cts_set_group_noti();
 
        ret = contacts_svc_end_trans(true);
@@ -130,7 +139,7 @@ API int contacts_svc_update_group(CTSvalue *group)
 
 API int contacts_svc_insert_group(int addressbook_id, CTSvalue *group)
 {
-       int ret, index;
+       int ret, index, ver;
        cts_stmt stmt = NULL;
        cts_group *record = (cts_group *)group;
        char query[CTS_SQL_MAX_LEN] = {0};
@@ -141,14 +150,16 @@ API int contacts_svc_insert_group(int addressbook_id, CTSvalue *group)
        retvm_if(NULL == record->name, CTS_ERR_ARG_INVALID,
                        "The name of group is empty.");
 
-       snprintf(query, sizeof(query),
-                       "INSERT INTO %s(addrbook_id, group_name, ringtone) "
-                       "VALUES(%d, ?, ?)",
-                       CTS_TABLE_GROUPS, addressbook_id);
-
        ret = contacts_svc_begin_trans();
        retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
 
+       ver = cts_get_next_ver();
+
+       snprintf(query, sizeof(query),
+                       "INSERT INTO %s(addrbook_id, group_name, created_ver, changed_ver, ringtone) "
+                       "VALUES(%d, ?, %d, %d, ?)",
+                       CTS_TABLE_GROUPS, addressbook_id, ver, ver);
+
        stmt = cts_query_prepare(query);
        if (NULL == stmt) {
                ERR("cts_query_prepare() Failed");
@@ -172,6 +183,15 @@ API int contacts_svc_insert_group(int addressbook_id, CTSvalue *group)
        index = cts_db_get_last_insert_id();
        cts_stmt_finalize(stmt);
 
+       if(record->img_path) {
+               ret = cts_set_img(CTS_GROUP_IMAGE_LOCATION, index, record->img_path);
+               if(CTS_SUCCESS != ret) {
+                       ERR("cts_set_img() Failed(%d)", ret);
+                       ret = contacts_svc_end_trans(false);
+                       return ret;
+               }
+       }
+
        cts_set_group_noti();
        ret = contacts_svc_end_trans(true);
        retvm_if(ret < CTS_SUCCESS, ret,
@@ -192,6 +212,7 @@ API int contacts_svc_delete_group_with_members(int index)
                        "IN (SELECT contact_id FROM %s A WHERE group_id = %d AND "
                        "(SELECT COUNT(*) FROM %s B WHERE A.contact_id = B.contact_id) = 1)",
                        CTS_TABLE_CONTACTS, CTS_TABLE_GROUPING_INFO, index, CTS_TABLE_GROUPING_INFO);
+
        ret = cts_query_exec(query);
        if (CTS_SUCCESS != ret)
        {
@@ -200,6 +221,13 @@ API int contacts_svc_delete_group_with_members(int index)
                return ret;
        }
 
+       ret = cts_person_garbagecollection();
+       if (CTS_SUCCESS != ret) {
+               ERR("cts_person_garbagecollection() Failed(%d)", ret);
+               contacts_svc_end_trans(false);
+               return ret;
+       }
+
        snprintf(query, sizeof(query), "DELETE FROM %s WHERE group_id = %d",
                        CTS_TABLE_GROUPS, index);
        ret = cts_query_exec(query);
@@ -212,6 +240,23 @@ API int contacts_svc_delete_group_with_members(int index)
 
        ret = cts_db_change();
        if (0 < ret) {
+               snprintf(query, sizeof(query), "INSERT INTO %s VALUES(%d, "
+                       "(SELECT addrbook_id FROM %s WHERE group_id = %d), %d)",
+                               CTS_TABLE_GROUP_DELETEDS, index, CTS_TABLE_GROUPS, index, cts_get_next_ver());
+               ret = cts_query_exec(query);
+               if (CTS_SUCCESS != ret) {
+                       ERR("cts_query_exec() Failed(%d)", ret);
+                       contacts_svc_end_trans(false);
+                       return ret;
+               }
+
+               ret = cts_set_img(CTS_GROUP_IMAGE_LOCATION, index, NULL);
+               if(CTS_SUCCESS != ret) {
+                       ERR("cts_set_img() Failed(%d)", ret);
+                       ret = contacts_svc_end_trans(false);
+                       return ret;
+               }
+
                cts_set_contact_noti();
                cts_set_group_noti();
                ret = contacts_svc_end_trans(true);
@@ -247,6 +292,23 @@ API int contacts_svc_delete_group(int index)
 
        ret = cts_db_change();
        if (0 < ret) {
+               snprintf(query, sizeof(query), "INSERT INTO %s VALUES(%d, "
+                       "(SELECT addrbook_id FROM %s WHERE group_id = %d), %d)",
+                               CTS_TABLE_GROUP_DELETEDS, index, CTS_TABLE_GROUPS, index, cts_get_next_ver());
+               ret = cts_query_exec(query);
+               if (CTS_SUCCESS != ret) {
+                       ERR("cts_query_exec() Failed(%d)", ret);
+                       contacts_svc_end_trans(false);
+                       return ret;
+               }
+
+               ret = cts_set_img(CTS_GROUP_IMAGE_LOCATION, index, NULL);
+               if (ret < 0) {
+                       ERR("cts_set_img() Failed(%d)", ret);
+                       ret = contacts_svc_end_trans(false);
+                       return ret;
+               }
+
                cts_set_group_noti();
                ret = contacts_svc_end_trans(true);
        } else {
@@ -260,11 +322,33 @@ API int contacts_svc_delete_group(int index)
                return CTS_SUCCESS;
 }
 
+/* type CTS_OPERATION_DELETED is set, CTS_OPERATION_INSERTED is unset */
+int cts_group_add_log(int group_id, int type)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MIN_LEN];
+
+       snprintf(query, sizeof(query), "INSERT OR IGNORE INTO %s VALUES(%d, %d, %d)",
+                       "group_relations_log", group_id, type, cts_get_next_ver());
+
+       stmt = cts_query_prepare(query);
+       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+
+       ret = cts_stmt_step(stmt);
+       warn_if(CTS_SUCCESS != ret, "cts_stmt_step() Failed(%d)", ret);
+
+       cts_stmt_finalize(stmt);
+
+       return ret;
+}
+
 int cts_group_set_relation(int group_id, int contact_id, int contact_acc)
 {
        int ret;
        cts_stmt stmt = NULL;
        char query[CTS_SQL_MIN_LEN];
+       int rel_changed = 0;
 
        snprintf(query, sizeof(query),
                        "SELECT addrbook_id FROM %s WHERE group_id = %d",
@@ -286,8 +370,14 @@ int cts_group_set_relation(int group_id, int contact_id, int contact_acc)
        ret = cts_stmt_step(stmt);
        warn_if(CTS_SUCCESS != ret, "cts_stmt_step() Failed(%d)", ret);
 
+       rel_changed = cts_db_change();
        cts_stmt_finalize(stmt);
 
+       if (0 < rel_changed) {
+               cts_group_add_log(group_id, CTS_OPERATION_INSERTED);
+               return rel_changed;
+       }
+
        return ret;
 }
 
@@ -295,6 +385,7 @@ API int contacts_svc_group_set_relation(int group_id, int contact_id)
 {
        int ret, ct_acc=0;
        char query[CTS_SQL_MIN_LEN];
+       int changed;
 
        snprintf(query, sizeof(query),
                        "SELECT addrbook_id FROM %s WHERE contact_id = %d LIMIT 1",
@@ -306,11 +397,11 @@ API int contacts_svc_group_set_relation(int group_id, int contact_id)
        ret = contacts_svc_begin_trans();
        retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
 
-       ret = cts_group_set_relation(group_id, contact_id, ct_acc);
-       if (ret) {
+       changed = cts_group_set_relation(group_id, contact_id, ct_acc);
+       if (changed < CTS_SUCCESS) {
                contacts_svc_end_trans(false);
-               ERR("cts_group_set_relation() Failed(%d)", ret);
-               return ret;
+               ERR("cts_group_set_relation() Failed(%d)", changed);
+               return changed;
        }
 
        ret = cts_update_contact_changed_time(contact_id);
@@ -321,7 +412,8 @@ API int contacts_svc_group_set_relation(int group_id, int contact_id)
        }
 
        cts_set_contact_noti();
-       cts_set_group_rel_noti();
+       if (0 < changed)
+               cts_set_group_rel_noti();
        ret = contacts_svc_end_trans(true);
        if (ret < CTS_SUCCESS)
                return ret;
@@ -345,14 +437,19 @@ int cts_group_unset_relation(int group_id, int contact_id)
        ret = cts_stmt_step(stmt);
        warn_if(CTS_SUCCESS != ret, "cts_stmt_step() Failed(%d)", ret);
 
+       ret = cts_db_change();
        cts_stmt_finalize(stmt);
 
+       if (0 <= ret)
+               cts_group_add_log(group_id, CTS_OPERATION_DELETED);
+
        return ret;
 }
 
 API int contacts_svc_group_unset_relation(int group_id, int contact_id)
 {
        int ret;
+       int changed;
 
        retvm_if(!group_id, CTS_ERR_ARG_INVALID, "group_id is 0");
        retvm_if(!contact_id, CTS_ERR_ARG_INVALID, "contact_id is 0");
@@ -360,11 +457,11 @@ API int contacts_svc_group_unset_relation(int group_id, int contact_id)
        ret = contacts_svc_begin_trans();
        retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
 
-       ret = cts_group_unset_relation(group_id, contact_id);
-       if (ret) {
+       changed = cts_group_unset_relation(group_id, contact_id);
+       if (changed < CTS_SUCCESS) {
                contacts_svc_end_trans(false);
-               ERR("cts_group_unset_relation() Failed(%d)", ret);
-               return ret;
+               ERR("cts_group_unset_relation() Failed(%d)", changed);
+               return changed;
        }
 
        ret = cts_update_contact_changed_time(contact_id);
@@ -375,7 +472,8 @@ API int contacts_svc_group_unset_relation(int group_id, int contact_id)
        }
 
        cts_set_contact_noti();
-       cts_set_group_rel_noti();
+       if (0 < changed)
+               cts_set_group_rel_noti();
        ret = contacts_svc_end_trans(true);
        if (ret < CTS_SUCCESS)
                return ret;
diff --git a/src/cts-im.c b/src/cts-im.c
new file mode 100755 (executable)
index 0000000..5a21bf9
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjae Shin <yj99.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "cts-internal.h"
+#include "cts-im.h"
+
+API int contacts_svc_get_im_status(cts_get_im_op op_code, int search_id,
+               cts_im_callback_fn cb, void *user_data)
+{
+       // select MAX(status) from connected_im where contact_id = index
+       // select status from connected_im where data_id = index
+       return CTS_SUCCESS;
+}
+
+API int contacts_svc_set_im_status(cts_im_type type,
+               const char *im_id, cts_im_status status)
+{
+       return CTS_SUCCESS;
+}
+
diff --git a/src/cts-im.h b/src/cts-im.h
new file mode 100755 (executable)
index 0000000..36d52c9
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjae Shin <yj99.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#ifndef __CTS_IM_H__
+#define __CTS_IM_H__
+//<!--
+/**
+ * A kind of status for instant messaging
+ * @see contacts_svc_set_im_status()
+ */
+typedef enum
+{
+       CTS_IM_STATUS_NONE=0,
+       CTS_IM_STATUS_OFFLINE,
+       CTS_IM_STATUS_BUSY,
+       CTS_IM_STATUS_AWAY,
+       CTS_IM_STATUS_ONLINE,
+}cts_im_status;
+
+/**
+ * This is the signature of a callback function added with contacts_svc_get_im_status().
+ * \n The callback function is invoked when the status of IM(Instant Messaging) is got.
+ * @param[in] index The index of contact or im information
+ * @param[in] stat #cts_im_status
+ * @param[in] user_data The data which is set by contacts_svc_get_im_status()
+ */
+typedef void (*cts_im_callback_fn)(int index, cts_im_status stat, void* user_data);
+
+/**
+ * Use for contacts_svc_get_im_status().
+ */
+typedef enum{
+       CTS_IM_STATUS, /**< Status for A Instant Messaging ID */
+       CTS_IM_CONTACT_STATUS /**< Status for a contact ID  */
+}cts_get_im_op;
+
+/**
+ * This function gets status of IM by op_code(CTS_IM_STATUS, CTS_IM_CONTACT_STATUS).
+ * #search_id is related to op_code.
+ * For #CTS_IM_STATUS, search_id is a id of IM information
+ * For #CTS_IM_CONTACT_STATUS, search_id is a id of contact
+ * @param[in] op_code #cts_get_im_op
+ * @param[in] search_id index for searching.
+ * @param[in] cb callback function(#cts_im_callback_fn)
+ * @param[in] user_data callback data
+ * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
+ */
+int contacts_svc_get_im_status(cts_get_im_op op_code, int search_id,
+               cts_im_callback_fn cb, void *user_data);
+
+typedef enum{
+       CTS_IM_TYPE_NONE, /**< Others */
+       CTS_IM_TYPE_GOOGLE,
+       CTS_IM_TYPE_WLM,
+       CTS_IM_TYPE_YAHOO,
+       CTS_IM_TYPE_FACEBOOK,
+       CTS_IM_TYPE_ICQ,
+       CTS_IM_TYPE_AIM,
+       CTS_IM_TYPE_QQ,
+       CTS_IM_TYPE_JABBER,
+       CTS_IM_TYPE_SKYPE,
+       CTS_IM_TYPE_IRC,
+}cts_im_type;
+
+/**
+ * This function sets status of IM.
+ * @param[in] type The type of IM.(#cts_im_type)
+ * @param[in] im_id The user ID of IM
+ * @param[in] status status of IM to be set.
+ * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
+ */
+int contacts_svc_set_im_status(cts_im_type type, const char *im_id, cts_im_status status);
+//-->
+#endif //__CTS_IM_H__
diff --git a/src/cts-list-filter.c b/src/cts-list-filter.c
new file mode 100755 (executable)
index 0000000..33d5445
--- /dev/null
@@ -0,0 +1,724 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjae Shin <yj99.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "cts-internal.h"
+#include "cts-schema.h"
+#include "cts-utils.h"
+#include "cts-types.h"
+#include "cts-normalize.h"
+#include "cts-restriction.h"
+#include "cts-list-filter.h"
+
+
+enum {
+       CTS_FILTER_TYPE_NONE,
+       CTS_FILTER_TYPE_INT,
+       CTS_FILTER_TYPE_STR,
+};
+
+API int contacts_svc_list_filter_free(CTSfilter *filter)
+{
+       retv_if(NULL == filter, CTS_ERR_ARG_NULL);
+
+       free(filter->search_val);
+       free(filter);
+       return CTS_SUCCESS;
+}
+
+static inline int cts_filter_parse_args(va_list args, int type, CTSfilter *ret)
+{
+       while (type) {
+               switch (type) {
+               case CTS_LIST_FILTER_NONE:
+                       break;
+               case CTS_LIST_FILTER_ADDRESBOOK_ID_INT:
+                       ret->addrbook_on = true;
+                       ret->addrbook_id = va_arg(args, int);
+                       break;
+               case CTS_LIST_FILTER_GROUP_ID_INT:
+                       ret->group_on = true;
+                       ret->group_id = va_arg(args, int);
+                       break;
+               case CTS_LIST_FILTER_LIMIT_INT:
+                       ret->limit_on = true;
+                       ret->limit = va_arg(args, int);
+                       break;
+               case CTS_LIST_FILTER_OFFSET_INT:
+                       ret->offset_on = true;
+                       ret->offset = va_arg(args, int);
+                       break;
+               default:
+                       ERR("Invalid type. Your type(%d) is not supported.", type);
+                       return CTS_ERR_ARG_INVALID;
+               }
+               type = va_arg(args, int);
+       }
+
+       retvm_if(ret->offset_on && !ret->limit_on, CTS_ERR_ARG_INVALID, "OFFSET is depends on LIMIT");
+
+       return CTS_SUCCESS;
+}
+
+API CTSfilter* contacts_svc_list_str_filter_new(cts_str_filter_op list_type,
+               const char *search_value, cts_filter_type first_type, ...)
+{
+       int ret;
+       CTSfilter *ret_val;
+       va_list args;
+
+       retvm_if(NULL == search_value, NULL, "The parameter(search_value) is NULL");
+
+/*  DISABLED. for OSP - permission of making transparent filter
+       retvm_if(CTS_LIST_FILTER_NONE == first_type, NULL,
+                       "filter constraint is missing(use contacts_svc_get_list_with_str()");
+*/
+
+       ret_val = calloc(1, sizeof(CTSfilter));
+       ret_val->type = CTS_FILTER_TYPE_STR;
+       ret_val->list_type = list_type;
+       ret_val->search_val = strdup(search_value);
+
+       va_start(args, first_type);
+       ret = cts_filter_parse_args(args, first_type, ret_val);
+       va_end(args);
+
+       if (ret) {
+               contacts_svc_list_filter_free(ret_val);
+               return NULL;
+       }
+
+       return (CTSfilter *)ret_val;
+}
+
+API CTSfilter* contacts_svc_list_filter_new(cts_filter_op list_type, cts_filter_type first_type, ...)
+{
+       int ret;
+       CTSfilter *ret_val;
+       va_list args;
+
+/* DISABLED. for OSP - permission of making transparent filter
+       retvm_if(CTS_LIST_FILTER_NONE == first_type, NULL,
+                       "filter constraint is missing(use contacts_svc_get_list()");
+*/
+       ret_val = calloc(1, sizeof(CTSfilter));
+       ret_val->type = CTS_FILTER_TYPE_NONE;
+       ret_val->list_type = list_type;
+
+       va_start(args, first_type);
+       ret = cts_filter_parse_args(args, first_type, ret_val);
+       va_end(args);
+
+       if (ret) {
+               contacts_svc_list_filter_free(ret_val);
+               return NULL;
+       }
+
+       return (CTSfilter *)ret_val;
+}
+
+static int cts_list_str_filter_make_query(CTSfilter *filter, CTSiter *iter)
+{
+       int ret;
+       cts_stmt stmt;
+       const char *display, *data;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       char remake_val[CTS_SQL_MIN_LEN] = {0};
+
+       retvm_if(NULL == filter->search_val,
+                       CTS_ERR_ARG_INVALID, "The parameter(filter) doesn't have search_val");
+
+       if (CTS_ORDER_NAME_LASTFIRST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
+               display = CTS_SCHEMA_DATA_NAME_REVERSE_LOOKUP;
+       else
+               display = CTS_SCHEMA_DATA_NAME_LOOKUP;
+
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
+       switch (filter->list_type) {
+       case CTS_FILTERED_PLOGS_OF_NUMBER:
+               iter->i_type = CTS_ITER_PLOGS_OF_NUMBER;
+               if (filter->search_val && *filter->search_val) {
+                       ret = snprintf(query, sizeof(query),
+                                       "SELECT A.id, A.log_type, A.log_time, A.data1, A.data2, MIN(B.contact_id) "
+                                       "FROM %s A LEFT JOIN %s B ON A.normal_num = B.data3 AND B.datatype = %d AND "
+                                       "(A.related_id = B.contact_id OR A.related_id IS NULL OR "
+                                       "NOT EXISTS (SELECT id FROM %s "
+                                       "WHERE datatype = %d AND contact_id = A.related_id AND data3 = ?)) "
+                                       "WHERE A.number = ? "
+                                       "GROUP BY A.id "
+                                       "ORDER BY A.log_time DESC",
+                                       CTS_TABLE_PHONELOGS, data, CTS_DATA_NUMBER, data, CTS_DATA_NUMBER);
+               }
+               else {
+                       ret = snprintf(query, sizeof(query),
+                                       "SELECT id, log_type, log_time, data1, data2, NULL "
+                                       "FROM %s WHERE number ISNULL and log_type < %d "
+                                       "ORDER BY id DESC",
+                                       CTS_TABLE_PHONELOGS, CTS_PLOG_TYPE_EMAIL_RECEIVED);
+               }
+               if (filter->limit_on) {
+                       ret += snprintf(query+ret, sizeof(query)-ret, " LIMIT %d", filter->limit);
+                       if (filter->offset_on)
+                               ret += snprintf(query+ret, sizeof(query)-ret, " OFFSET %d", filter->offset);
+               }
+
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               if (filter->search_val) {
+                       const char *normal_num;
+                       ret = cts_clean_number(filter->search_val, remake_val, sizeof(remake_val));
+                       retvm_if(ret <= 0, CTS_ERR_ARG_INVALID, "Number(%s) is invalid", filter->search_val);
+
+                       normal_num = cts_normalize_number(remake_val);
+                       cts_stmt_bind_copy_text(stmt, 1, normal_num, strlen(normal_num));
+                       cts_stmt_bind_copy_text(stmt, 2, filter->search_val, strlen(filter->search_val));
+               }
+               iter->stmt = stmt;
+               break;
+       case CTS_FILTERED_CONTACTS_WITH_NAME:
+               retvm_if(CTS_SQL_MIN_LEN <= strlen(filter->search_val), CTS_ERR_ARG_INVALID,
+                               "search_value is too long");
+               iter->i_type = CTS_ITER_CONTACTS_WITH_NAME;
+               memset(remake_val, 0x00, sizeof(remake_val));
+
+               ret = cts_normalize_str(filter->search_val, remake_val, CTS_SQL_MIN_LEN);
+               retvm_if(ret < CTS_SUCCESS, ret, "cts_normalize_str() Failed(%d)", ret);
+
+               if (filter->addrbook_on) {
+                       ret = snprintf(query, sizeof(query),
+                                       "SELECT B.person_id, data1, data2, data3, data5, B.addrbook_id, B.image0, B.contact_id "
+                                       "FROM %s A, %s B ON A.contact_id = B.contact_id "
+                                       "WHERE datatype = %d AND B.addrbook_id = %d AND %s LIKE ('%%' || ? || '%%') "
+                                       "ORDER BY data1, %s",
+                                       data, CTS_TABLE_CONTACTS, CTS_DATA_NAME, filter->addrbook_id,
+                                       display, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+               } else if (filter->group_on) {
+                       ret = snprintf(query, sizeof(query),
+                                       "SELECT B.person_id, data1, data2, data3, data5, B.addrbook_id, B.image0, B.contact_id "
+                                       "FROM %s A, %s B ON A.contact_id = B.contact_id "
+                                       "WHERE datatype = %d AND %s LIKE ('%%' || ? || '%%') "
+                                       "AND contact_id IN (SELECT contact_id FROM %s WHERE group_id = %d) "
+                                       "ORDER BY data1, %s",
+                                       data, CTS_TABLE_CONTACTS, CTS_DATA_NAME, display,
+                                       CTS_TABLE_GROUPING_INFO, filter->group_id, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+               } else {
+                       ret = snprintf(query, sizeof(query),
+                                       "SELECT B.person_id, data1, data2, data3, data5, B.addrbook_id, B.image0, B.contact_id "
+                                       "FROM %s A, %s B ON A.contact_id = B.contact_id "
+                                       "WHERE datatype = %d AND %s LIKE ('%%' || ? || '%%') "
+                                       "ORDER BY data1, %s",
+                                       data, CTS_TABLE_CONTACTS, CTS_DATA_NAME, display, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+               }
+
+               if (filter->limit_on) {
+                       ret += snprintf(query+ret, sizeof(query)-ret, " LIMIT %d", filter->limit);
+                       if (filter->offset_on)
+                               ret += snprintf(query+ret, sizeof(query)-ret, " OFFSET %d", filter->offset);
+               }
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               cts_stmt_bind_copy_text(stmt, 1, remake_val, strlen(remake_val));
+               break;
+       case CTS_FILTERED_NUMBERINFOS_WITH_NAME:
+               retvm_if(CTS_SQL_MIN_LEN <= strlen(filter->search_val), CTS_ERR_ARG_INVALID,
+                               "search_value is too long");
+               iter->i_type = CTS_ITER_NUMBERINFOS;
+               memset(remake_val, 0x00, sizeof(remake_val));
+
+               ret = cts_normalize_str(filter->search_val, remake_val, CTS_SQL_MIN_LEN);
+               retvm_if(ret < CTS_SUCCESS, ret, "cts_normalize_str() Failed(%d)", ret);
+
+               if (filter->addrbook_on) {
+                       ret = snprintf(query, sizeof(query),
+                                       "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0, C.contact_id "
+                                       "FROM %s A, %s B, %s C "
+                                       "ON A.contact_id = C.person_id AND B.contact_id = C.contact_id "
+                                       "WHERE A.datatype = %d AND B.datatype = %d "
+                                       "AND C.addrbook_id = %d AND A.%s LIKE ('%%' || ? || '%%') "
+                                       "ORDER BY A.data1, A.%s",
+                                       data, data, CTS_TABLE_CONTACTS,
+                                       CTS_DATA_NAME, CTS_DATA_NUMBER,
+                                       filter->addrbook_id, display, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+               } else if (filter->group_on) {
+                       ret = snprintf(query, sizeof(query),
+                                       "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0, C.contact_id "
+                                       "FROM %s A, %s B, %s C "
+                                       "ON A.contact_id = C.person_id AND B.contact_id = C.contact_id "
+                                       "WHERE A.datatype = %d AND B.datatype = %d AND A.%s LIKE ('%%' || ? || '%%') "
+                                       "AND A.contact_id IN "
+                                       "(SELECT contact_id FROM %s WHERE group_id = %d) "
+                                       "ORDER BY A.data1, A.%s",
+                                       data, data, CTS_TABLE_CONTACTS,
+                                       CTS_DATA_NAME, CTS_DATA_NUMBER, display,
+                                       CTS_TABLE_GROUPING_INFO, filter->group_id, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+               } else {
+                       ret = snprintf(query, sizeof(query),
+                                       "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0, C.contact_id "
+                                       "FROM %s A, %s B, %s C "
+                                       "ON A.contact_id = C.person_id AND B.contact_id = C.contact_id "
+                                       "WHERE A.datatype = %d AND B.datatype = %d AND A.%s LIKE ('%%' || ? || '%%') "
+                                       "ORDER BY A.data1, A.%s",
+                                       data, data, CTS_TABLE_CONTACTS,
+                                       CTS_DATA_NAME, CTS_DATA_NUMBER,
+                                       display, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+               }
+               if (filter->limit_on) {
+                       ret += snprintf(query+ret, sizeof(query)-ret, " LIMIT %d", filter->limit);
+                       if (filter->offset_on)
+                               ret += snprintf(query+ret, sizeof(query)-ret, " OFFSET %d", filter->offset);
+               }
+
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               cts_stmt_bind_copy_text(stmt, 1, remake_val, strlen(remake_val));
+               break;
+       case CTS_FILTERED_NUMBERINFOS_WITH_NUM:
+               iter->i_type = CTS_ITER_NUMBERINFOS;
+
+               if (filter->addrbook_on) {
+                       ret = snprintf(query, sizeof(query),
+                                       "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0, C.contact_id "
+                                       "FROM %s A, %s B, %s C "
+                                       "ON A.contact_id = C.person_id AND B.contact_id = C.contact_id "
+                                       "WHERE A.datatype = %d AND B.datatype = %d "
+                                       "AND C.addrbook_id = %d AND B.data2 LIKE ('%%' || ? || '%%') "
+                                       "ORDER BY A.data1, A.%s",
+                                       data, data, CTS_TABLE_CONTACTS,
+                                       CTS_DATA_NAME, CTS_DATA_NUMBER,
+                                       filter->addrbook_id, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+               } else if (filter->group_on) {
+                       ret = snprintf(query, sizeof(query),
+                                       "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0, C.contact_id "
+                                       "FROM %s A, %s B, %s C "
+                                       "ON A.contact_id = C.person_id AND B.contact_id = C.contact_id "
+                                       "WHERE A.datatype = %d AND B.datatype = %d AND B.data2 LIKE ('%%' || ? || '%%') "
+                                       "AND A.contact_id IN (SELECT contact_id FROM %s WHERE group_id = %d) "
+                                       "ORDER BY A.data1, A.%s",
+                                       data, data, CTS_TABLE_CONTACTS,
+                                       CTS_DATA_NAME, CTS_DATA_NUMBER,
+                                       CTS_TABLE_GROUPING_INFO, filter->group_id, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+               } else {
+                       ret = snprintf(query, sizeof(query),
+                                       "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0, C.contact_id "
+                                       "FROM %s A, %s B, %s C "
+                                       "ON A.contact_id = C.person_id AND B.contact_id = C.contact_id "
+                                       "WHERE B.data2 LIKE ('%%' || ? || '%%') "
+                                       "AND A.datatype = %d AND B.datatype = %d "
+                                       "ORDER BY A.data1, A.%s",
+                                       data, data, CTS_TABLE_CONTACTS,
+                                       CTS_DATA_NAME, CTS_DATA_NUMBER, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+               }
+               if (filter->limit_on) {
+                       ret += snprintf(query+ret, sizeof(query)-ret, " LIMIT %d", filter->limit);
+                       if (filter->offset_on)
+                               ret += snprintf(query+ret, sizeof(query)-ret, " OFFSET %d", filter->offset);
+               }
+
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               cts_stmt_bind_copy_text(stmt, 1, filter->search_val, strlen(filter->search_val));
+               break;
+       case CTS_FILTERED_EMAILINFOS_WITH_EMAIL:
+               iter->i_type = CTS_ITER_EMAILINFOS_WITH_EMAIL;
+
+               if (filter->addrbook_on) {
+                       ret = snprintf(query, sizeof(query),
+                                       "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0, C.contact_id "
+                                       "FROM %s A, %s B, %s C "
+                                       "ON A.contact_id = C.person_id AND B.contact_id = C.contact_id "
+                                       "WHERE A.datatype = %d AND B.datatype = %d AND C.addrbook_id = %d "
+                                       "AND B.data2 LIKE ('%%' || ? || '%%') "
+                                       "ORDER BY A.data1, A.%s",
+                                       data, data, CTS_TABLE_CONTACTS,
+                                       CTS_DATA_NAME, CTS_DATA_EMAIL, filter->addrbook_id,
+                                       CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+               } else if (filter->group_on) {
+                       ret = snprintf(query, sizeof(query),
+                                       "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0, C.contact_id "
+                                       "FROM %s A, %s B, %s C "
+                                       "ON A.contact_id = C.person_id AND B.contact_id = C.contact_id "
+                                       "WHERE A.datatype = %d AND B.datatype = %d AND "
+                                       "B.data2 LIKE ('%%' || ? || '%%') AND A.contact_id IN "
+                                       "(SELECT contact_id FROM %s WHERE group_id = %d) "
+                                       "ORDER BY A.data1, A.%s",
+                                       data, data, CTS_TABLE_CONTACTS,
+                                       CTS_DATA_NAME, CTS_DATA_EMAIL,
+                                       CTS_TABLE_GROUPING_INFO, filter->group_id,
+                                       CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+               } else {
+                       ret = snprintf(query, sizeof(query),
+                                       "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0, C.contact_id "
+                                       "FROM %s A, %s B, %s C "
+                                       "ON A.contact_id = C.person_id AND B.contact_id = C.contact_id "
+                                       "WHERE A.datatype = %d AND B.datatype = %d AND B.data2 LIKE ('%%' || ? || '%%') "
+                                       "ORDER BY A.data1, A.%s",
+                                       data, data, CTS_TABLE_CONTACTS,
+                                       CTS_DATA_NAME, CTS_DATA_EMAIL,
+                                       CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+               }
+               if (filter->limit_on) {
+                       ret += snprintf(query+ret, sizeof(query)-ret, " LIMIT %d", filter->limit);
+                       if (filter->offset_on)
+                               ret += snprintf(query+ret, sizeof(query)-ret, " OFFSET %d", filter->offset);
+               }
+
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               cts_stmt_bind_copy_text(stmt, 1, filter->search_val, strlen(filter->search_val));
+               break;
+       default:
+               ERR("Invalid parameter : The op_code(%d) is not supported", filter->list_type);
+               return CTS_ERR_ARG_INVALID;
+       }
+       iter->stmt = stmt;
+
+       return CTS_SUCCESS;
+}
+
+static inline void cts_filter_make_query_ALL_CONTACT(CTSfilter *filter, char *buf, int buf_size)
+{
+       int ret;
+       const char *display, *data;
+
+       if (CTS_ORDER_NAME_LASTFIRST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
+               display = CTS_SCHEMA_DATA_NAME_REVERSE_LOOKUP;
+       else
+               display = CTS_SCHEMA_DATA_NAME_LOOKUP;
+
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
+       if (filter->addrbook_on) {
+               ret = snprintf(buf, buf_size,
+                               "SELECT B.person_id, data1, data2, data3, data5, B.addrbook_id, B.image0, B.contact_id, %s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
+                               "WHERE datatype = %d AND B.addrbook_id = %d "
+                               "GROUP BY B.person_id "
+                               "ORDER BY data1, %s",
+                               display, data, CTS_TABLE_CONTACTS,
+                               CTS_DATA_NAME, filter->addrbook_id, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+       } else if (filter->group_on) {
+               ret = snprintf(buf, buf_size,
+                               "SELECT B.person_id, data1, data2, data3, data5, B.addrbook_id, B.image0, B.contact_id, %s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
+                               "WHERE datatype = %d AND B.contact_id IN "
+                               "(SELECT contact_id FROM %s WHERE group_id = %d) "
+                               "GROUP BY B.person_id "
+                               "ORDER BY data1, %s",
+                               display, data, CTS_TABLE_CONTACTS, CTS_DATA_NAME,
+                               CTS_TABLE_GROUPING_INFO, filter->group_id, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+       } else {
+               ret = snprintf(buf, buf_size,
+                               "SELECT B.person_id, data1, data2, data3, data5, B.addrbook_id, B.image0, B.person_id, %s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
+                               "WHERE A.datatype = %d AND B.person_id = B.contact_id "
+                               "ORDER BY A.data1, A.%s",
+                               display, data, CTS_TABLE_CONTACTS,
+                               CTS_DATA_NAME, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+       }
+
+       if (filter->limit_on) {
+               ret += snprintf(buf+ret, buf_size-ret, " LIMIT %d", filter->limit);
+               if (filter->offset_on)
+                       ret += snprintf(buf+ret, buf_size-ret, " OFFSET %d", filter->offset);
+       }
+}
+
+static inline void cts_filter_make_query_ALL_CONTACT_OSP(CTSfilter *filter, char *buf, int buf_size)
+{
+       int ret;
+       const char *display, *data;
+
+       if (CTS_ORDER_NAME_LASTFIRST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
+               display = CTS_SCHEMA_DATA_NAME_REVERSE_LOOKUP;
+       else
+               display = CTS_SCHEMA_DATA_NAME_LOOKUP;
+
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
+       if (filter->addrbook_on) {
+               ret = snprintf(buf, buf_size,
+                               "SELECT B.person_id, A.data1, A.data2, A.data3, A.data5, B.addrbook_id, B.image0, B.person_id, "
+                               "C.data1, C.data2, D.data1, D.data2, A.%s "
+                               "FROM (%s A, %s B ON A.contact_id = B.person_id) LEFT JOIN %s C ON B.default_num = C.id "
+                               "LEFT JOIN %s D ON B.default_email = D.id "
+                               "WHERE A.datatype = %d AND B.addrbook_id = %d "
+                               "GROUP BY B.person_id "
+                               "ORDER BY A.data1, A.%s",
+                               display, data, CTS_TABLE_CONTACTS, data, data,
+                               CTS_DATA_NAME, filter->addrbook_id,
+                               CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+       } else if (filter->group_on) {
+               ret = snprintf(buf, buf_size,
+                               "SELECT B.person_id, A.data1, A.data2, A.data3, A.data5, B.addrbook_id, B.image0, B.person_id, "
+                               "C.data1, C.data2, D.data1, D.data2, A.%s "
+                               "FROM (%s A, %s B ON A.contact_id = B.person_id) LEFT JOIN %s C ON B.default_num = C.id "
+                               "LEFT JOIN %s D ON B.default_email = D.id "
+                               "WHERE A.datatype = %d AND B.contact_id IN (SELECT contact_id FROM %s WHERE group_id = %d) "
+                               "GROUP BY B.person_id "
+                               "ORDER BY A.data1, A.%s",
+                               display, data, CTS_TABLE_CONTACTS, data, data,
+                               CTS_DATA_NAME, CTS_TABLE_GROUPING_INFO, filter->group_id,
+                               CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+       } else {
+               ret = snprintf(buf, buf_size,
+                               "SELECT B.person_id, A.data1, A.data2, A.data3, A.data5, B.addrbook_id, B.image0, B.person_id, "
+                               "C.data1, C.data2, D.data1, D.data2, A.%s "
+                               "FROM (%s A, %s B ON A.contact_id = B.person_id) LEFT JOIN %s C ON B.default_num = C.id "
+                               "LEFT JOIN %s D ON B.default_email = D.id "
+                               "WHERE A.datatype = %d AND B.person_id = B.contact_id "
+                               "ORDER BY A.data1, A.%s",
+                               display, data, CTS_TABLE_CONTACTS, data, data,
+                               CTS_DATA_NAME, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+       }
+
+       if (filter->limit_on) {
+               ret += snprintf(buf+ret, buf_size-ret, " LIMIT %d", filter->limit);
+               if (filter->offset_on)
+                       ret += snprintf(buf+ret, buf_size-ret, " OFFSET %d", filter->offset);
+       }
+}
+
+static inline void cts_filter_make_query_ALL_CONTACT_HAD_NUMBER(CTSfilter *filter, char *buf, int buf_size)
+{
+       int ret;
+       const char *display, *data;
+
+       if (CTS_ORDER_NAME_LASTFIRST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
+               display = CTS_SCHEMA_DATA_NAME_REVERSE_LOOKUP;
+       else
+               display = CTS_SCHEMA_DATA_NAME_LOOKUP;
+
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
+       if (filter->addrbook_on) {
+               ret = snprintf(buf, buf_size,
+                               "SELECT B.person_id, A.data1, A.data2, A.data3, A.data5, B.addrbook_id, B.image0, B.contact_id, A.%s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
+                               "WHERE A.datatype = %d AND B.default_num > 0 AND B.addrbook_id = %d "
+                               "GROUP BY B.person_id "
+                               "ORDER BY A.data1, A.%s",
+                               display, data, CTS_TABLE_CONTACTS, CTS_DATA_NAME, filter->addrbook_id,
+                               CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+       } else if (filter->group_on) {
+               ret = snprintf(buf, buf_size,
+                               "SELECT B.person_id, A.data1, A.data2, A.data3, A.data5, B.addrbook_id, B.image0, B.contact_id, A.%s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
+                               "WHERE A.datatype = %d AND B.default_num > 0 AND B.contact_id IN "
+                                       "(SELECT contact_id FROM %s WHERE group_id = %d) "
+                               "GROUP BY B.person_id "
+                               "ORDER BY A.data1, A.%s",
+                               display, data, CTS_TABLE_CONTACTS, CTS_DATA_NAME,
+                               CTS_TABLE_GROUPING_INFO, filter->group_id, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+       } else {
+               snprintf(buf, buf_size,
+                               "SELECT B.person_id, A.data1, A.data2, A.data3, A.data5, B.addrbook_id, B.image0, B.contact_id, A.%s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
+                               "WHERE A.datatype = %d AND B.default_num > 0 "
+                               "GROUP BY B.person_id "
+                               "ORDER BY A.data1, A.%s",
+                               display, data, CTS_TABLE_CONTACTS, CTS_DATA_NAME, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+       }
+
+       if (filter->limit_on) {
+               ret += snprintf(buf+ret, buf_size-ret, " LIMIT %d", filter->limit);
+               if (filter->offset_on)
+                       ret += snprintf(buf+ret, buf_size-ret, " OFFSET %d", filter->offset);
+       }
+}
+
+
+static inline void cts_filter_make_query_ALL_CONTACT_HAD_EMAIL(CTSfilter *filter, char *buf, int buf_size)
+{
+       int ret;
+       const char *display, *data;
+
+       if (CTS_ORDER_NAME_LASTFIRST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
+               display = CTS_SCHEMA_DATA_NAME_REVERSE_LOOKUP;
+       else
+               display = CTS_SCHEMA_DATA_NAME_LOOKUP;
+
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
+       if (filter->addrbook_on) {
+               ret = snprintf(buf, buf_size,
+                               "SELECT B.person_id, A.data1, A.data2, A.data3, A.data5, B.addrbook_id, B.image0, B.contact_id, A.%s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
+                               "WHERE A.datatype = %d AND B.default_email > 0 AND B.addrbook_id = %d "
+                               "GROUP BY B.person_id "
+                               "ORDER BY A.data1, A.%s",
+                               display, data, CTS_TABLE_CONTACTS, CTS_DATA_NAME, filter->addrbook_id,
+                               CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+       } else if (filter->group_on) {
+               ret = snprintf(buf, buf_size,
+                               "SELECT B.person_id, A.data1, A.data2, A.data3, A.data5, B.addrbook_id, B.image0, B.contact_id, A.%s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
+                               "WHERE A.datatype = %d AND B.default_email > 0 AND B.contact_id IN "
+                                       "(SELECT contact_id FROM %s WHERE group_id = %d) "
+                               "GROUP BY B.person_id "
+                               "ORDER BY A.data1, A.%s",
+                               display, data, CTS_TABLE_CONTACTS, CTS_DATA_NAME,
+                               CTS_TABLE_GROUPING_INFO, filter->group_id, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+       } else {
+               snprintf(buf, buf_size,
+                               "SELECT B.person_id, A.data1, A.data2, A.data3, A.data5, B.addrbook_id, B.image0, B.contact_id, A.%s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
+                               "WHERE A.datatype = %d AND B.default_email > 0 "
+                               "GROUP BY B.person_id "
+                               "ORDER BY A.data1, A.%s",
+                               display, data, CTS_TABLE_CONTACTS, CTS_DATA_NAME, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+       }
+
+       if (filter->limit_on) {
+               ret += snprintf(buf+ret, buf_size-ret, " LIMIT %d", filter->limit);
+               if (filter->offset_on)
+                       ret += snprintf(buf+ret, buf_size-ret, " OFFSET %d", filter->offset);
+       }
+}
+
+static int cts_list_filter_make_query(CTSfilter *filter, CTSiter *iter)
+{
+       cts_stmt stmt;
+       const char *display, *data;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       if (CTS_ORDER_NAME_LASTFIRST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
+               display = CTS_SCHEMA_DATA_NAME_REVERSE_LOOKUP;
+       else
+               display = CTS_SCHEMA_DATA_NAME_LOOKUP;
+
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
+       switch (filter->list_type) {
+       case CTS_FILTERED_ALL_CONTACT:
+               iter->i_type = CTS_ITER_CONTACTS;
+
+               cts_filter_make_query_ALL_CONTACT(filter, query, sizeof(query));
+
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               iter->stmt = stmt;
+               break;
+       case CTS_FILTERED_ALL_CONTACT_OSP:
+               iter->i_type = CTS_ITER_OSP;
+
+               cts_filter_make_query_ALL_CONTACT_OSP(filter, query, sizeof(query));
+
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               break;
+       case CTS_FILTERED_ALL_CONTACT_HAD_NUMBER:
+               iter->i_type = CTS_ITER_CONTACTS;
+
+               cts_filter_make_query_ALL_CONTACT_HAD_NUMBER(filter, query, sizeof(query));
+
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               break;
+       case CTS_FILTERED_ALL_CONTACT_HAD_EMAIL:
+               iter->i_type = CTS_ITER_CONTACTS;
+
+               cts_filter_make_query_ALL_CONTACT_HAD_EMAIL(filter, query, sizeof(query));
+
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               break;
+       default:
+               ERR("Invalid parameter : The op_code(%d) is not supported", filter->list_type);
+               return CTS_ERR_ARG_INVALID;
+       }
+       iter->stmt = stmt;
+
+       return CTS_SUCCESS;
+}
+
+API int contacts_svc_get_list_with_filter(CTSfilter *filter, CTSiter **iter)
+{
+       int ret;
+       CTSiter *result;
+
+       retv_if(NULL == filter, CTS_ERR_ARG_NULL);
+       retv_if(NULL == iter, CTS_ERR_ARG_NULL);
+       retvm_if(CTS_FILTER_TYPE_NONE != filter->type && CTS_FILTER_TYPE_STR != filter->type,
+                       CTS_ERR_ARG_INVALID, "Invalid CTSfilter(type = %d)", filter->type);
+
+       result = calloc(1, sizeof(CTSiter));
+       retvm_if(NULL == result, CTS_ERR_OUT_OF_MEMORY, "calloc() Failed");
+
+       if (CTS_FILTER_TYPE_NONE == filter->type) {
+               ret = cts_list_filter_make_query(filter, result);
+               if (ret) {
+                       ERR("cts_list_filter_make_query() Failed(%d)", ret);
+                       free(result);
+                       return ret;
+               }
+       } else if (CTS_FILTER_TYPE_STR == filter->type) {
+               ret = cts_list_str_filter_make_query(filter, result);
+               if (ret) {
+                       ERR("cts_list_str_filter_make_query() Failed(%d)", ret);
+                       free(result);
+                       return ret;
+               }
+       }
+
+       *iter = (CTSiter *)result;
+       INFO(",CTSiter,1");
+       return CTS_SUCCESS;
+}
+
+API int contacts_svc_list_with_filter_foreach(CTSfilter *filter,
+               cts_foreach_fn cb, void *user_data)
+{
+       int ret;
+       CTSiter iter = {0};
+
+       if (CTS_FILTER_TYPE_STR == filter->type) {
+               ret = cts_list_str_filter_make_query(filter, &iter);
+               retvm_if(CTS_SUCCESS != ret, ret, "cts_list_str_filter_make_query() Failed(%d)", ret);
+       } else if (CTS_FILTER_TYPE_NONE == filter->type) {
+               ret = cts_list_filter_make_query(filter, &iter);
+               retvm_if(CTS_SUCCESS != ret, ret, "cts_list_filter_make_query() Failed(%d)", ret);
+       } else {
+               ERR("Invalid CTSfilter(type = %d)", filter->type);
+               return CTS_ERR_ARG_INVALID;
+       }
+
+       cts_foreach_run(&iter, cb, user_data);
+
+       return CTS_SUCCESS;
+}
+
diff --git a/src/cts-list-filter.h b/src/cts-list-filter.h
new file mode 100755 (executable)
index 0000000..a2af59c
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjae Shin <yj99.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#ifndef __CTS_LIST_FILTER_H__
+#define __CTS_LIST_FILTER_H__
+
+#include "cts-list.h"
+
+struct cts_filter {
+       int type;
+       int list_type;
+       char *search_val;
+       bool addrbook_on;
+       bool group_on;
+       bool limit_on;
+       bool offset_on;
+       int addrbook_id;
+       int group_id;
+       int limit;
+       int offset;
+};
+
+//<!--
+
+/**
+ * @defgroup   CONTACTS_SVC_LIST_FILTER List handling with filter
+ * @ingroup    CONTACTS_SVC_LIST
+ * @addtogroup CONTACTS_SVC_LIST_FILTER
+ * @{
+ *
+ * This interface provides methods to handle the List.
+ *
+ * List is handled by iterator. The iterator is same to handle's cursor of Sqlite3.
+ * While an iterator is in use, all attempts to write in this or some other process
+ * will be blocked. Parallel reads are supported.
+ *
+ */
+
+/**
+ * CTSiter is an opaque type, it must be
+ * used via accessor functions.
+ * @see contacts_svc_list_filter_new(), contacts_svc_list_str_filter_new(), contacts_svc_list_filter_free()
+ */
+typedef struct cts_filter CTSfilter;
+
+/**
+ * Use for contacts_svc_list_str_filter_new().
+ */
+typedef enum {
+       CTS_FILTERED_PLOGS_OF_NUMBER = CTS_LIST_PLOGS_OF_NUMBER,/**< #PHONELOGLIST */
+       CTS_FILTERED_CONTACTS_WITH_NAME = CTS_LIST_CONTACTS_WITH_NAME,/**< #CONTACTLIST */
+       CTS_FILTERED_NUMBERINFOS_WITH_NAME = CTS_LIST_NUMBERINFOS_WITH_NAME,/**< #NUMBERLIST */
+       CTS_FILTERED_NUMBERINFOS_WITH_NUM = CTS_LIST_NUMBERINFOS_WITH_NUM,/**< #NUMBERLIST */
+       CTS_FILTERED_EMAILINFOS_WITH_EMAIL= CTS_LIST_EMAILINFOS_WITH_EMAIL,/**< #EMAILLIST */
+}cts_str_filter_op;
+
+/**
+ * Use for contacts_svc_list_filter_new().
+ */
+typedef enum {
+       CTS_FILTERED_ALL_CONTACT,/**< #CONTACTLIST */
+       CTS_FILTERED_ALL_CONTACT_HAD_NUMBER,/**< #CONTACTLIST */
+       CTS_FILTERED_ALL_CONTACT_HAD_EMAIL,/**< #CONTACTLIST */
+       CTS_FILTERED_ALL_CONTACT_OSP = 1000,/**< #OSPLIST */
+}cts_filter_op;
+
+/**
+ * Use for contacts_svc_list_filter_new(), contacts_svc_list_str_filter_new().
+ */
+typedef enum {
+       CTS_LIST_FILTER_NONE, /**< . */
+       CTS_LIST_FILTER_ADDRESBOOK_ID_INT, /**< exclusive with #CTS_LIST_FILTER_GROUP_ID_INT */
+       CTS_LIST_FILTER_GROUP_ID_INT, /**< exclusive with #CTS_LIST_FILTER_ADDRESBOOK_ID_INT */
+       CTS_LIST_FILTER_LIMIT_INT, /**< . */
+       CTS_LIST_FILTER_OFFSET_INT, /**< Offset depends on Limit(#CTS_LIST_FILTER_LIMIT_INT) */
+}cts_filter_type;
+
+/**
+ * Allocate, initialize and return a new contacts service list filter with constraints.
+ * The constaint is composed with the pair of (type, val).
+ * The constaints list should be terminated with #CTS_LIST_FILTER_NONE,
+ * therefore the count of parameter is an odd number.
+ * This should be used for getting filtered list only,
+ * if not, be sure to use contacts_svc_get_list_with_str().
+ *
+ * @param[in] list_type type of list(#cts_str_filter_op)
+ * @param[in] search_value String search value
+ * @param[in] first_type type of first constraint
+ * @return The pointer of New contacts service list filter, NULL on error
+ * @see contacts_svc_list_filter_free()
+ */
+CTSfilter* contacts_svc_list_str_filter_new(cts_str_filter_op list_type,
+   const char *search_value, cts_filter_type first_type, ...);
+
+/**
+ * Allocate, initialize and return a new contacts service list filter with constraints.
+ * The constaint is composed with the pair of (type, val).
+ * The constaints list should be terminated with #CTS_LIST_FILTER_NONE,
+ * therefore the count of parameter is an even number.
+ * This should be used for getting filtered list only,
+ * if not, be sure to use contacts_svc_get_list().
+ *
+ * @param[in] list_type type of list(#cts_filter_op)
+ * @param[in] first_type type of first constraint
+ * @return The pointer of New contacts service list filter, NULL on error
+ * @see contacts_svc_list_filter_free()
+ */
+CTSfilter* contacts_svc_list_filter_new(cts_filter_op list_type, cts_filter_type first_type, ...);
+
+/**
+ * A destructor for contacts service list filter.
+ *
+ * @param[in] filter A contacts service struct
+ * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
+ * @see contacts_svc_list_filter_new(), contacts_svc_list_str_filter_new()
+ */
+int contacts_svc_list_filter_free(CTSfilter *filter);
+
+/**
+ * This function calls cb(#cts_foreach_fn) for each record of list gotten by filter.
+ *
+ * @param[in] filter The filter for searching
+ * @param[in] cb callback function pointer(#cts_foreach_fn)
+ * @param[in] user_data data which is passed to callback function
+ * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
+ */
+int contacts_svc_list_with_filter_foreach(CTSfilter *filter,
+   cts_foreach_fn cb, void *user_data);
+
+/**
+ * This function gets iterator of the gotten data by filter.
+ * \n Obtained iterator should be free using by contacts_svc_iter_remove().
+ *
+ * @param[in] filter The filter for searching
+ * @param[out] iter Point of data iterator to be got
+ * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
+ */
+int contacts_svc_get_list_with_filter(CTSfilter *filter, CTSiter **iter);
+
+/**
+ * @}
+ */
+//-->
+
+#endif //__CTS_LIST_FILTER_H__
+
index c9e0204..a88b059 100755 (executable)
@@ -33,7 +33,7 @@ static inline CTSvalue* cts_iter_get_info_contact(cts_stmt stmt, int type)
        retvm_if(NULL == result, NULL, "contacts_svc_value_new() Failed");
 
        i = 0;
-       result->id = cts_stmt_get_int(stmt, i++);
+       result->person_id = cts_stmt_get_int(stmt, i++);
        lang = cts_stmt_get_int(stmt, i++);
        temp = cts_stmt_get_text(stmt, i++);
        result->first = SAFE_STRDUP(temp);
@@ -41,13 +41,14 @@ static inline CTSvalue* cts_iter_get_info_contact(cts_stmt stmt, int type)
        result->last = SAFE_STRDUP(temp);
        temp = cts_stmt_get_text(stmt, i++);
        result->display = SAFE_STRDUP(temp);
-       result->acc_id = cts_stmt_get_int(stmt, i++);
+       result->addrbook_id = cts_stmt_get_int(stmt, i++);
        temp = cts_stmt_get_text(stmt, i++);
        if (temp) {
                char full_path[CTS_IMG_PATH_SIZE_MAX];
                snprintf(full_path, sizeof(full_path), "%s/%s", CTS_IMAGE_LOCATION, temp);
                result->img_path = strdup(full_path);
        }
+       result->contact_id = cts_stmt_get_int(stmt, i++);
 
        if (CTS_LANG_DEFAULT == lang)
                lang = cts_get_default_language();
@@ -70,6 +71,58 @@ static inline CTSvalue* cts_iter_get_info_contact(cts_stmt stmt, int type)
        return (CTSvalue *)result;
 }
 
+static inline CTSvalue* cts_iter_get_info_osp(cts_stmt stmt)
+{
+       int i, lang;
+       char *temp;
+       osp_list *result;
+
+       result = (osp_list *)contacts_svc_value_new(CTS_VALUE_LIST_OSP);
+       retvm_if(NULL == result, NULL, "contacts_svc_value_new() Failed");
+
+       i = 0;
+       result->person_id = cts_stmt_get_int(stmt, i++);
+       lang = cts_stmt_get_int(stmt, i++);
+       temp = cts_stmt_get_text(stmt, i++);
+       result->first = SAFE_STRDUP(temp);
+       temp = cts_stmt_get_text(stmt, i++);
+       result->last = SAFE_STRDUP(temp);
+       temp = cts_stmt_get_text(stmt, i++);
+       result->display = SAFE_STRDUP(temp);
+       result->addrbook_id = cts_stmt_get_int(stmt, i++);
+       temp = cts_stmt_get_text(stmt, i++);
+       if (temp) {
+               char full_path[CTS_IMG_PATH_SIZE_MAX];
+               snprintf(full_path, sizeof(full_path), "%s/%s", CTS_IMAGE_LOCATION, temp);
+               result->img_path = strdup(full_path);
+       }
+       result->contact_id = cts_stmt_get_int(stmt, i++);
+       result->def_num_type = cts_stmt_get_int(stmt, i++);
+       temp = cts_stmt_get_text(stmt, i++);
+       result->def_num = SAFE_STRDUP(temp);
+       result->def_email_type = cts_stmt_get_int(stmt, i++);
+       temp = cts_stmt_get_text(stmt, i++);
+       result->def_email = SAFE_STRDUP(temp);
+
+       if (CTS_LANG_DEFAULT == lang)
+               lang = cts_get_default_language();
+
+       if (NULL == result->display && result->first && result->last
+                       && CTS_LANG_ENGLISH == lang) {
+               char display[CTS_SQL_MAX_LEN];
+               if (CTS_ORDER_NAME_FIRSTLAST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
+                       snprintf(display, sizeof(display), "%s %s", result->first, result->last);
+               else
+                       snprintf(display, sizeof(display), "%s, %s", result->last, result->first);
+
+               result->display = strdup(display);
+       }
+       temp = cts_stmt_get_text(stmt, i++);
+       result->normalize = SAFE_STRDUP(temp);
+
+       return (CTSvalue *)result;
+}
+
 static inline CTSvalue* cts_iter_get_info_number_email(cts_stmt stmt, int type)
 {
        int i, lang;
@@ -86,7 +139,7 @@ static inline CTSvalue* cts_iter_get_info_number_email(cts_stmt stmt, int type)
                result->v_type = CTS_VALUE_LIST_NUMBERINFO;
 
        i = 0;
-       result->id = cts_stmt_get_int(stmt, i++);
+       result->person_id = cts_stmt_get_int(stmt, i++);
        lang = cts_stmt_get_int(stmt, i++);
        temp = cts_stmt_get_text(stmt, i++);
        result->first = SAFE_STRDUP(temp);
@@ -102,9 +155,9 @@ static inline CTSvalue* cts_iter_get_info_number_email(cts_stmt stmt, int type)
                snprintf(full_path, sizeof(full_path), "%s/%s", CTS_IMAGE_LOCATION, temp);
                result->img_path = strdup(full_path);
        }
-
+       result->contact_id = cts_stmt_get_int(stmt, i++);
        if (CTS_ITER_NUMBERS_EMAILS == type) {
-               result->acc_id = cts_stmt_get_int(stmt, i++);
+               result->addrbook_id = cts_stmt_get_int(stmt, i++);
                temp = cts_stmt_get_text(stmt, i++);
                result->normalize = SAFE_STRDUP(temp);
        }
@@ -142,7 +195,7 @@ static inline CTSvalue* cts_iter_get_info_sdn(cts_stmt stmt, int type)
        return (CTSvalue *)result;
 }
 
-static inline CTSvalue* cts_iter_get_info_change(updated_contact *cursor)
+static inline CTSvalue* cts_iter_get_info_change(updated_record *cursor)
 {
        change_list *result;
 
@@ -152,6 +205,7 @@ static inline CTSvalue* cts_iter_get_info_change(updated_contact *cursor)
        result->changed_type = cursor->type;
        result->id = cursor->id;
        result->changed_ver = cursor->ver;
+       result->addressbook_id = cursor->addressbook_id;
 
        return (CTSvalue *)result;
 }
@@ -215,6 +269,17 @@ static inline CTSvalue* cts_iter_get_info_plog(int type, cts_stmt stmt)
                result->extra_data2 = SAFE_STRDUP(temp);
                result->related_id = cts_stmt_get_int(stmt, cnt++);
                break;
+       case CTS_ITER_PLOGS_OF_PERSON_ID:
+               result->id = cts_stmt_get_int(stmt, cnt++);
+               result->log_type = cts_stmt_get_int(stmt, cnt++);
+               result->log_time = cts_stmt_get_int(stmt, cnt++);
+               result->extra_data1 = cts_stmt_get_int(stmt, cnt++);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->extra_data2 = SAFE_STRDUP(temp);
+               result->related_id = cts_stmt_get_int(stmt, cnt++);
+               temp = cts_stmt_get_text(stmt, cnt++);
+               result->number = SAFE_STRDUP(temp);
+               break;
        default:
                ERR("Invalid parameter : The type(%d) is unknown type", type);
                contacts_svc_value_free((CTSvalue*)result);
@@ -258,6 +323,8 @@ static inline CTSvalue* cts_iter_get_info_group(cts_stmt stmt)
        result->id = cts_stmt_get_int(stmt, 0);
        result->addrbook_id = cts_stmt_get_int(stmt, 1);
        result->name = SAFE_STRDUP(cts_stmt_get_text(stmt, 2));
+       result->ringtone_path = SAFE_STRDUP(cts_stmt_get_text(stmt, 3));
+       result->img_loaded = false; //It will load at cts_value_get_str_group()
 
        return (CTSvalue *)result;
 }
@@ -336,12 +403,13 @@ API CTSvalue* contacts_svc_iter_get_info(CTSiter *iter)
                result = cts_iter_get_info_sdn(iter->stmt, iter->i_type);
                retvm_if(NULL == result, NULL, "cts_iter_get_info_number() Failed");
                break;
-       case CTS_ITER_UPDATED_CONTACTS_AFTER_VER:
+       case CTS_ITER_UPDATED_INFO_AFTER_VER:
                result = cts_iter_get_info_change(iter->info->cursor);
                retvm_if(NULL == result, NULL, "cts_iter_get_info_change() Failed");
                break;
        case CTS_ITER_GROUPING_PLOG:
        case CTS_ITER_PLOGS_OF_NUMBER:
+       case CTS_ITER_PLOGS_OF_PERSON_ID:
                result = cts_iter_get_info_plog(iter->i_type, iter->stmt);
                retvm_if(NULL == result, NULL, "cts_iter_get_info_plog() Failed");
                break;
@@ -366,6 +434,9 @@ API CTSvalue* contacts_svc_iter_get_info(CTSiter *iter)
        case CTS_ITER_PLOGNUMBERS_WITH_NUM:
                result = (CTSvalue*)(SAFE_STRDUP(cts_stmt_get_text(iter->stmt, 0)));
                break;
+       case CTS_ITER_OSP:
+               result = cts_iter_get_info_osp(iter->stmt);
+               break;
        default:
                ERR("Invalid parameter : The iter(%d) has unknown type", iter->i_type);
                return NULL;
index 31aa8b1..727fb09 100755 (executable)
 #include "cts-types.h"
 #include "cts-normalize.h"
 #include "cts-favorite.h"
+#include "cts-restriction.h"
 #include "cts-list.h"
 
 #define CTS_MALLOC_DEFAULT_NUM 256 //4Kbytes
 #define CTS_OFTEN_USED_NUM 1
 
-static inline updated_contact* cts_updated_contact_add_mempool(void)
+static inline updated_record* cts_updated_info_add_mempool(void)
 {
        int i;
-       updated_contact *mempool;
+       updated_record *mempool;
 
-       mempool = calloc(CTS_MALLOC_DEFAULT_NUM, sizeof(updated_contact));
+       mempool = calloc(CTS_MALLOC_DEFAULT_NUM, sizeof(updated_record));
        for (i=0;i<CTS_MALLOC_DEFAULT_NUM-1;i++)
                mempool[i].next = &mempool[i+1];
        return mempool;
 }
 
-static inline int cts_updated_contact_free_mempool(updated_contact *mempool)
+static inline int cts_updated_contact_free_mempool(updated_record *mempool)
 {
-       updated_contact *memseg, *tmp;
+       updated_record *memseg, *tmp;
 
        retv_if(NULL == mempool, CTS_ERR_ARG_NULL);
 
@@ -64,7 +65,7 @@ API int contacts_svc_iter_next(CTSiter *iter)
        retvm_if(iter->i_type <= CTS_ITER_NONE || CTS_ITER_MAX <= iter->i_type,
                        CTS_ERR_ARG_INVALID, "iter is Invalid(type=%d", iter->i_type);
 
-       if (CTS_ITER_UPDATED_CONTACTS_AFTER_VER == iter->i_type)
+       if (CTS_ITER_UPDATED_INFO_AFTER_VER == iter->i_type)
        {
                retv_if(NULL == iter->info, CTS_ERR_ARG_INVALID);
 
@@ -82,13 +83,14 @@ API int contacts_svc_iter_next(CTSiter *iter)
        else
        {
                ret = cts_stmt_step(iter->stmt);
-               if (CTS_TRUE != ret)
-               {
+               if (CTS_TRUE != ret) {
                        if (CTS_SUCCESS != ret)
                                ERR("cts_stmt_step() Failed(%d)", ret);
+                       else
+                               ret = CTS_ERR_FINISH_ITER;
                        cts_stmt_finalize(iter->stmt);
                        iter->stmt = NULL;
-                       return CTS_ERR_FINISH_ITER;
+                       return ret;
                }
        }
        return CTS_SUCCESS;
@@ -100,7 +102,7 @@ API int contacts_svc_iter_remove(CTSiter *iter)
        retvm_if(iter->i_type <= CTS_ITER_NONE || CTS_ITER_MAX <= iter->i_type,
                        CTS_ERR_ARG_INVALID, "iter is Invalid(type=%d", iter->i_type);
 
-       if (CTS_ITER_UPDATED_CONTACTS_AFTER_VER == iter->i_type) {
+       if (CTS_ITER_UPDATED_INFO_AFTER_VER == iter->i_type) {
                retv_if(NULL == iter->info, CTS_ERR_ARG_INVALID);
                if (iter->info->head)
                        cts_updated_contact_free_mempool(iter->info->head);
@@ -111,13 +113,14 @@ API int contacts_svc_iter_remove(CTSiter *iter)
        }
 
        free(iter);
+       INFO(",CTSiter,0");
        return CTS_SUCCESS;
 }
 
 static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
 {
        cts_stmt stmt = NULL;
-       const char *display;
+       const char *display, *data;
        char query[CTS_SQL_MAX_LEN] = {0};
 
        retv_if(NULL == iter, CTS_ERR_ARG_NULL);
@@ -125,6 +128,11 @@ static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
        iter->i_type = CTS_ITER_NONE;
        iter->stmt = NULL;
 
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
        switch (op_code)
        {
        case CTS_LIST_ALL_CONTACT:
@@ -136,11 +144,11 @@ static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
                        display = CTS_SCHEMA_DATA_NAME_LOOKUP;
 
                snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, data1, data2, data3, data5, B.addrbook_id, B.image0, %s "
-                               "FROM %s A, %s B ON A.contact_id = B.contact_id "
-                               "WHERE A.datatype = %d "
+                               "SELECT B.person_id, data1, data2, data3, data5, B.addrbook_id, B.image0, B.person_id, %s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
+                               "WHERE A.datatype = %d AND B.person_id = B.contact_id "
                                "ORDER BY A.data1, A.%s",
-                               display, CTS_TABLE_DATA, CTS_TABLE_CONTACTS,
+                               display, data, CTS_TABLE_CONTACTS,
                                CTS_DATA_NAME, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
@@ -159,7 +167,7 @@ static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
                break;
        case CTS_LIST_ALL_GROUP:
                iter->i_type = CTS_ITER_GROUPS;
-               snprintf(query, sizeof(query), "SELECT group_id, addrbook_id, group_name "
+               snprintf(query, sizeof(query), "SELECT group_id, addrbook_id, group_name, ringtone "
                                "FROM %s ORDER BY addrbook_id, group_name COLLATE NOCASE",
                                CTS_TABLE_GROUPS);
 
@@ -189,14 +197,16 @@ static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
                                "NOT EXISTS (SELECT id FROM %s "
                                "WHERE datatype = %d AND contact_id = A.related_id "
                                "AND A.normal_num = data3)) "
+                               "WHERE A.log_type < %d "
                                "GROUP BY A.id) C "
                                "LEFT JOIN (SELECT D.contact_id, data1, data2, data3, data5, image0 "
                                "FROM %s D, %s E ON D.datatype = %d AND D.contact_id = E.contact_id) F "
                                "ON C.contact_id = F.contact_id "
                                "GROUP BY F.data2, F.data3, F.data5, C.number "
                                "ORDER BY C.log_time DESC",
-                               CTS_TABLE_PHONELOGS, CTS_TABLE_DATA, CTS_DATA_NUMBER, CTS_TABLE_DATA,
-                               CTS_DATA_NUMBER, CTS_TABLE_DATA, CTS_TABLE_CONTACTS, CTS_DATA_NAME);
+                               CTS_TABLE_PHONELOGS, data, CTS_DATA_NUMBER, data,
+                               CTS_DATA_NUMBER, CTS_PLOG_TYPE_EMAIL_RECEIVED,
+                               data, CTS_TABLE_CONTACTS, CTS_DATA_NAME);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
                iter->stmt = stmt;
@@ -213,15 +223,16 @@ static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
                                "(A.related_id = B.contact_id OR A.related_id IS NULL OR "
                                "NOT EXISTS (SELECT id FROM %s WHERE datatype = %d AND contact_id = A.related_id "
                                "AND A.normal_num = data3)) "
-                               "WHERE A.log_type >= %d "
+                               "WHERE (A.log_type BETWEEN %d AND %d) "
                                "GROUP BY A.id) C "
                                "LEFT JOIN (SELECT D.contact_id, data1, data2, data3, data5, image0 "
                                "FROM %s D, %s E ON D.datatype = %d AND D.contact_id = E.contact_id) F "
                                "ON C.contact_id = F.contact_id "
                                "GROUP BY F.data2, F.data3, F.data5, C.number "
                                "ORDER BY C.log_time DESC",
-                               CTS_TABLE_PHONELOGS, CTS_TABLE_DATA, CTS_DATA_NUMBER, CTS_TABLE_DATA, CTS_DATA_NUMBER,
-                               CTS_PLOG_TYPE_MMS_INCOMMING, CTS_TABLE_DATA, CTS_TABLE_CONTACTS, CTS_DATA_NAME);
+                               CTS_TABLE_PHONELOGS, data, CTS_DATA_NUMBER, data, CTS_DATA_NUMBER,
+                               CTS_PLOG_TYPE_MMS_INCOMMING, CTS_PLOG_TYPE_MMS_BLOCKED,
+                               data, CTS_TABLE_CONTACTS, CTS_DATA_NAME);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
                iter->stmt = stmt;
@@ -245,8 +256,8 @@ static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
                                "ON C.contact_id = F.contact_id "
                                "GROUP BY F.data2, F.data3, F.data5, C.number "
                                "ORDER BY C.log_time DESC",
-                               CTS_TABLE_PHONELOGS, CTS_TABLE_DATA, CTS_DATA_NUMBER, CTS_TABLE_DATA, CTS_DATA_NUMBER,
-                               CTS_PLOG_TYPE_MMS_INCOMMING, CTS_TABLE_DATA, CTS_TABLE_CONTACTS, CTS_DATA_NAME);
+                               CTS_TABLE_PHONELOGS, data, CTS_DATA_NUMBER, data, CTS_DATA_NUMBER,
+                               CTS_PLOG_TYPE_MMS_INCOMMING, data, CTS_TABLE_CONTACTS, CTS_DATA_NAME);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
                iter->stmt = stmt;
@@ -264,13 +275,41 @@ static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
                                "NOT EXISTS (SELECT id FROM %s "
                                "WHERE datatype = %d AND contact_id = A.related_id "
                                "AND A.normal_num = data3)) "
+                               "WHERE A.log_type < %d "
                                "GROUP BY A.id) C "
                                "LEFT JOIN (SELECT D.contact_id, data1, data2, data3, data5, image0 "
                                "FROM %s D, %s E ON D.datatype = %d AND D.contact_id = E.contact_id) F "
                                "ON C.contact_id = F.contact_id "
                                "ORDER BY C.log_time DESC",
-                               CTS_TABLE_PHONELOGS, CTS_TABLE_DATA, CTS_DATA_NUMBER, CTS_TABLE_DATA,
-                               CTS_DATA_NUMBER, CTS_TABLE_DATA, CTS_TABLE_CONTACTS, CTS_DATA_NAME);
+                               CTS_TABLE_PHONELOGS, data, CTS_DATA_NUMBER, data,
+                               CTS_DATA_NUMBER, CTS_PLOG_TYPE_EMAIL_RECEIVED,
+                               data, CTS_TABLE_CONTACTS, CTS_DATA_NAME);
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               iter->stmt = stmt;
+               break;
+       case CTS_LIST_ALL_EMAIL_PLOG:
+               iter->i_type = CTS_ITER_GROUPING_PLOG;
+               snprintf(query, sizeof(query),
+                               "SELECT C.id, F.data1, F.data2, F.data3, F.data5, F.image0, C.number, "
+                               "C.log_type, C.log_time, C.data1, C.data2, C.contact_id, C.number_type "
+                               "FROM "
+                               "(SELECT A.id, A.number, A.log_type, A.log_time, A.data1, A.data2, "
+                               "MIN(B.contact_id) contact_id, B.data1 number_type "
+                               "FROM %s A LEFT JOIN %s B ON B.datatype = %d AND A.number = B.data2 AND "
+                               "(A.related_id = B.contact_id OR A.related_id IS NULL OR "
+                               "NOT EXISTS (SELECT id FROM %s "
+                               "WHERE datatype = %d AND contact_id = A.related_id "
+                               "AND A.number = data2)) "
+                               "WHERE A.log_type >= %d "
+                               "GROUP BY A.id) C "
+                               "LEFT JOIN (SELECT D.contact_id, data1, data2, data3, data5, image0 "
+                               "FROM %s D, %s E ON D.datatype = %d AND D.contact_id = E.contact_id) F "
+                               "ON C.contact_id = F.contact_id "
+                               "ORDER BY C.log_time DESC",
+                               CTS_TABLE_PHONELOGS, data, CTS_DATA_EMAIL, data, CTS_DATA_EMAIL,
+                               CTS_PLOG_TYPE_EMAIL_RECEIVED,
+                               data, CTS_TABLE_CONTACTS, CTS_DATA_NAME);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
                iter->stmt = stmt;
@@ -288,15 +327,41 @@ static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
                                "NOT EXISTS (SELECT id FROM %s "
                                "WHERE datatype = %d AND contact_id = A.related_id "
                                "AND A.normal_num = data3)) "
+                               "WHERE (A.log_type BETWEEN %d AND %d) "
+                               "GROUP BY A.id) C "
+                               "LEFT JOIN (SELECT D.contact_id, data1, data2, data3, data5, image0 "
+                               "FROM %s D, %s E ON D.datatype = %d AND D.contact_id = E.contact_id) F "
+                               "ON C.contact_id = F.contact_id "
+                               "ORDER BY C.log_time DESC",
+                               CTS_TABLE_PHONELOGS, data, CTS_DATA_NUMBER, data, CTS_DATA_NUMBER,
+                               CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN, CTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN,
+                               data, CTS_TABLE_CONTACTS, CTS_DATA_NAME);
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               iter->stmt = stmt;
+               break;
+       case CTS_LIST_ALL_UNSEEN_MISSED_CALL:
+               iter->i_type = CTS_ITER_GROUPING_PLOG;
+               snprintf(query, sizeof(query),
+                               "SELECT C.id, F.data1, F.data2, F.data3, F.data5, F.image0, C.number, "
+                               "C.log_type, C.log_time, C.data1, C.data2, C.contact_id, C.number_type "
+                               "FROM "
+                               "(SELECT A.id, A.number, A.log_type, A.log_time, A.data1, A.data2, "
+                               "MIN(B.contact_id) contact_id, B.data1 number_type "
+                               "FROM %s A LEFT JOIN %s B ON B.datatype = %d AND A.normal_num = B.data3 AND "
+                               "(A.related_id = B.contact_id OR A.related_id IS NULL OR "
+                               "NOT EXISTS (SELECT id FROM %s "
+                               "WHERE datatype = %d AND contact_id = A.related_id "
+                               "AND A.normal_num = data3)) "
                                "WHERE (A.log_type = %d OR A.log_type = %d) "
                                "GROUP BY A.id) C "
                                "LEFT JOIN (SELECT D.contact_id, data1, data2, data3, data5, image0 "
                                "FROM %s D, %s E ON D.datatype = %d AND D.contact_id = E.contact_id) F "
                                "ON C.contact_id = F.contact_id "
                                "ORDER BY C.log_time DESC",
-                               CTS_TABLE_PHONELOGS, CTS_TABLE_DATA, CTS_DATA_NUMBER, CTS_TABLE_DATA, CTS_DATA_NUMBER,
+                               CTS_TABLE_PHONELOGS, data, CTS_DATA_NUMBER, data, CTS_DATA_NUMBER,
                                CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN, CTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN,
-                               CTS_TABLE_DATA, CTS_TABLE_CONTACTS, CTS_DATA_NAME);
+                               data, CTS_TABLE_CONTACTS, CTS_DATA_NAME);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
                iter->stmt = stmt;
@@ -304,13 +369,13 @@ static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
        case CTS_LIST_ALL_NUMBER_FAVORITE:
                iter->i_type = CTS_ITER_ALL_NUM_FAVORITE;
                snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, D.image0, "
+                               "SELECT D.person_id, A.data1, A.data2, A.data3, A.data5, D.image0, "
                                "B.id, B.data1, B.data2 "
                                "FROM %s A, %s B, %s C, %s D "
-                               "ON A.contact_id = B.contact_id AND B.id = C.related_id AND A.contact_id = D.contact_id "
-                               "WHERE A.datatype = %d AND B.datatype = %d AND C.type = %d "
+                               "ON A.contact_id = B.contact_id AND B.id = C.related_id AND A.contact_id = D.person_id "
+                               "WHERE A.datatype = %d AND B.datatype = %d AND C.type = %d AND D.person_id = D.contact_id "
                                "ORDER BY C.favorite_prio",
-                               CTS_TABLE_DATA, CTS_TABLE_DATA, CTS_TABLE_FAVORITES, CTS_TABLE_CONTACTS,
+                               data, data, CTS_TABLE_FAVORITES, CTS_TABLE_CONTACTS,
                                CTS_DATA_NAME, CTS_DATA_NUMBER, CTS_FAVOR_NUMBER);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
@@ -319,13 +384,43 @@ static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
        case CTS_LIST_ALL_CONTACT_FAVORITE:
                iter->i_type = CTS_ITER_ALL_CONTACT_FAVORITE;
                snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, C.image0, B.id "
+                               "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, C.image0, B.id "
+                               "FROM %s A, %s B, %s C "
+                               "ON A.contact_id = B.related_id AND A.contact_id = C.person_id "
+                               "WHERE A.datatype = %d AND B.type = %d AND C.person_id = C.contact_id "
+                               "ORDER BY B.favorite_prio",
+                               data, CTS_TABLE_FAVORITES, CTS_TABLE_CONTACTS,
+                               CTS_DATA_NAME, CTS_FAVOR_PERSON);
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               iter->stmt = stmt;
+               break;
+       case CTS_LIST_ALL_CONTACT_FAVORITE_HAD_NUMBER:
+               iter->i_type = CTS_ITER_ALL_CONTACT_FAVORITE;
+               snprintf(query, sizeof(query),
+                               "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, C.image0, B.id "
                                "FROM %s A, %s B, %s C "
-                               "ON A.contact_id = B.related_id AND A.contact_id = C.contact_id "
-                               "WHERE A.datatype = %d AND B.type = %d "
+                               "ON A.contact_id = B.related_id AND A.contact_id = C.person_id "
+                               "WHERE A.datatype = %d AND B.type = %d AND C.default_num > 0 "
+                               "GROUP BY C.person_id "
                                "ORDER BY B.favorite_prio",
-                               CTS_TABLE_DATA, CTS_TABLE_FAVORITES, CTS_TABLE_CONTACTS,
-                               CTS_DATA_NAME, CTS_FAVOR_CONTACT);
+                               data, CTS_TABLE_FAVORITES, CTS_TABLE_CONTACTS,
+                               CTS_DATA_NAME, CTS_FAVOR_PERSON);
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               iter->stmt = stmt;
+               break;
+       case CTS_LIST_ALL_CONTACT_FAVORITE_HAD_EMAIL:
+               iter->i_type = CTS_ITER_ALL_CONTACT_FAVORITE;
+               snprintf(query, sizeof(query),
+                               "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, C.image0, B.id "
+                               "FROM %s A, %s B, %s C "
+                               "ON A.contact_id = B.related_id AND A.contact_id = C.person_id "
+                               "WHERE A.datatype = %d AND B.type = %d AND C.default_email > 0 "
+                               "GROUP BY C.person_id "
+                               "ORDER BY B.favorite_prio",
+                               data, CTS_TABLE_FAVORITES, CTS_TABLE_CONTACTS,
+                               CTS_DATA_NAME, CTS_FAVOR_PERSON);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
                iter->stmt = stmt;
@@ -333,13 +428,13 @@ static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
        case CTS_LIST_ALL_SPEEDDIAL:
                iter->i_type = CTS_ITER_ALL_SPEEDDIAL;
                snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, D.image0, "
+                               "SELECT D.contact_id, A.data1, A.data2, A.data3, A.data5, D.image0, "
                                "B.id, B.data1, B.data2, C.speed_num "
                                "FROM %s A, %s B, %s C, %s D "
                                "WHERE A.datatype = %d AND B.datatype = %d AND B.id = C.number_id "
-                               "AND A.contact_id = B.contact_id AND A.contact_id = D.contact_id "
+                               "AND A.contact_id = B.contact_id AND A.contact_id = D.person_id "
                                "ORDER BY C.speed_num",
-                               CTS_TABLE_DATA, CTS_TABLE_DATA, CTS_TABLE_SPEEDDIALS,
+                               data, data, CTS_TABLE_SPEEDDIALS,
                                CTS_TABLE_CONTACTS, CTS_DATA_NAME, CTS_DATA_NUMBER);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
@@ -362,11 +457,12 @@ static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
                        display = CTS_SCHEMA_DATA_NAME_LOOKUP;
 
                snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, B.addrbook_id, B.image0, A.%s "
-                               "FROM %s A, %s B ON A.contact_id = B.contact_id "
+                               "SELECT B.person_id, A.data1, A.data2, A.data3, A.data5, B.addrbook_id, B.image0, B.contact_id, A.%s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
                                "WHERE A.datatype = %d AND B.default_num > 0 "
+                               "GROUP BY B.person_id "
                                "ORDER BY A.data1, A.%s",
-                               display, CTS_TABLE_DATA, CTS_TABLE_CONTACTS, CTS_DATA_NAME, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+                               display, data, CTS_TABLE_CONTACTS, CTS_DATA_NAME, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
                iter->stmt = stmt;
@@ -379,11 +475,12 @@ static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
                        display = CTS_SCHEMA_DATA_NAME_LOOKUP;
 
                snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, B.addrbook_id, B.image0, A.%s "
-                               "FROM %s A, %s B ON A.contact_id = B.contact_id "
+                               "SELECT B.person_id, A.data1, A.data2, A.data3, A.data5, B.addrbook_id, B.image0, B.contact_id, A.%s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
                                "WHERE A.datatype = %d AND B.default_email > 0 "
+                               "GROUP BY B.person_id "
                                "ORDER BY A.data1, A.%s",
-                               display, CTS_TABLE_DATA, CTS_TABLE_CONTACTS, CTS_DATA_NAME, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+                               display, data, CTS_TABLE_CONTACTS, CTS_DATA_NAME, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
                iter->stmt = stmt;
@@ -397,12 +494,12 @@ static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
                        display = CTS_SCHEMA_DATA_NAME_LOOKUP;
 
                snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0, C.addrbook_id, A.%s "
+                               "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0, C.contact_id, C.addrbook_id, A.%s "
                                "FROM %s A, %s B, %s C "
-                               "ON A.contact_id = B.contact_id AND A.contact_id = C.contact_id "
+                               "ON A.contact_id = B.contact_id AND A.contact_id = C.person_id "
                                "WHERE A.datatype = %d AND (B.datatype = %d OR B.datatype = %d) "
                                "ORDER BY A.data1, A.%s",
-                               display, CTS_TABLE_DATA, CTS_TABLE_DATA, CTS_TABLE_CONTACTS,
+                               display, data, data, CTS_TABLE_CONTACTS,
                                CTS_DATA_NAME, CTS_DATA_NUMBER, CTS_DATA_EMAIL, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
@@ -417,12 +514,11 @@ static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
                        display = CTS_SCHEMA_DATA_NAME_LOOKUP;
 
                snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, data1, data2, data3, data5, A.addrbook_id, A.image0, %s "
-                               "FROM %s A, %s B "
+                               "SELECT A.person_id, data1, data2, data3, data5, C.addrbook_id, C.image0, C.person_id, %s "
+                               "FROM %s A, %s B, %s C ON A.person_id = B.contact_id AND B.contact_id = C.contact_id "
                                "WHERE A.outgoing_count > %d AND B.datatype = %d "
-                               "AND B.contact_id = A.contact_id "
                                "ORDER BY A.outgoing_count DESC, data1, %s",
-                               display, CTS_TABLE_CONTACTS, CTS_TABLE_DATA,
+                               display, CTS_TABLE_PERSONS, data, CTS_TABLE_CONTACTS,
                                CTS_OFTEN_USED_NUM, CTS_DATA_NAME, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
@@ -437,12 +533,12 @@ static inline int cts_get_list(cts_get_list_op op_code, CTSiter *iter)
                        display = CTS_SCHEMA_DATA_NAME_LOOKUP;
 
                snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0, C.addrbook_id, A.%s "
+                               "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0, C.contact_id, C.addrbook_id, A.%s "
                                "FROM %s A, %s B, %s C "
-                               "ON A.contact_id = B.contact_id AND A.contact_id = C.contact_id "
-                               "WHERE A.datatype = %d AND (B.datatype = %d) "
+                               "ON A.contact_id = B.contact_id AND A.contact_id = C.person_id "
+                               "WHERE A.datatype = %d AND B.datatype = %d "
                                "ORDER BY A.data1, A.%s",
-                               display, CTS_TABLE_DATA, CTS_TABLE_DATA, CTS_TABLE_CONTACTS,
+                               display, data, data, CTS_TABLE_CONTACTS,
                                CTS_DATA_NAME, CTS_DATA_NUMBER, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
@@ -474,6 +570,7 @@ API int contacts_svc_get_list(cts_get_list_op op_code, CTSiter **iter)
        }
 
        *iter = (CTSiter *)result;
+       INFO(",CTSiter,1");
        return CTS_SUCCESS;
 }
 
@@ -482,7 +579,7 @@ static inline int cts_get_list_with_str(cts_get_list_str_op op_code,
 {
        int ret;
        cts_stmt stmt = NULL;
-       const char *display;
+       const char *display, *data;
        char query[CTS_SQL_MAX_LEN] = {0};
        char remake_val[CTS_SQL_MIN_LEN];
 
@@ -496,6 +593,11 @@ static inline int cts_get_list_with_str(cts_get_list_str_op op_code,
        retvm_if(NULL == search_value && CTS_LIST_PLOGS_OF_NUMBER != op_code,
                        CTS_ERR_ARG_NULL, "The search_value is NULL");
 
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
        switch ((int)op_code)
        {
        case CTS_LIST_PLOGS_OF_NUMBER:
@@ -510,12 +612,13 @@ static inline int cts_get_list_with_str(cts_get_list_str_op op_code,
                                        "WHERE A.number = ? "
                                        "GROUP BY A.id "
                                        "ORDER BY A.log_time DESC",
-                                       CTS_TABLE_PHONELOGS, CTS_TABLE_DATA, CTS_DATA_NUMBER, CTS_TABLE_DATA, CTS_DATA_NUMBER);
+                                       CTS_TABLE_PHONELOGS, data, CTS_DATA_NUMBER, data, CTS_DATA_NUMBER);
                }
                else {
                        snprintf(query, sizeof(query),
                                        "SELECT id, log_type, log_time, data1, data2, NULL "
-                                       "FROM %s WHERE number ISNULL ORDER BY id DESC", CTS_TABLE_PHONELOGS);
+                                       "FROM %s WHERE number ISNULL AND log_type < %d ORDER BY id DESC",
+                                       CTS_TABLE_PHONELOGS, CTS_PLOG_TYPE_EMAIL_RECEIVED);
                }
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
@@ -526,7 +629,7 @@ static inline int cts_get_list_with_str(cts_get_list_str_op op_code,
 
                        normal_num = cts_normalize_number(remake_val);
                        cts_stmt_bind_copy_text(stmt, 1, normal_num, strlen(normal_num));
-                       cts_stmt_bind_copy_text(stmt, 2, remake_val, strlen(remake_val));
+                       cts_stmt_bind_copy_text(stmt, 2, search_value, strlen(search_value));
                }
                iter->stmt = stmt;
                break;
@@ -545,11 +648,11 @@ static inline int cts_get_list_with_str(cts_get_list_str_op op_code,
                        display = CTS_SCHEMA_DATA_NAME_LOOKUP;
 
                snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, data1, data2, data3, data5, B.addrbook_id, B.image0 "
+                               "SELECT B.person_id, data1, data2, data3, data5, B.addrbook_id, B.image0, B.contact_id "
                                "FROM %s A, %s B ON A.contact_id = B.contact_id "
                                "WHERE datatype = %d AND %s LIKE ('%%' || ? || '%%') "
                                "ORDER BY data1, %s",
-                               CTS_TABLE_DATA, CTS_TABLE_CONTACTS, CTS_DATA_NAME, display, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+                               data, CTS_TABLE_CONTACTS, CTS_DATA_NAME, display, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
                cts_stmt_bind_copy_text(stmt, 1, remake_val, strlen(remake_val));
@@ -570,12 +673,12 @@ static inline int cts_get_list_with_str(cts_get_list_str_op op_code,
                        display = CTS_SCHEMA_DATA_NAME_LOOKUP;
 
                snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0 "
+                               "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0, C.contact_id "
                                "FROM %s A, %s B, %s C "
-                               "ON A.contact_id = B.contact_id AND A.contact_id = C.contact_id "
+                               "ON A.contact_id = C.person_id AND B.contact_id = C.contact_id "
                                "WHERE A.datatype = %d AND B.datatype = %d AND A.%s LIKE ('%%' || ? || '%%') "
                                "ORDER BY A.data1, A.%s",
-                               CTS_TABLE_DATA, CTS_TABLE_DATA, CTS_TABLE_CONTACTS,
+                               data, data, CTS_TABLE_CONTACTS,
                                CTS_DATA_NAME, CTS_DATA_NUMBER, display, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
 
                stmt = cts_query_prepare(query);
@@ -587,12 +690,12 @@ static inline int cts_get_list_with_str(cts_get_list_str_op op_code,
                iter->i_type = CTS_ITER_NUMBERINFOS;
 
                snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0 "
+                               "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0, C.contact_id "
                                "FROM %s A, %s B, %s C "
-                               "ON A.contact_id = B.contact_id AND A.contact_id = C.contact_id "
+                               "ON A.contact_id = C.person_id AND B.contact_id = C.contact_id "
                                "WHERE A.datatype = %d AND B.datatype = %d AND B.data2 LIKE ('%%' || ? || '%%') "
                                "ORDER BY A.data1, A.%s",
-                               CTS_TABLE_DATA, CTS_TABLE_DATA, CTS_TABLE_CONTACTS,
+                               data, data, CTS_TABLE_CONTACTS,
                                CTS_DATA_NAME, CTS_DATA_NUMBER, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
 
                stmt = cts_query_prepare(query);
@@ -603,12 +706,12 @@ static inline int cts_get_list_with_str(cts_get_list_str_op op_code,
        case CTS_LIST_EMAILINFOS_WITH_EMAIL:
                iter->i_type = CTS_ITER_EMAILINFOS_WITH_EMAIL;
                snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0 "
+                               "SELECT C.person_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0, C.contact_id "
                                "FROM %s A, %s B, %s C "
-                               "ON A.contact_id = B.contact_id AND A.contact_id = C.contact_id "
+                               "ON A.contact_id = C.person_id AND B.contact_id = C.contact_id "
                                "WHERE A.datatype = %d AND B.datatype = %d AND B.data2 LIKE ('%%' || ? || '%%') "
                                "ORDER BY A.data1, A.%s",
-                               CTS_TABLE_DATA, CTS_TABLE_DATA, CTS_TABLE_CONTACTS,
+                               data, data, CTS_TABLE_CONTACTS,
                                CTS_DATA_NAME, CTS_DATA_EMAIL, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
@@ -620,7 +723,7 @@ static inline int cts_get_list_with_str(cts_get_list_str_op op_code,
                                CTS_ERR_ARG_INVALID, "search_value is too long");
                iter->i_type = CTS_ITER_PLOGNUMBERS_WITH_NUM;
                snprintf(query, sizeof(query),
-                               "SELECT number FROM %s WHERE number LIKE '%%%s%%' GROUP BY number",
+                               "SELECT number FROM %s WHERE number LIKE '%%%s%%' AND normal_num NOTNULL GROUP BY number",
                                CTS_TABLE_PHONELOGS, search_value);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
@@ -654,6 +757,7 @@ API int contacts_svc_get_list_with_str(cts_get_list_str_op op_code,
        }
 
        *iter = (CTSiter *)result;
+       INFO(",CTSiter,1");
        return CTS_SUCCESS;
 }
 
@@ -661,7 +765,7 @@ static inline int cts_get_list_with_int(cts_get_list_int_op op_code,
                unsigned int search_value, CTSiter *iter)
 {
        cts_stmt stmt = NULL;
-       const char *display;
+       const char *display, *data;
        char query[CTS_SQL_MAX_LEN] = {0};
 
        retv_if(NULL == iter, CTS_ERR_ARG_NULL);
@@ -673,17 +777,22 @@ static inline int cts_get_list_with_int(cts_get_list_int_op op_code,
        else
                display = CTS_SCHEMA_DATA_NAME_LOOKUP;
 
-       switch (op_code)
-       {
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
+       switch (op_code) {
        case CTS_LIST_MEMBERS_OF_GROUP_ID:
                iter->i_type = CTS_ITER_CONTACTS;
                snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, data1, data2, data3, data5, B.addrbook_id, B.image0, %s "
-                               "FROM %s A, %s B WHERE datatype = %d AND A.contact_id IN "
+                               "SELECT B.person_id, data1, data2, data3, data5, B.addrbook_id, B.image0, B.contact_id, %s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
+                               "WHERE datatype = %d AND B.contact_id IN "
                                "(SELECT contact_id FROM %s WHERE group_id = %d) "
-                               "AND A.contact_id = B.contact_id "
+                               "GROUP BY B.person_id "
                                "ORDER BY data1, %s",
-                               display, CTS_TABLE_DATA, CTS_TABLE_CONTACTS, CTS_DATA_NAME,
+                               display, data, CTS_TABLE_CONTACTS, CTS_DATA_NAME,
                                CTS_TABLE_GROUPING_INFO, search_value, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
@@ -692,15 +801,15 @@ static inline int cts_get_list_with_int(cts_get_list_int_op op_code,
        case CTS_LIST_NO_GROUP_MEMBERS_OF_ADDRESSBOOK_ID:
                iter->i_type = CTS_ITER_CONTACTS;
                snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, data1, data2, data3, data5, A.addrbook_id, A.image0, %s "
-                               "FROM %s A, %s B ON A.contact_id = B.contact_id "
-                               "WHERE A.addrbook_id = %d AND NOT EXISTS "
-                               "(SELECT contact_id FROM %s WHERE contact_id=A.contact_id LIMIT 1) "
-                               "AND datatype = %d "
+                               "SELECT B.person_id, data1, data2, data3, data5, B.addrbook_id, B.image0, B.contact_id, %s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
+                               "WHERE datatype = %d AND B.addrbook_id = %d AND NOT EXISTS "
+                               "(SELECT contact_id FROM %s WHERE contact_id=B.contact_id LIMIT 1) "
+                               "GROUP BY B.person_id "
                                "ORDER BY data1, %s",
-                               display, CTS_TABLE_CONTACTS, CTS_TABLE_DATA,
-                               search_value, CTS_TABLE_GROUPING_INFO, CTS_DATA_NAME,
-                               CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+                               display, data, CTS_TABLE_CONTACTS,
+                               CTS_DATA_NAME, search_value,
+                               CTS_TABLE_GROUPING_INFO, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
 
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
@@ -709,12 +818,13 @@ static inline int cts_get_list_with_int(cts_get_list_int_op op_code,
        case CTS_LIST_MEMBERS_OF_ADDRESSBOOK_ID:
                iter->i_type = CTS_ITER_CONTACTS;
                snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, data1, data2, data3, data5, B.addrbook_id, B.image0, %s "
-                               "FROM %s A, %s B ON A.contact_id = B.contact_id "
+                               "SELECT B.person_id, data1, data2, data3, data5, B.addrbook_id, B.image0, B.contact_id, %s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
                                "WHERE datatype = %d AND B.addrbook_id = %d "
+                               "GROUP BY B.person_id "
                                "ORDER BY data1, %s",
-                               display, CTS_TABLE_DATA, CTS_TABLE_CONTACTS, CTS_DATA_NAME, search_value,
-                               CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+                               display, data, CTS_TABLE_CONTACTS,
+                               CTS_DATA_NAME, search_value, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
 
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
@@ -723,7 +833,7 @@ static inline int cts_get_list_with_int(cts_get_list_int_op op_code,
        case CTS_LIST_GROUPS_OF_ADDRESSBOOK_ID:
                iter->i_type = CTS_ITER_GROUPS;
                snprintf(query, sizeof(query),
-                               "SELECT group_id, %d, group_name "
+                               "SELECT group_id, %d, group_name, ringtone "
                                "FROM %s WHERE addrbook_id = %d "
                                "ORDER BY group_name COLLATE NOCASE",
                                search_value, CTS_TABLE_GROUPS, search_value);
@@ -736,12 +846,71 @@ static inline int cts_get_list_with_int(cts_get_list_int_op op_code,
                snprintf(query, sizeof(query),
                                "SELECT addrbook_id, addrbook_name, acc_id, acc_type, mode "
                                "FROM %s WHERE acc_id = %d "
-                               "ORDER BY acc_id, addrbook_id",
+                               "ORDER BY addrbook_id",
                                CTS_TABLE_ADDRESSBOOKS, search_value);
                stmt = cts_query_prepare(query);
                retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
                iter->stmt = stmt;
                break;
+       case CTS_LIST_MEMBERS_OF_PERSON_ID:
+               iter->i_type = CTS_ITER_CONTACTS;
+               snprintf(query, sizeof(query),
+                               "SELECT B.person_id, data1, data2, data3, data5, B.addrbook_id, B.image0, B.contact_id, %s "
+                               "FROM %s A, %s B ON A.contact_id = B.contact_id "
+                               "WHERE A.datatype = %d AND B.person_id = %d "
+                               "ORDER BY data1, %s",
+                               display, data, CTS_TABLE_CONTACTS, CTS_DATA_NAME, search_value,
+                               CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               iter->stmt = stmt;
+               break;
+       case CTS_LIST_PLOG_OF_PERSON_ID:
+               iter->i_type = CTS_ITER_PLOGS_OF_PERSON_ID;
+               snprintf(query, sizeof(query),
+                               "SELECT A.id, A.log_type, A.log_time, A.data1, A.data2, A.related_id, A.number "
+                               "FROM %s A, %s B WHERE ((A.normal_num = B.data3 AND B.datatype = %d) OR "
+                               "(A.number = B.data2 AND B.datatype = %d)) "
+                               "AND EXISTS (SELECT contact_id from %s WHERE person_id = %d AND B.contact_id = contact_id) "
+                               "ORDER BY A.log_time DESC",
+                               CTS_TABLE_PHONELOGS, data, CTS_DATA_NUMBER, CTS_DATA_EMAIL,
+                               CTS_TABLE_CONTACTS, search_value);
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               iter->stmt = stmt;
+               break;
+       case CTS_LIST_NO_GROUP_MEMBERS_HAD_NUMBER_OF_ADDRESSBOOK_ID:
+               iter->i_type = CTS_ITER_CONTACTS;
+               snprintf(query, sizeof(query),
+                               "SELECT B.person_id, data1, data2, data3, data5, B.addrbook_id, B.image0, B.contact_id, %s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
+                               "WHERE datatype = %d AND B.addrbook_id = %d AND B.default_num > 0 AND "
+                               "NOT EXISTS (SELECT contact_id FROM %s WHERE contact_id=B.contact_id LIMIT 1) "
+                               "GROUP BY B.person_id "
+                               "ORDER BY data1, %s",
+                               display, data, CTS_TABLE_CONTACTS,
+                               CTS_DATA_NAME, search_value,
+                               CTS_TABLE_GROUPING_INFO, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               iter->stmt = stmt;
+               break;
+       case CTS_LIST_NO_GROUP_MEMBERS_HAD_EMAIL_OF_ADDRESSBOOK_ID:
+               iter->i_type = CTS_ITER_CONTACTS;
+               snprintf(query, sizeof(query),
+                               "SELECT B.person_id, data1, data2, data3, data5, B.addrbook_id, B.image0, B.contact_id, %s "
+                               "FROM %s A, %s B ON A.contact_id = B.person_id "
+                               "WHERE datatype = %d AND B.addrbook_id = %d AND B.default_email > 0 AND "
+                               "NOT EXISTS (SELECT contact_id FROM %s WHERE contact_id=B.contact_id LIMIT 1) "
+                               "GROUP BY B.person_id "
+                               "ORDER BY data1, %s",
+                               display, data, CTS_TABLE_CONTACTS,
+                               CTS_DATA_NAME, search_value,
+                               CTS_TABLE_GROUPING_INFO, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+               iter->stmt = stmt;
+               break;
        default:
                ERR("Invalid parameter : The op_code(%d) is not supported", op_code);
                return CTS_ERR_ARG_INVALID;
@@ -769,6 +938,7 @@ API int contacts_svc_get_list_with_int(cts_get_list_int_op op_code,
        }
 
        *iter = (CTSiter *)result;
+       INFO(",CTSiter,1");
        return CTS_SUCCESS;
 }
 
@@ -778,20 +948,34 @@ static inline int cts_get_updated_contacts(int addressbook_id, int version,
        int ret;
        cts_stmt stmt = NULL;
        char query[CTS_SQL_MAX_LEN] = {0};
-       updated_contact *result;
+       updated_record *result;
 
        retv_if(NULL == iter, CTS_ERR_ARG_NULL);
        retv_if(NULL == iter->info, CTS_ERR_ARG_INVALID);
 
-       iter->i_type = CTS_ITER_UPDATED_CONTACTS_AFTER_VER;
-       snprintf(query, sizeof(query),
-                       "SELECT %d, contact_id, changed_ver, created_ver FROM %s "
-                       "WHERE changed_ver > %d AND addrbook_id = %d "
-                       "UNION "
-                       "SELECT %d, contact_id, deleted_ver, -1 FROM %s "
-                       "WHERE deleted_ver > %d AND addrbook_id = %d",
-                       CTS_OPERATION_UPDATED, CTS_TABLE_CONTACTS, version, addressbook_id,
-                       CTS_OPERATION_DELETED, CTS_TABLE_DELETEDS, version, addressbook_id);
+       iter->i_type = CTS_ITER_UPDATED_INFO_AFTER_VER;
+
+       if (0 <= addressbook_id)
+       {
+               snprintf(query, sizeof(query),
+                               "SELECT %d, contact_id, changed_ver, created_ver, addrbook_id FROM %s "
+                               "WHERE changed_ver > %d AND addrbook_id = %d "
+                               "UNION "
+                               "SELECT %d, contact_id, deleted_ver, -1, addrbook_id FROM %s "
+                               "WHERE deleted_ver > %d AND addrbook_id = %d",
+                               CTS_OPERATION_UPDATED, CTS_TABLE_CONTACTS, version, addressbook_id,
+                               CTS_OPERATION_DELETED, CTS_TABLE_DELETEDS, version, addressbook_id);
+       }
+       else {
+               snprintf(query, sizeof(query),
+                               "SELECT %d, contact_id, changed_ver, created_ver, addrbook_id FROM %s "
+                               "WHERE changed_ver > %d "
+                               "UNION "
+                               "SELECT %d, contact_id, deleted_ver, -1, addrbook_id FROM %s "
+                               "WHERE deleted_ver > %d ",
+                               CTS_OPERATION_UPDATED, CTS_TABLE_CONTACTS, version,
+                               CTS_OPERATION_DELETED, CTS_TABLE_DELETEDS, version );
+       }
 
        stmt = cts_query_prepare(query);
        retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
@@ -804,15 +988,16 @@ static inline int cts_get_updated_contacts(int addressbook_id, int version,
                return CTS_ERR_DB_RECORD_NOT_FOUND;
        }
 
-       iter->info->head = result = cts_updated_contact_add_mempool();
+       iter->info->head = result = cts_updated_info_add_mempool();
        do {
                result->type = cts_stmt_get_int(stmt, 0);
                result->id = cts_stmt_get_int(stmt, 1);
                result->ver = cts_stmt_get_int(stmt, 2);
                if (cts_stmt_get_int(stmt, 3) == result->ver || version < cts_stmt_get_int(stmt, 3))
                        result->type = CTS_OPERATION_INSERTED;
+               result->addressbook_id = cts_stmt_get_int(stmt, 4);
                if (NULL == result->next)
-                       result->next = cts_updated_contact_add_mempool();
+                       result->next = cts_updated_info_add_mempool();
                result = result->next;
        }while(CTS_TRUE == cts_stmt_step(stmt));
 
@@ -833,7 +1018,7 @@ API int contacts_svc_get_updated_contacts(int addressbook_id,
        result = calloc(1, sizeof(CTSiter));
        retvm_if(NULL == result, CTS_ERR_OUT_OF_MEMORY, "calloc() Failed");
 
-       result->info = calloc(1, sizeof(updated_contact_info));
+       result->info = calloc(1, sizeof(updated_info));
        if (NULL == result->info) {
                ERR("calloc() Failed");
                free(result);
@@ -849,10 +1034,105 @@ API int contacts_svc_get_updated_contacts(int addressbook_id,
        }
 
        *iter = (CTSiter *)result;
+       INFO(",CTSiter,1");
        return CTS_SUCCESS;
 }
 
-static inline void cts_foreach_run(CTSiter *iter, cts_foreach_fn cb, void *data)
+static inline int cts_get_updated_groups(int addressbook_id, int version,
+               CTSiter *iter)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       updated_record *result;
+
+       retv_if(NULL == iter, CTS_ERR_ARG_NULL);
+       retv_if(NULL == iter->info, CTS_ERR_ARG_INVALID);
+
+       iter->i_type = CTS_ITER_UPDATED_INFO_AFTER_VER;
+       if (0 <= addressbook_id)
+       {
+               snprintf(query, sizeof(query),
+                               "SELECT %d, group_id, changed_ver, created_ver, addrbook_id FROM %s "
+                               "WHERE changed_ver > %d AND addrbook_id = %d "
+                               "UNION "
+                               "SELECT %d, group_id, deleted_ver, -1, addrbook_id FROM %s "
+                               "WHERE deleted_ver > %d AND addrbook_id = %d",
+                               CTS_OPERATION_UPDATED, CTS_TABLE_GROUPS, version, addressbook_id,
+                               CTS_OPERATION_DELETED, CTS_TABLE_GROUP_DELETEDS, version, addressbook_id);
+       }
+       else {
+               snprintf(query, sizeof(query),
+                               "SELECT %d, group_id, changed_ver, created_ver, addrbook_id FROM %s "
+                               "WHERE changed_ver > %d "
+                               "UNION "
+                               "SELECT %d, group_id, deleted_ver, -1, addrbook_id FROM %s "
+                               "WHERE deleted_ver > %d ",
+                               CTS_OPERATION_UPDATED, CTS_TABLE_GROUPS, version,
+                               CTS_OPERATION_DELETED, CTS_TABLE_GROUP_DELETEDS, version);
+       }
+       stmt = cts_query_prepare(query);
+       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+
+       ret = cts_stmt_step(stmt);
+       if (CTS_TRUE != ret) {
+               warn_if(CTS_SUCCESS != ret, "cts_stmt_step() Failed(%d)", ret);
+               cts_stmt_finalize(stmt);
+               return CTS_ERR_DB_RECORD_NOT_FOUND;
+       }
+
+       iter->info->head = result = cts_updated_info_add_mempool();
+       do {
+               result->type = cts_stmt_get_int(stmt, 0);
+               result->id = cts_stmt_get_int(stmt, 1);
+               result->ver = cts_stmt_get_int(stmt, 2);
+               if (cts_stmt_get_int(stmt, 3) == result->ver || version < cts_stmt_get_int(stmt, 3))
+                       result->type = CTS_OPERATION_INSERTED;
+               result->addressbook_id = cts_stmt_get_int(stmt, 4);
+               if (NULL == result->next)
+                       result->next = cts_updated_info_add_mempool();
+               result = result->next;
+       }while (CTS_TRUE == cts_stmt_step(stmt));
+
+       cts_stmt_finalize(stmt);
+
+       return CTS_SUCCESS;
+}
+
+
+API int contacts_svc_get_updated_groups(int addressbook_id,
+               int version, CTSiter **iter)
+{
+       int ret;
+       CTSiter *result;
+
+       retv_if(NULL == iter, CTS_ERR_ARG_NULL);
+       retvm_if(version < 0, CTS_ERR_ARG_INVALID, "The version(%d) is invalid", version);
+
+       result = calloc(1, sizeof(CTSiter));
+       retvm_if(NULL == result, CTS_ERR_OUT_OF_MEMORY, "calloc() Failed");
+
+       result->info = calloc(1, sizeof(updated_info));
+       if (NULL == result->info) {
+               ERR("calloc() Failed");
+               free(result);
+               return CTS_ERR_OUT_OF_MEMORY;
+       }
+
+       ret = cts_get_updated_groups(addressbook_id, version, result);
+       if (ret) {
+               ERR("cts_get_updated_groups() Failed(%d)", ret);
+               free(result->info);
+               free(result);
+               return ret;
+       }
+
+       *iter = (CTSiter *)result;
+       INFO(",CTSiter,1");
+       return CTS_SUCCESS;
+}
+
+void cts_foreach_run(CTSiter *iter, cts_foreach_fn cb, void *data)
 {
        while (CTS_SUCCESS == contacts_svc_iter_next(iter)) {
                int ret;
@@ -913,412 +1193,6 @@ API int contacts_svc_list_with_str_foreach(cts_get_list_str_op op_code,
        return CTS_SUCCESS;
 }
 
-API int contacts_svc_list_filter_free(CTSfilter *filter)
-{
-       retv_if(NULL == filter, CTS_ERR_ARG_NULL);
-
-       free(filter->search_val);
-       free(filter);
-       return CTS_SUCCESS;
-}
-
-static inline int cts_filter_parse_args(va_list args, int type, CTSfilter *ret)
-{
-       while (type) {
-               switch (type) {
-               case CTS_LIST_FILTER_NONE:
-                       break;
-               case CTS_LIST_FILTER_ADDRESBOOK_ID_INT:
-                       ret->addrbook_on = true;
-                       ret->addrbook_id = va_arg(args, int);
-                       break;
-               case CTS_LIST_FILTER_GROUP_ID_INT:
-                       ret->group_on = true;
-                       ret->group_id = va_arg(args, int);
-                       break;
-               case CTS_LIST_FILTER_LIMIT_INT:
-                       ret->limit_on = true;
-                       ret->limit = va_arg(args, int);
-                       break;
-               case CTS_LIST_FILTER_OFFSET_INT:
-                       ret->offset_on = true;
-                       ret->offset = va_arg(args, int);
-                       break;
-               default:
-                       ERR("Invalid type. Your type(%d) is not supported.", type);
-                       return CTS_ERR_ARG_INVALID;
-               }
-               type = va_arg(args, int);
-       }
-
-       retvm_if(ret->offset_on && !ret->limit_on, CTS_ERR_ARG_INVALID, "OFFSET is depends on LIMIT");
-
-       return CTS_SUCCESS;
-}
-
-enum {
-       CTS_FILTER_TYPE_NONE,
-       CTS_FILTER_TYPE_INT,
-       CTS_FILTER_TYPE_STR,
-};
-
-API CTSfilter* contacts_svc_list_str_filter_new(cts_str_filter_op list_type,
-               const char *search_value, cts_filter_type first_type, ...)
-{
-       int ret;
-       CTSfilter *ret_val;
-       va_list args;
-
-       retvm_if(NULL == search_value, NULL, "The parameter(search_value) is NULL");
-       retvm_if(CTS_LIST_FILTER_NONE == first_type, NULL,
-                       "filter constraint is missing(use contacts_svc_get_list_with_str()");
-
-       ret_val = calloc(1, sizeof(CTSfilter));
-       ret_val->type = CTS_FILTER_TYPE_STR;
-       ret_val->list_type = list_type;
-       ret_val->search_val = strdup(search_value);
-
-       va_start(args, first_type);
-       ret = cts_filter_parse_args(args, first_type, ret_val);
-       va_end(args);
-
-       if (ret) {
-               contacts_svc_list_filter_free(ret_val);
-               return NULL;
-       }
-
-       return (CTSfilter *)ret_val;
-}
-
-API CTSfilter* contacts_svc_list_filter_new(cts_filter_op list_type, cts_filter_type first_type, ...)
-{
-       int ret;
-       CTSfilter *ret_val;
-       va_list args;
-
-       retvm_if(CTS_LIST_FILTER_NONE == first_type, NULL,
-                       "filter constraint is missing(use contacts_svc_get_list()");
-
-       ret_val = calloc(1, sizeof(CTSfilter));
-       ret_val = CTS_FILTER_TYPE_NONE;
-       ret_val->list_type = list_type;
-
-       va_start(args, first_type);
-       ret = cts_filter_parse_args(args, first_type, ret_val);
-       va_end(args);
-
-       if (ret) {
-               contacts_svc_list_filter_free(ret_val);
-               return NULL;
-       }
-
-       return (CTSfilter *)ret_val;
-}
-
-static int cts_list_with_str_make_query(CTSfilter *filter, CTSiter *iter)
-{
-       int ret;
-       cts_stmt stmt;
-       const char *display;
-       char query[CTS_SQL_MAX_LEN] = {0};
-       char remake_val[CTS_SQL_MIN_LEN] = {0};
-
-       retvm_if(NULL == filter->search_val,
-                       CTS_ERR_ARG_INVALID, "The parameter(filter) doesn't have search_val");
-
-       if (CTS_ORDER_NAME_LASTFIRST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
-               display = CTS_SCHEMA_DATA_NAME_REVERSE_LOOKUP;
-       else
-               display = CTS_SCHEMA_DATA_NAME_LOOKUP;
-
-       switch (filter->list_type) {
-       case CTS_LIST_PLOGS_OF_NUMBER:
-               iter->i_type = CTS_ITER_PLOGS_OF_NUMBER;
-               if (filter->search_val && *filter->search_val) {
-                       ret = snprintf(query, sizeof(query),
-                                       "SELECT A.id, A.log_type, A.log_time, A.data1, A.data2, MIN(B.contact_id) "
-                                       "FROM %s A LEFT JOIN %s B ON A.normal_num = B.data3 AND B.datatype = %d AND "
-                                       "(A.related_id = B.contact_id OR A.related_id IS NULL OR "
-                                       "NOT EXISTS (SELECT id FROM %s "
-                                       "WHERE datatype = %d AND contact_id = A.related_id AND data3 = ?)) "
-                                       "WHERE A.number = ? "
-                                       "GROUP BY A.id "
-                                       "ORDER BY A.log_time DESC",
-                                       CTS_TABLE_PHONELOGS, CTS_TABLE_DATA, CTS_DATA_NUMBER, CTS_TABLE_DATA, CTS_DATA_NUMBER);
-               }
-               else {
-                       ret = snprintf(query, sizeof(query),
-                                       "SELECT id, log_type, log_time, data1, data2, NULL "
-                                       "FROM %s WHERE number ISNULL ORDER BY id DESC", CTS_TABLE_PHONELOGS);
-               }
-               if (filter->limit_on) {
-                       ret += snprintf(query+ret, sizeof(query)-ret, " LIMIT %d ", filter->limit);
-                       if (filter->offset_on)
-                               ret += snprintf(query+ret, sizeof(query)-ret, ", %d", filter->offset);
-               }
-
-               stmt = cts_query_prepare(query);
-               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-               if (filter->search_val) {
-                       const char *normal_num;
-                       ret = cts_clean_number(filter->search_val, remake_val, sizeof(remake_val));
-                       retvm_if(ret <= 0, CTS_ERR_ARG_INVALID, "Number(%s) is invalid", filter->search_val);
-
-                       normal_num = cts_normalize_number(remake_val);
-                       cts_stmt_bind_copy_text(stmt, 1, normal_num, strlen(normal_num));
-                       cts_stmt_bind_copy_text(stmt, 2, remake_val, strlen(remake_val));
-               }
-               iter->stmt = stmt;
-               break;
-       case CTS_LIST_CONTACTS_WITH_NAME:
-               retvm_if(CTS_SQL_MIN_LEN <= strlen(filter->search_val), CTS_ERR_ARG_INVALID,
-                               "search_value is too long");
-               iter->i_type = CTS_ITER_CONTACTS_WITH_NAME;
-               memset(remake_val, 0x00, sizeof(remake_val));
-
-               ret = cts_normalize_str(filter->search_val, remake_val, CTS_SQL_MIN_LEN);
-               retvm_if(ret < CTS_SUCCESS, ret, "cts_normalize_str() Failed(%d)", ret);
-
-               if (filter->addrbook_on) {
-                       ret = snprintf(query, sizeof(query),
-                                       "SELECT A.contact_id, data1, data2, data3, data5, B.addrbook_id, B.image0 "
-                                       "FROM %s A, %s B ON A.contact_id = B.contact_id "
-                                       "WHERE datatype = %d AND B.addrbook_id = %d AND %s LIKE ('%%' || ? || '%%') "
-                                       "ORDER BY data1, %s",
-                                       CTS_TABLE_DATA, CTS_TABLE_CONTACTS, CTS_DATA_NAME, filter->addrbook_id,
-                                       display, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
-               } else if (filter->group_on) {
-                       ret = snprintf(query, sizeof(query),
-                                       "SELECT A.contact_id, data1, data2, data3, data5, B.addrbook_id, B.image0 "
-                                       "FROM %s A, %s B ON A.contact_id = B.contact_id "
-                                       "WHERE datatype = %d AND %s LIKE ('%%' || ? || '%%') "
-                                       "AND contact_id IN (SELECT contact_id FROM %s WHERE group_id = %d) "
-                                       "ORDER BY data1, %s",
-                                       CTS_TABLE_DATA, CTS_TABLE_CONTACTS, CTS_DATA_NAME, display,
-                                       CTS_TABLE_GROUPING_INFO, filter->group_id,
-                                       CTS_SCHEMA_DATA_NAME_SORTING_KEY);
-               } else {
-                       ret = snprintf(query, sizeof(query),
-                                       "SELECT A.contact_id, data1, data2, data3, data5, B.addrbook_id, B.image0 "
-                                       "FROM %s A, %s B ON A.contact_id = B.contact_id "
-                                       "WHERE datatype = %d AND %s LIKE ('%%' || ? || '%%') "
-                                       "ORDER BY data1, %s",
-                                       CTS_TABLE_DATA, CTS_TABLE_CONTACTS, CTS_DATA_NAME, display,
-                                       CTS_SCHEMA_DATA_NAME_SORTING_KEY);
-               }
-
-               if (filter->limit_on) {
-                       ret += snprintf(query+ret, sizeof(query)-ret, " LIMIT %d ", filter->limit);
-                       if (filter->offset_on)
-                               ret += snprintf(query+ret, sizeof(query)-ret, ", %d", filter->offset);
-               }
-               stmt = cts_query_prepare(query);
-               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-               cts_stmt_bind_copy_text(stmt, 1, remake_val, strlen(remake_val));
-               break;
-       case CTS_LIST_NUMBERINFOS_WITH_NAME:
-               retvm_if(CTS_SQL_MIN_LEN <= strlen(filter->search_val), CTS_ERR_ARG_INVALID,
-                               "search_value is too long");
-               iter->i_type = CTS_ITER_NUMBERINFOS;
-               memset(remake_val, 0x00, sizeof(remake_val));
-
-               ret = cts_normalize_str(filter->search_val, remake_val, CTS_SQL_MIN_LEN);
-               retvm_if(ret < CTS_SUCCESS, ret, "cts_normalize_str() Failed(%d)", ret);
-
-               if (filter->addrbook_on) {
-                       ret = snprintf(query, sizeof(query),
-                                       "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0 "
-                                       "FROM %s A, %s B, %s C "
-                                       "ON A.contact_id = B.contact_id AND A.contact_id = C.contact_id "
-                                       "WHERE A.datatype = %d AND A.datatype = %d "
-                                       "AND C.addrbook_id = %d AND A.%s LIKE ('%%' || ? || '%%') "
-                                       "ORDER BY A.data1, A.%s",
-                                       CTS_TABLE_DATA, CTS_TABLE_DATA, CTS_TABLE_CONTACTS,
-                                       CTS_DATA_NAME, CTS_DATA_NUMBER,
-                                       filter->addrbook_id, display, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
-               } else if (filter->group_on) {
-                       ret = snprintf(query, sizeof(query),
-                                       "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0 "
-                                       "FROM %s A, %s B, %s C "
-                                       "ON A.contact_id = B.contact_id AND A.contact_id = C.contact_id "
-                                       "WHERE A.datatype = %d AND B.datatype = %d AND A.%s LIKE ('%%' || ? || '%%') "
-                                       "AND A.contact_id IN "
-                                       "(SELECT contact_id FROM %s WHERE group_id = %d) "
-                                       "ORDER BY A.data1, A.%s",
-                                       CTS_TABLE_DATA, CTS_TABLE_DATA, CTS_TABLE_CONTACTS,
-                                       CTS_DATA_NAME, CTS_DATA_NUMBER, display,
-                                       CTS_TABLE_GROUPING_INFO, filter->group_id, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
-               } else {
-                       ret = snprintf(query, sizeof(query),
-                                       "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0 "
-                                       "FROM %s A, %s B, %s C "
-                                       "ON A.contact_id = B.contact_id AND A.contact_id = C.contact_id "
-                                       "WHERE A.datatype = %d AND B.datatype = %d AND A.%s LIKE ('%%' || ? || '%%') "
-                                       "ORDER BY A.data1, A.%s",
-                                       CTS_TABLE_DATA, CTS_TABLE_DATA, CTS_TABLE_CONTACTS,
-                                       CTS_DATA_NAME, CTS_DATA_NUMBER,
-                                       display, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
-               }
-               if (filter->limit_on) {
-                       ret += snprintf(query+ret, sizeof(query)-ret, " LIMIT %d ", filter->limit);
-                       if (filter->offset_on)
-                               ret += snprintf(query+ret, sizeof(query)-ret, ", %d", filter->offset);
-               }
-
-               stmt = cts_query_prepare(query);
-               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-               cts_stmt_bind_copy_text(stmt, 1, remake_val, strlen(remake_val));
-               break;
-       case CTS_LIST_NUMBERINFOS_WITH_NUM:
-               iter->i_type = CTS_ITER_NUMBERINFOS;
-
-               if (filter->addrbook_on) {
-                       ret = snprintf(query, sizeof(query),
-                                       "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0 "
-                                       "FROM %s A, %s B, %s C "
-                                       "ON A.contact_id = B.contact_id AND A.contact_id = C.contact_id "
-                                       "WHERE A.datatype = %d AND B.datatype = %d "
-                                       "AND C.addrbook_id = %d AND B.data2 LIKE ('%%' || ? || '%%') "
-                                       "ORDER BY A.data1, A.%s",
-                                       CTS_TABLE_DATA, CTS_TABLE_DATA, CTS_TABLE_CONTACTS,
-                                       CTS_DATA_NAME, CTS_DATA_NUMBER,
-                                       filter->addrbook_id, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
-               } else if (filter->group_on) {
-                       ret = snprintf(query, sizeof(query),
-                                       "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0 "
-                                       "FROM %s A, %s B, %s C "
-                                       "ON A.contact_id = B.contact_id AND A.contact_id = C.contact_id "
-                                       "WHERE A.datatype = %d AND B.datatype = %d AND B.data2 LIKE ('%%' || ? || '%%') "
-                                       "AND A.contact_id IN (SELECT contact_id FROM %s WHERE group_id = %d) "
-                                       "ORDER BY A.data1, A.%s",
-                                       CTS_TABLE_DATA, CTS_TABLE_DATA, CTS_TABLE_CONTACTS,
-                                       CTS_DATA_NAME, CTS_DATA_NUMBER,
-                                       CTS_TABLE_GROUPING_INFO, filter->group_id, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
-               } else {
-                       ret = snprintf(query, sizeof(query),
-                                       "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0 "
-                                       "FROM %s A, %s B, %s C "
-                                       "ON A.contact_id = B.contact_id AND A.contact_id = C.conatct_id "
-                                       "WHERE B.data2 LIKE ('%%' || ? || '%%') "
-                                       "AND A.datatype = %d AND B.datatype = %d "
-                                       "ORDER BY A.data1, A.%s",
-                                       CTS_TABLE_DATA, CTS_TABLE_DATA, CTS_TABLE_CONTACTS,
-                                       CTS_DATA_NAME, CTS_DATA_NUMBER, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
-               }
-               if (filter->limit_on) {
-                       ret += snprintf(query+ret, sizeof(query)-ret, " LIMIT %d ", filter->limit);
-                       if (filter->offset_on)
-                               ret += snprintf(query+ret, sizeof(query)-ret, ", %d", filter->offset);
-               }
-
-               stmt = cts_query_prepare(query);
-               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-               cts_stmt_bind_copy_text(stmt, 1, filter->search_val, strlen(filter->search_val));
-               break;
-       case CTS_LIST_EMAILINFOS_WITH_EMAIL:
-               iter->i_type = CTS_ITER_EMAILINFOS_WITH_EMAIL;
-
-               if (filter->addrbook_on) {
-                       ret = snprintf(query, sizeof(query),
-                                       "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0 "
-                                       "FROM %s A, %s B, %s C "
-                                       "ON A.contact_id = B.contact_id AND A.contact_id = C.contact_id "
-                                       "WHERE A.datatype = %d AND B.datatype = %d AND C.addrbook_id = %d "
-                                       "AND B.data2 LIKE ('%%' || ? || '%%') "
-                                       "ORDER BY A.data1, A.%s",
-                                       CTS_TABLE_DATA, CTS_TABLE_DATA, CTS_TABLE_CONTACTS,
-                                       CTS_DATA_NAME, CTS_DATA_NUMBER, filter->addrbook_id,
-                                       CTS_SCHEMA_DATA_NAME_SORTING_KEY);
-               } else if (filter->group_on) {
-                       ret = snprintf(query, sizeof(query),
-                                       "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0 "
-                                       "FROM %s A, %s B, %s C "
-                                       "ON A.contact_id = B.contact_id AND A.contact_id = C.contact_id "
-                                       "WHERE A.datatype = %d AND B.datatype = %d AND "
-                                       "B.data2 LIKE ('%%' || ? || '%%') AND A.contact_id IN "
-                                       "(SELECT contact_id FROM %s WHERE group_id = %d) "
-                                       "ORDER BY A.data1, A.%s",
-                                       CTS_TABLE_DATA, CTS_TABLE_DATA, CTS_TABLE_CONTACTS,
-                                       CTS_DATA_NAME, CTS_DATA_NUMBER,
-                                       CTS_TABLE_GROUPING_INFO, filter->group_id,
-                                       CTS_SCHEMA_DATA_NAME_SORTING_KEY);
-               } else {
-                       ret = snprintf(query, sizeof(query),
-                                       "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, B.data2, C.image0 "
-                                       "FROM %s A, %s B, %s C "
-                                       "ON A.contact_id = B.contact_id AND A.contact_id = C.contact_id "
-                                       "WHERE A.datatype = %d AND B.datatype = %d AND B.data2 LIKE ('%%' || ? || '%%') "
-                                       "ORDER BY A.data1, A.%s",
-                                       CTS_TABLE_DATA, CTS_TABLE_DATA, CTS_TABLE_CONTACTS,
-                                       CTS_DATA_NAME, CTS_DATA_EMAIL,
-                                       CTS_SCHEMA_DATA_NAME_SORTING_KEY);
-               }
-               if (filter->limit_on) {
-                       ret += snprintf(query+ret, sizeof(query)-ret, " LIMIT %d ", filter->limit);
-                       if (filter->offset_on)
-                               ret += snprintf(query+ret, sizeof(query)-ret, ", %d", filter->offset);
-               }
-
-               stmt = cts_query_prepare(query);
-               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-               cts_stmt_bind_copy_text(stmt, 1, filter->search_val, strlen(filter->search_val));
-               break;
-       default:
-               ERR("Invalid parameter : The op_code(%d) is not supported", filter->list_type);
-               return CTS_ERR_ARG_INVALID;
-       }
-       iter->stmt = stmt;
-
-       return CTS_SUCCESS;
-}
-
-#ifdef CTS_DEPRECATED
-API int contacts_svc_get_list_with_filter(CTSfilter *filter, CTSiter **iter)
-{
-       int ret;
-       CTSiter *result;
-
-       retv_if(NULL == filter, CTS_ERR_ARG_NULL);
-       retv_if(NULL == iter, CTS_ERR_ARG_NULL);
-
-       if (CTS_FILTER_TYPE_STR == filter->type) {
-               result = calloc(1, sizeof(CTSiter));
-               retvm_if(NULL == result, CTS_ERR_OUT_OF_MEMORY, "calloc() Failed");
-
-               ret = cts_list_with_str_make_query(filter, result);
-               if (ret) {
-                       ERR("cts_list_with_str_make_query() Failed(%d)", ret);
-                       free(result);
-                       return ret;
-               }
-       } else {
-               ERR("Invalid CTSfilter(type = %d)", filter->type);
-               return CTS_ERR_ARG_INVALID;
-       }
-
-       return CTS_SUCCESS;
-}
-#endif
-
-API int contacts_svc_list_with_filter_foreach(CTSfilter *filter,
-               cts_foreach_fn cb, void *user_data)
-{
-       int ret;
-       CTSiter iter = {0};
-
-       if (CTS_FILTER_TYPE_STR == filter->type) {
-               ret = cts_list_with_str_make_query(filter, &iter);
-               retvm_if(CTS_SUCCESS != ret, ret, "contacts_svc_get_list_with_filter() Failed(%d)", ret);
-       } else {
-               ERR("Invalid CTSfilter(type = %d)", filter->type);
-               return CTS_ERR_ARG_INVALID;
-       }
-
-       cts_foreach_run(&iter, cb, user_data);
-
-       return CTS_SUCCESS;
-}
-
 // same with check_dirty_number()
 static inline bool cts_is_number(const char *str)
 {
@@ -1372,7 +1246,7 @@ API int contacts_svc_smartsearch_excl(const char *search_str, int limit, int off
 {
        int ret, len;
        CTSiter iter = {0};
-       const char *display;
+       const char *display, *data;
        cts_stmt stmt = NULL;
        char query[CTS_SQL_MAX_LEN];
        char remake_name[CTS_SQL_MIN_LEN], escape_name[CTS_SQL_MIN_LEN];
@@ -1388,26 +1262,31 @@ API int contacts_svc_smartsearch_excl(const char *search_str, int limit, int off
        else
                display = CTS_SCHEMA_DATA_NAME_LOOKUP;
 
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
        if (cts_is_number(search_str)) {
                len = snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, C.data2, B.image0 "
-                               "FROM (%s A, %s B ON A.contact_id = B.contact_id AND A.datatype = %d) "
+                               "SELECT B.person_id, A.data1, A.data2, A.data3, A.data5, C.data2, B.image0, B.contact_id "
+                               "FROM (%s A, %s B ON A.contact_id = B.person_id AND A.datatype=%d) "
                                        "LEFT JOIN %s C ON B.contact_id = C.contact_id AND C.datatype = %d "
                                "WHERE C.data2 LIKE '%%%s%%' OR A.%s LIKE ('%%' || ? || '%%') "
                                "ORDER BY A.data1, A.%s",
-                               CTS_TABLE_DATA, CTS_TABLE_CONTACTS, CTS_DATA_NAME,
-                               CTS_TABLE_DATA, CTS_DATA_NUMBER,
+                               data, CTS_TABLE_CONTACTS, CTS_DATA_NAME,
+                               data, CTS_DATA_NUMBER,
                                search_str, display, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
        }
        else {
                len = snprintf(query, sizeof(query),
-                               "SELECT A.contact_id, A.data1, A.data2, A.data3, A.data5, C.data2, B.image0 "
-                               "FROM (%s A, %s B ON A.contact_id = B.contact_id AND A.datatype = %d) "
+                               "SELECT B.person_id, A.data1, A.data2, A.data3, A.data5, C.data2, B.image0, B.contact_id "
+                               "FROM (%s A, %s B ON A.contact_id = B.person_id AND A.datatype = %d) "
                                        "LEFT JOIN %s C ON B.default_num = C.id AND C.datatype = %d "
                                "WHERE A.%s LIKE ('%%' || ? || '%%') ESCAPE '\\' "
                                "ORDER BY A.data1, A.%s",
-                               CTS_TABLE_DATA, CTS_TABLE_CONTACTS, CTS_DATA_NAME,
-                               CTS_TABLE_DATA, CTS_DATA_NUMBER,
+                               data, CTS_TABLE_CONTACTS, CTS_DATA_NAME,
+                               data, CTS_DATA_NUMBER,
                                display, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
        }
 
@@ -1435,17 +1314,23 @@ static inline int cts_group_get_relation_changes(int addressbook_id, int version
        int ret;
        cts_stmt stmt = NULL;
        char query[CTS_SQL_MAX_LEN] = {0};
-       updated_contact *result;
+       updated_record *result;
 
        retv_if(NULL == iter, CTS_ERR_ARG_NULL);
        retv_if(NULL == iter->info, CTS_ERR_ARG_INVALID);
 
-       iter->i_type = CTS_ITER_UPDATED_CONTACTS_AFTER_VER;
-       snprintf(query, sizeof(query),
-                       "SELECT group_id, type, ver FROM %s, %s USING (group_id) "
-                       "WHERE ver > %d AND addrbook_id = %d ",
-                       "group_relations_log", CTS_TABLE_GROUPS,
-                       version, addressbook_id);
+       iter->i_type = CTS_ITER_UPDATED_INFO_AFTER_VER;
+
+       ret = snprintf(query, sizeof(query),
+                       "SELECT group_id, type, ver, addrbook_id FROM %s, %s USING (group_id) "
+                       "WHERE ver > %d ",
+                       "group_relations_log", CTS_TABLE_GROUPS, version);
+
+       if (0 <= addressbook_id)
+       {
+               snprintf(query + ret , sizeof(query) -ret ,
+                               "AND addrbook_id = %d ", addressbook_id);
+       }
 
        stmt = cts_query_prepare(query);
        retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
@@ -1458,14 +1343,14 @@ static inline int cts_group_get_relation_changes(int addressbook_id, int version
                return CTS_ERR_DB_RECORD_NOT_FOUND;
        }
 
-       iter->info->head = result = cts_updated_contact_add_mempool();
+       iter->info->head = result = cts_updated_info_add_mempool();
        do {
                result->id = cts_stmt_get_int(stmt, 0);
                result->type = cts_stmt_get_int(stmt, 1);
                result->ver = cts_stmt_get_int(stmt, 2);
-
+               result->addressbook_id = cts_stmt_get_int(stmt, 3);
                if (NULL == result->next)
-                       result->next = cts_updated_contact_add_mempool();
+                       result->next = cts_updated_info_add_mempool();
                result = result->next;
        }while(CTS_TRUE == cts_stmt_step(stmt));
 
@@ -1473,3 +1358,37 @@ static inline int cts_group_get_relation_changes(int addressbook_id, int version
 
        return CTS_SUCCESS;
 }
+
+/* This function is only for OSP */
+API int contacts_svc_group_get_relation_changes(int addressbook_id,
+               int version, CTSiter **iter)
+{
+       int ret;
+       CTSiter *result;
+
+       retv_if(NULL == iter, CTS_ERR_ARG_NULL);
+       retvm_if(version < 0, CTS_ERR_ARG_INVALID, "The version(%d) is invalid", version);
+
+       result = calloc(1, sizeof(CTSiter));
+       retvm_if(NULL == result, CTS_ERR_OUT_OF_MEMORY, "calloc() Failed");
+
+       result->info = calloc(1, sizeof(updated_info));
+       if (NULL == result->info) {
+               ERR("calloc() Failed");
+               free(result);
+               return CTS_ERR_OUT_OF_MEMORY;
+       }
+
+       ret = cts_group_get_relation_changes(addressbook_id, version, result);
+       if (ret) {
+               ERR("cts_group_get_relation_changes() Failed(%d)", ret);
+               free(result->info);
+               free(result);
+               return ret;
+       }
+
+       *iter = (CTSiter *)result;
+       INFO(",CTSiter,1");
+       return CTS_SUCCESS;
+}
+
index a46356d..05b15e3 100755 (executable)
@@ -43,40 +43,29 @@ enum
        CTS_ITER_ADDRESSBOOKS,
        CTS_ITER_EMAILS_OF_CONTACT_ID,
        CTS_ITER_NUMBERS_OF_CONTACT_ID,
-       CTS_ITER_UPDATED_CONTACTS_AFTER_VER,
+       CTS_ITER_UPDATED_INFO_AFTER_VER,
+       CTS_ITER_PLOGS_OF_PERSON_ID,
+       CTS_ITER_OSP,
        CTS_ITER_MAX
 };
 
-typedef struct _updated_contact {
+typedef struct _updated_record {
        int type;
        int id;
        int ver;
-       struct _updated_contact *next;
-}updated_contact;
+       int addressbook_id;
+       struct _updated_record *next;
+}updated_record;
 
 typedef struct {
-       updated_contact *head;
-       updated_contact *cursor;
-}updated_contact_info;
+       updated_record *head;
+       updated_record *cursor;
+}updated_info;
 
 struct _cts_iter {
        int i_type;
        cts_stmt stmt;
-       updated_contact_info *info;
-};
-
-struct cts_filter {
-       int type;
-       int list_type;
-       char *search_val;
-       bool addrbook_on;
-       bool group_on;
-       bool limit_on;
-       bool offset_on;
-       int addrbook_id;
-       int group_id;
-       int limit;
-       int offset;
+       updated_info *info;
 };
 
 //<!--
@@ -102,13 +91,6 @@ struct cts_filter {
  */
 typedef struct _cts_iter CTSiter;
 
-/**
- * CTSiter is an opaque type, it must be
- * used via accessor functions.
- * @see contacts_svc_list_filter_new(), contacts_svc_list_str_filter_new(), contacts_svc_list_filter_free()
- */
-typedef struct cts_filter CTSfilter;
-
 //////////////////// read only value ////////////////////
 //////////////////// List row info ////////////////////
 /**
@@ -116,6 +98,9 @@ typedef struct cts_filter CTSfilter;
  * For #CTS_LIST_PLOGS_OF_NUMBER, it supports CTS_LIST_PLOG_ID_INT, CTS_LIST_PLOG_LOG_TIME_INT,
  * CTS_LIST_PLOG_LOG_TYPE_INT, CTS_LIST_PLOG_DURATION_INT(or CTS_LIST_PLOG_MSGID_INT), CTS_LIST_PLOG_SHORTMSG_STR
  * and CTS_LIST_PLOG_RELATED_ID_INT.
+ * For #CTS_LIST_PLOGS_OF_PERSON_ID, it supports CTS_LIST_PLOG_ID_INT, CTS_LIST_PLOG_LOG_TIME_INT,
+ * CTS_LIST_PLOG_LOG_TYPE_INT, CTS_LIST_PLOG_DURATION_INT(or CTS_LIST_PLOG_MSGID_INT), CTS_LIST_PLOG_SHORTMSG_STR
+ * CTS_LIST_PLOG_RELATED_ID_INT and CTS_LIST_PLOG_NUMBER_STR.
  */
 enum PHONELOGLIST{
        CTS_LIST_PLOG_ID_INT,/**< . */
@@ -130,9 +115,27 @@ enum PHONELOGLIST{
        CTS_LIST_PLOG_DURATION_INT,/**< seconds */
        CTS_LIST_PLOG_MSGID_INT,/**< . */
        CTS_LIST_PLOG_SHORTMSG_STR,/**< . */
-       CTS_LIST_PLOG_RELATED_ID_INT/**< contact id */
+       CTS_LIST_PLOG_RELATED_ID_INT/**< person id */
 };
 
+/**
+ * Contact List for OSP(C++)
+ * Usually, This is sorted by name related with #CTS_ORDER_OF_SORTING
+ */
+enum OSPLIST{
+       CTS_LIST_OSP_PERSON_ID_INT,/**< . */
+       CTS_LIST_OSP_CONTACT_ID_INT,/**< . */
+       CTS_LIST_OSP_ADDRESSBOOK_ID_INT,/**< . */
+       CTS_LIST_OSP_IMG_PATH_STR,/**< . */
+       CTS_LIST_OSP_FIRST_STR,/**< . */
+       CTS_LIST_OSP_LAST_STR,/**< . */
+       CTS_LIST_OSP_DISPLAY_STR,/**< . */
+       CTS_LIST_OSP_DEF_NUM_TYPE_INT,/**< Default number type */
+       CTS_LIST_OSP_DEF_NUM_STR,/**< Default number */
+       CTS_LIST_OSP_DEF_EMAIL_TYPE_INT,/**< Default email type */
+       CTS_LIST_OSP_DEF_EMAIL_STR,/**< Default email */
+       CTS_LIST_OSP_NORMALIZED_STR,/**< . */
+};
 
 /**
  * Contact List
@@ -147,6 +150,7 @@ enum CONTACTLIST{
        CTS_LIST_CONTACT_NUM_OR_EMAIL_STR,/**< optional. related with #CTS_LIST_ALL_EMAIL_NUMBER */
        CTS_LIST_CONTACT_NORMALIZED_STR,/**< optional */
        CTS_LIST_CONTACT_ADDRESSBOOK_ID_INT,/**< . */
+       CTS_LIST_CONTACT_PERSON_ID_INT,/**< . */
 };
 
 /**
@@ -158,7 +162,8 @@ enum NUMBERLIST{
        CTS_LIST_NUM_CONTACT_FIRST_STR,/**< . */
        CTS_LIST_NUM_CONTACT_LAST_STR,/**< . */
        CTS_LIST_NUM_CONTACT_DISPLAY_STR,/**< . */
-       CTS_LIST_NUM_NUMBER_STR /**< . */
+       CTS_LIST_NUM_NUMBER_STR, /**< . */
+       CTS_LIST_NUM_PERSON_ID_INT,/**< . */
 };
 
 /**
@@ -170,7 +175,8 @@ enum EMAILLIST{
        CTS_LIST_EMAIL_CONTACT_FIRST_STR,/**< . */
        CTS_LIST_EMAIL_CONTACT_LAST_STR,/**< . */
        CTS_LIST_EMAIL_CONTACT_DISPLAY_STR,/**< . */
-       CTS_LIST_EMAIL_ADDR_STR /**< . */
+       CTS_LIST_EMAIL_ADDR_STR,/**< . */
+       CTS_LIST_EMAIL_PERSON_ID_INT /**< . */
 };
 
 
@@ -181,6 +187,7 @@ enum CHANGELIST{
        CTS_LIST_CHANGE_ID_INT,/**< . */
        CTS_LIST_CHANGE_TYPE_INT, /**< #CTS_OPERATION_UPDATED, #CTS_OPERATION_DELETED, #CTS_OPERATION_INSERTED */
        CTS_LIST_CHANGE_VER_INT,/**< The version when this contact is changed */
+       CTS_LIST_CHANGE_ADDRESSBOOK_ID_INT, /**< The version when this contact is changed */
 };
 
 enum {
@@ -216,9 +223,11 @@ enum CUSTOMNUMTYPELIST{
  * Usually, This is sorted by addressbook_id and name.
  */
 enum GROUPLIST{
-       CTS_LIST_GROUP_ID_INT,/**< . */
-       CTS_LIST_GROUP_ADDRESSBOOK_ID_INT,/**< . */
-       CTS_LIST_GROUP_NAME_STR,/**< . */
+       CTS_LIST_GROUP_ID_INT = CTS_GROUP_VAL_ID_INT,/**< . */
+       CTS_LIST_GROUP_ADDRESSBOOK_ID_INT = CTS_GROUP_VAL_ADDRESSBOOK_ID_INT,/**< . */
+       CTS_LIST_GROUP_NAME_STR = CTS_GROUP_VAL_NAME_STR,/**< . */
+       CTS_LIST_GROUP_RINGTONE_STR = CTS_GROUP_VAL_RINGTONE_STR,/**< . */
+       CTS_LIST_GROUP_IMAGE_STR = CTS_GROUP_VAL_IMG_PATH_STR,/**< . */
 };
 
 /**
@@ -226,7 +235,7 @@ enum GROUPLIST{
  */
 enum SHORTCUTLIST{
        CTS_LIST_SHORTCUT_ID_INT,/**< . */
-       CTS_LIST_SHORTCUT_CONTACT_ID_INT,/**< . */
+       CTS_LIST_SHORTCUT_PERSON_ID_INT,/**< . */
        CTS_LIST_SHORTCUT_FIRST_NAME_STR,/**< . */
        CTS_LIST_SHORTCUT_LAST_NAME_STR,/**< . */
        CTS_LIST_SHORTCUT_DISPLAY_NAME_STR,/**< . */
@@ -236,6 +245,11 @@ enum SHORTCUTLIST{
        CTS_LIST_SHORTCUT_SPEEDDIAL_INT /**< only for #CTS_LIST_ALL_SPEEDDIAL */
 };
 
+/**
+ * deprecated
+ */
+#define CTS_LIST_SHORTCUT_CONTACT_ID_INT CTS_LIST_SHORTCUT_PERSON_ID_INT
+
 
 /**
  * SDN(Service Dialing Number) List
@@ -267,6 +281,10 @@ typedef enum{
        CTS_LIST_ALL_PLOG, /**< #PHONELOGLIST */
        CTS_LIST_ALL_MISSED_CALL, /**< #PHONELOGLIST */
        CTS_LIST_ALL_NUMBER, /**< #CONTACTLIST */
+       CTS_LIST_ALL_UNSEEN_MISSED_CALL, /**< #PHONELOGLIST */
+       CTS_LIST_ALL_CONTACT_FAVORITE_HAD_NUMBER,/**< #SHORTCUTLIST */
+       CTS_LIST_ALL_CONTACT_FAVORITE_HAD_EMAIL,/**< #SHORTCUTLIST */
+       CTS_LIST_ALL_EMAIL_PLOG, /**< #PHONELOGLIST */
 }cts_get_list_op;
 /**
  * This function gets iterator of the gotten data by op_code.
@@ -345,6 +363,10 @@ typedef enum{
        CTS_LIST_NO_GROUP_MEMBERS_OF_ADDRESSBOOK_ID, /**< #CONTACTLIST */
        CTS_LIST_GROUPS_OF_ADDRESSBOOK_ID, /**< #GROUPLIST */
        CTS_LIST_ADDRESSBOOKS_OF_ACCOUNT_ID, /**< #ADDRESSBOOKLIST */
+       CTS_LIST_MEMBERS_OF_PERSON_ID, /**< #CONTACTLIST */
+       CTS_LIST_NO_GROUP_MEMBERS_HAD_NUMBER_OF_ADDRESSBOOK_ID, /**< #CONTACTLIST */
+       CTS_LIST_NO_GROUP_MEMBERS_HAD_EMAIL_OF_ADDRESSBOOK_ID, /**< #CONTACTLIST */
+       CTS_LIST_PLOG_OF_PERSON_ID,/**< #PHONELOGLIST */
        //CTS_LIST_EMAILS_OF_CONTACT_ID,/**< only use #CTS_LIST_EMAIL_CONTACT_ID_INT, #CTS_LIST_EMAIL_ADDR_STR */
        //CTS_LIST_NUMBERS_OF_CONTACT_ID,/**< only use #CTS_LIST_NUM_CONTACT_ID_INT, #CTS_LIST_NUM_NUMBER_STR */
 }cts_get_list_int_op;
@@ -511,87 +533,6 @@ int contacts_svc_list_with_str_foreach(cts_get_list_str_op op_code,
    const char *search_value, cts_foreach_fn cb, void *data);
 
 /**
- * Use for contacts_svc_list_str_filter_new().
- */
-typedef enum {
-       CTS_FILTERED_PLOGS_OF_NUMBER = CTS_LIST_PLOGS_OF_NUMBER,/**< #PHONELOGLIST */
-       CTS_FILTERED_CONTACTS_WITH_NAME = CTS_LIST_CONTACTS_WITH_NAME,/**< #CONTACTLIST */
-       CTS_FILTERED_NUMBERINFOS_WITH_NAME = CTS_LIST_NUMBERINFOS_WITH_NAME,/**< #NUMBERLIST */
-       CTS_FILTERED_NUMBERINFOS_WITH_NUM = CTS_LIST_NUMBERINFOS_WITH_NUM,/**< #NUMBERLIST */
-       CTS_FILTERED_EMAILINFOS_WITH_EMAIL= CTS_LIST_EMAILINFOS_WITH_EMAIL,/**< #EMAILLIST */
-}cts_str_filter_op;
-
-/**
- * Use for contacts_svc_list_filter_new().
- */
-typedef enum {
-       CTS_FILTERED_ALL_CONTACT,/**< #CONTACTLIST */
-}cts_filter_op;
-
-/**
- * Use for contacts_svc_list_filter_new(), contacts_svc_list_str_filter_new().
- */
-typedef enum {
-       CTS_LIST_FILTER_NONE, /**< . */
-       CTS_LIST_FILTER_ADDRESBOOK_ID_INT, /**< exclusive with #CTS_LIST_FILTER_GROUP_ID_INT */
-       CTS_LIST_FILTER_GROUP_ID_INT, /**< exclusive with #CTS_LIST_FILTER_ADDRESBOOK_ID_INT */
-       CTS_LIST_FILTER_LIMIT_INT, /**< . */
-       CTS_LIST_FILTER_OFFSET_INT, /**< Offset depends on Limit(#CTS_LIST_FILTER_LIMIT_INT) */
-}cts_filter_type;
-
-/**
- * Allocate, initialize and return a new contacts service list filter with constraints.
- * The constaint is composed with the pair of (type, val).
- * The constaints list should be terminated with #CTS_LIST_FILTER_NONE,
- * therefore the count of parameter is an odd number.
- * This should be used for getting filtered list only,
- * if not, be sure to use contacts_svc_get_list_with_str().
- *
- * @param[in] list_type type of list(#cts_str_filter_op)
- * @param[in] search_value String search value
- * @param[in] first_type type of first constraint
- * @return The pointer of New contacts service list filter, NULL on error
- * @see contacts_svc_list_filter_free()
- */
-CTSfilter* contacts_svc_list_str_filter_new(cts_str_filter_op list_type,
-   const char *search_value, cts_filter_type first_type, ...);
-
-/**
- * Allocate, initialize and return a new contacts service list filter with constraints.
- * The constaint is composed with the pair of (type, val).
- * The constaints list should be terminated with #CTS_LIST_FILTER_NONE,
- * therefore the count of parameter is an even number.
- * This should be used for getting filtered list only,
- * if not, be sure to use contacts_svc_get_list().
- *
- * @param[in] list_type type of list(#cts_filter_op)
- * @param[in] first_type type of first constraint
- * @return The pointer of New contacts service list filter, NULL on error
- * @see contacts_svc_list_filter_free()
- */
-CTSfilter* contacts_svc_list_filter_new(cts_filter_op list_type, cts_filter_type first_type, ...);
-
-/**
- * A destructor for contacts service list filter.
- *
- * @param[in] filter A contacts service struct
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @see contacts_svc_list_filter_new(), contacts_svc_list_str_filter_new()
- */
-int contacts_svc_list_filter_free(CTSfilter *filter);
-
-/**
- * This function calls cb(#cts_foreach_fn) for each record of list gotten by filter.
- *
- * @param[in] filter The filter for searching
- * @param[in] cb callback function pointer(#cts_foreach_fn)
- * @param[in] user_data data which is passed to callback function
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_list_with_filter_foreach(CTSfilter *filter,
-   cts_foreach_fn cb, void *user_data);
-
-/**
  * It is the smartsearch exclusive function. It is supported for only smartsearch(inhouse application).
  * It can be changed without announcement.
  * This function calls #cts_foreach_fn for each record of list.
@@ -611,6 +552,8 @@ int contacts_svc_smartsearch_excl(const char *search_str, int limit, int offset,
  */
 //-->
 
+void cts_foreach_run(CTSiter *iter, cts_foreach_fn cb, void *data);
+
 
 #endif //__CTS_LIST_H__
 
index 644e9a1..d5036bd 100755 (executable)
@@ -25,7 +25,7 @@
 #include "cts-sqlite.h"
 
 #define CTS_COMPARE_BETWEEN(left_range, value, right_range) (((left_range) <= (value)) && ((value) <= (right_range)))
-#define CTS_VCONF_DEFAULT_LANGUAGE "db/service/contacts/default_lang"
+#define CTS_VCONF_DEFAULT_LANGUAGE "file/private/contacts-service/default_lang"
 
 /**
  * Language Type
diff --git a/src/cts-person.c b/src/cts-person.c
new file mode 100755 (executable)
index 0000000..09db7f5
--- /dev/null
@@ -0,0 +1,654 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjae Shin <yj99.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "cts-internal.h"
+#include "cts-utils.h"
+#include "cts-sqlite.h"
+#include "cts-schema.h"
+#include "cts-struct-ext.h"
+#include "cts-normalize.h"
+#include "cts-restriction.h"
+#include "cts-person.h"
+
+API int contacts_svc_link_person(int base_person_id, int sub_person_id)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN];
+
+       retvm_if(base_person_id == sub_person_id, CTS_ERR_ARG_INVALID,
+               "base_person_id(%d), sub_person_id(%d)", base_person_id, sub_person_id);
+
+       ret = contacts_svc_begin_trans();
+       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET person_id=%d WHERE person_id=%d",
+                       CTS_TABLE_CONTACTS, base_person_id, sub_person_id);
+       ret = cts_query_exec(query);
+       if (CTS_SUCCESS != ret) {
+               ERR("cts_query_exec() Failed(%d)", ret);
+               contacts_svc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "UPDATE %s "
+                       "SET outgoing_count=(SELECT MAX(outgoing_count) FROM %s WHERE person_id IN (%d, %d))"
+                       "WHERE person_id=%d",
+                       CTS_TABLE_PERSONS,
+                       CTS_TABLE_PERSONS, base_person_id, sub_person_id,
+                       base_person_id);
+       ret = cts_query_exec(query);
+       if (CTS_SUCCESS != ret) {
+               ERR("cts_query_exec() Failed(%d)", ret);
+               contacts_svc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE person_id = %d",
+                       CTS_TABLE_PERSONS, sub_person_id);
+       ret = cts_query_exec(query);
+       if (CTS_SUCCESS != ret) {
+               ERR("cts_query_exec() Failed(%d)", ret);
+               contacts_svc_end_trans(false);
+               return ret;
+       }
+
+       cts_set_link_noti();
+       contacts_svc_end_trans(true);
+
+       return CTS_SUCCESS;
+}
+
+
+int cts_insert_person(int contact_id, int outgoing_cnt)
+{
+       int ret, index;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MIN_LEN];
+
+       snprintf(query, sizeof(query),
+                       "INSERT INTO %s(person_id, outgoing_count) VALUES(%d, %d)",
+                       CTS_TABLE_PERSONS, contact_id, outgoing_cnt);
+
+       stmt = cts_query_prepare(query);
+       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+
+       ret = cts_stmt_step(stmt);
+       if (CTS_SUCCESS != ret) {
+               ERR("cts_stmt_step() Failed(%d)", ret);
+               cts_stmt_finalize(stmt);
+               return ret;
+       }
+       index = cts_db_get_last_insert_id();
+       cts_stmt_finalize(stmt);
+
+       return CTS_SUCCESS;
+}
+
+
+int cts_person_change_primary_contact(int person_id)
+{
+       int ret, new_person;
+       char query[CTS_SQL_MIN_LEN];
+
+       snprintf(query, sizeof(query),
+                       "SELECT B.contact_id "
+                       "FROM %s A, %s B ON A.contact_id = B.contact_id "
+                       "WHERE A.datatype = %d AND B.person_id = %d AND B.contact_id != %d "
+                       "ORDER BY data1, %s",
+                       CTS_TABLE_DATA, CTS_TABLE_CONTACTS, CTS_DATA_NAME, person_id, person_id,
+                       CTS_SCHEMA_DATA_NAME_SORTING_KEY);
+       new_person = cts_query_get_first_int_result(query);
+       retvm_if(new_person < CTS_SUCCESS, new_person,
+               "cts_query_get_first_int_result() Failed(%d)", new_person);
+
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET person_id=%d WHERE person_id=%d",
+                       CTS_TABLE_CONTACTS, new_person, person_id);
+       ret = cts_query_exec(query);
+       retvm_if(CTS_SUCCESS != ret, ret, "cts_query_exec() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET person_id=%d WHERE person_id=%d",
+                       CTS_TABLE_PERSONS, new_person, person_id);
+       ret = cts_query_exec(query);
+       retvm_if(CTS_SUCCESS != ret, ret, "cts_query_exec() Failed(%d)", ret);
+
+       return new_person;
+}
+
+
+API int contacts_svc_unlink_person(int person_id, int contact_id)
+{
+       int ret, outgoing_cnt;
+       char query[CTS_SQL_MIN_LEN];
+
+       snprintf(query, sizeof(query),
+                       "SELECT outgoing_count FROM %s WHERE person_id = %d",
+                       CTS_TABLE_PERSONS, person_id);
+
+       outgoing_cnt = cts_query_get_first_int_result(query);
+       retvm_if(outgoing_cnt < CTS_SUCCESS, outgoing_cnt,
+               "cts_query_get_first_int_result() Failed(%d)", outgoing_cnt);
+
+       ret = contacts_svc_begin_trans();
+       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
+
+       if (person_id == contact_id) {
+               ret = cts_person_change_primary_contact(person_id);
+               if (CTS_SUCCESS != ret) {
+                       ERR("cts_person_change_primary_contact() Failed(%d)", ret);
+                       contacts_svc_end_trans(false);
+                       return ret;
+               }
+       }
+
+       ret = cts_insert_person(contact_id, outgoing_cnt);
+       if (CTS_SUCCESS != ret) {
+               ERR("cts_insert_person() Failed(%d)", ret);
+               contacts_svc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET person_id=%d WHERE contact_id=%d",
+                       CTS_TABLE_CONTACTS, contact_id, contact_id);
+       ret = cts_query_exec(query);
+       if (CTS_SUCCESS != ret) {
+               ERR("cts_query_exec() Failed(%d)", ret);
+               contacts_svc_end_trans(false);
+               return ret;
+       }
+       cts_set_link_noti();
+       contacts_svc_end_trans(true);
+
+       return CTS_SUCCESS;
+}
+
+
+API int contacts_svc_get_person(int person_id, CTSstruct **person)
+{
+       int ret;
+       cts_stmt stmt;
+       CTSstruct *contact;
+       char query[CTS_SQL_MAX_LEN];
+
+       snprintf(query, sizeof(query), "SELECT contact_id FROM %s "
+               "WHERE person_id = %d", CTS_TABLE_CONTACTS, person_id);
+
+       stmt = cts_query_prepare(query);
+       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+
+       ret = cts_stmt_step(stmt);
+       if (CTS_TRUE != ret)
+       {
+               ERR("cts_stmt_step() Failed(%d)", ret);
+               cts_stmt_finalize(stmt);
+               return CTS_ERR_DB_RECORD_NOT_FOUND;
+       }
+
+       contact = contacts_svc_struct_new(CTS_STRUCT_CONTACT);
+       do {
+               CTSstruct *tmp;
+               ret = contacts_svc_get_contact(cts_stmt_get_int(stmt, 0), &tmp);
+               if (CTS_SUCCESS != ret) {
+                       ERR("contacts_svc_get_contact() Failed(%d)", ret);
+                       contacts_svc_struct_free(contact);
+                       cts_stmt_finalize(stmt);
+                       return ret;
+               }
+               if (cts_stmt_get_int(stmt, 0) == person_id) {
+                       contacts_svc_struct_merge(tmp, contact);
+                       contacts_svc_struct_free(contact);
+                       contact = tmp;
+               }
+               else {
+                       contacts_svc_struct_merge(contact, tmp);
+                       contacts_svc_struct_free(tmp);
+               }
+       }while(CTS_TRUE == cts_stmt_step(stmt));
+       cts_stmt_finalize(stmt);
+
+       *person = contact;
+
+       return CTS_SUCCESS;
+}
+
+/**
+ * The Number can be made with a set of values by specifying one or more values.
+ * \n Example : CTS_SIMILAR_NAME|CTS_SIMILAR_NUMBER
+ */
+typedef enum {
+       CTS_SIMILAR_NONE = 0,
+       CTS_SIMILAR_NAME = 1<<0,
+       CTS_SIMILAR_NUMBER = 1<<1,
+       CTS_SIMILAR_EMAIL = 1<<2,
+}cts_similar_op;
+
+
+API int contacts_svc_find_similar_person(cts_similar_op op_code, CTSstruct *contact)
+{
+       return CTS_SUCCESS;
+}
+
+
+/**
+ * This function gets index of person related with the contact.
+ * @param[in] contact_id index of contact
+ * @return index of found person on success, Negative value(#cts_error) on error
+ * @par example
+ * @code
+ void get_person(void)
+ {
+    int index, ret=-1;
+    CTSstruct *person = NULL;
+
+    index = contacts_svc_find_person_by_contact(123);
+    if(CTS_SUCCESS < index)
+      ret = contacts_svc_get_person(index, &person);
+    if(ret < CTS_SUCCESS)
+    {
+       printf("No found record\n");
+       return;
+    }
+ }
+ * @endcode
+ */
+API int contacts_svc_find_person_by_contact(int contact_id)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN];
+
+       snprintf(query, sizeof(query), "SELECT person_id "
+                       "FROM %s WHERE contact_id = %d", CTS_TABLE_CONTACTS, contact_id);
+       ret = cts_query_get_first_int_result(query);
+
+       return ret;
+}
+
+API int contacts_svc_find_person_by(cts_find_op op_code,
+               const char *user_data)
+{
+       int ret;
+       const char *temp, *data;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       char normalized_val[CTS_SQL_MIN_LEN];
+
+       CTS_START_TIME_CHECK;
+       retv_if(NULL == user_data, CTS_ERR_ARG_NULL);
+
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
+       switch (op_code)
+       {
+       case CTS_FIND_BY_NUMBER:
+               ret = cts_clean_number(user_data, normalized_val, sizeof(normalized_val));
+               retvm_if(ret <= 0, CTS_ERR_ARG_INVALID, "Number(%s) is invalid", user_data);
+
+               temp = cts_normalize_number(normalized_val);
+               snprintf(query, sizeof(query), "SELECT person_id FROM %s "
+                               "WHERE contact_id = (SELECT contact_id FROM %s "
+                                       "WHERE datatype = %d AND data3 = '%s' LIMIT 1)",
+                               CTS_TABLE_CONTACTS, CTS_TABLE_DATA, CTS_DATA_NUMBER, temp);
+               ret = cts_query_get_first_int_result(query);
+               break;
+       case CTS_FIND_BY_EMAIL:
+               snprintf(query, sizeof(query), "SELECT person_id FROM %s "
+                               "WHERE contact_id = (SELECT contact_id FROM %s "
+                                       "WHERE datatype = %d AND data2 = '%s' LIMIT 1)",
+                               CTS_TABLE_CONTACTS, data, CTS_DATA_EMAIL, user_data);
+               ret = cts_query_get_first_int_result(query);
+               break;
+       case CTS_FIND_BY_NAME:
+               ret = cts_normalize_str(user_data, normalized_val, sizeof(normalized_val));
+               retvm_if(ret < CTS_SUCCESS, ret, "cts_normalize_str() Failed(%d)", ret);
+
+               if (CTS_ORDER_NAME_LASTFIRST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
+                       temp = CTS_SCHEMA_DATA_NAME_REVERSE_LOOKUP;
+               else
+                       temp = CTS_SCHEMA_DATA_NAME_LOOKUP;
+
+               snprintf(query, sizeof(query), "SELECT person_id FROM %s "
+                               "WHERE contact_id = (SELECT contact_id FROM %s "
+                                       "WHERE %s LIKE '%%%s%%' LIMIT 1)",
+                               CTS_TABLE_CONTACTS, data, temp, normalized_val);
+
+               ret = cts_query_get_first_int_result(query);
+               break;
+       case CTS_FIND_BY_UID:
+               snprintf(query, sizeof(query), "SELECT person_id "
+                               "FROM %s WHERE uid = '%s' LIMIT 1", CTS_TABLE_CONTACTS, user_data);
+               ret = cts_query_get_first_int_result(query);
+               break;
+       default:
+               ERR("Invalid parameter : The op_code(%d) is not supported", op_code);
+               return CTS_ERR_ARG_INVALID;
+       }
+
+       CTS_END_TIME_CHECK();
+       return ret;
+}
+
+
+static inline int _cts_get_person_def_email_value(int id, CTSvalue **value)
+{
+       int ret;
+       const char *data;
+       cts_stmt stmt;
+       cts_email *email;
+       char query[CTS_SQL_MAX_LEN];
+
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
+       snprintf(query, sizeof(query),
+                       "SELECT B.id, B.data1, B.data2 "
+                       "FROM %s A, %s B ON B.id=A.default_email "
+                       "WHERE A.contact_id = %d",
+                       CTS_TABLE_CONTACTS, data, id);
+
+       stmt = cts_query_prepare(query);
+       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+
+       ret = cts_stmt_step(stmt);
+       if (CTS_SUCCESS == ret) {
+               cts_stmt_finalize(stmt);
+
+               snprintf(query, sizeof(query),
+                               "SELECT B.id, B.data1, B.data2 "
+                               "FROM %s A, %s B ON B.id=A.default_email "
+                               "WHERE A.person_id = %d LIMIT 1",
+                               CTS_TABLE_CONTACTS, data, id);
+
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+
+               ret = cts_stmt_step(stmt);
+               if (CTS_SUCCESS == ret)
+                       ret = CTS_ERR_DB_RECORD_NOT_FOUND;
+       }
+
+       if (ret < CTS_SUCCESS) {
+               ERR("cts_stmt_step() Failed(%d)", ret);
+               cts_stmt_finalize(stmt);
+               return ret;
+       }
+
+       email = (cts_email *)contacts_svc_value_new(CTS_VALUE_EMAIL);
+       if (email) {
+               email->v_type = CTS_VALUE_RDONLY_EMAIL;
+               email->embedded = true;
+               email->is_default = true;
+               cts_stmt_get_email(stmt, email, 0);
+
+               *value = (CTSvalue*)email;
+               ret = CTS_SUCCESS;
+       }
+       else {
+               ERR("contacts_svc_value_new() Failed");
+               ret = CTS_ERR_OUT_OF_MEMORY;
+       }
+
+       cts_stmt_finalize(stmt);
+       return ret;
+}
+
+static inline int _cts_get_person_def_number_value(int id, CTSvalue **value)
+{
+       int ret;
+       cts_stmt stmt;
+       const char *data;
+       cts_number *number;
+       char query[CTS_SQL_MAX_LEN];
+
+       if (cts_restriction_get_permit())
+               data = CTS_TABLE_DATA;
+       else
+               data = CTS_TABLE_RESTRICTED_DATA_VIEW;
+
+       snprintf(query, sizeof(query),
+                       "SELECT B.id, B.data1, B.data2 "
+                       "FROM %s A, %s B ON B.id=A.default_num "
+                       "WHERE A.contact_id = %d",
+                       CTS_TABLE_CONTACTS, data, id);
+
+       stmt = cts_query_prepare(query);
+       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+
+       ret = cts_stmt_step(stmt);
+       if (CTS_SUCCESS == ret) {
+               cts_stmt_finalize(stmt);
+
+               snprintf(query, sizeof(query),
+                               "SELECT B.id, B.data1, B.data2 "
+                               "FROM %s A, %s B ON B.id=A.default_num "
+                               "WHERE A.person_id = %d LIMIT 1",
+                               CTS_TABLE_CONTACTS, data, id);
+
+               stmt = cts_query_prepare(query);
+               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+
+               ret = cts_stmt_step(stmt);
+               if (CTS_SUCCESS == ret)
+                       ret = CTS_ERR_DB_RECORD_NOT_FOUND;
+       }
+
+       number = (cts_number *)contacts_svc_value_new(CTS_VALUE_NUMBER);
+       if (number) {
+               number->v_type = CTS_VALUE_RDONLY_NUMBER;
+               number->embedded = true;
+               number->is_default = true;
+               cts_stmt_get_number(stmt, number, 0);
+
+               *value = (CTSvalue*)number;
+               ret = CTS_SUCCESS;
+       }
+       else {
+               ERR("contacts_svc_value_new() Failed");
+               ret = CTS_ERR_OUT_OF_MEMORY;
+       }
+
+       cts_stmt_finalize(stmt);
+       return ret;
+}
+
+
+API int contacts_svc_get_person_value(cts_get_person_val_op op_code,
+               int person_id, CTSvalue **value)
+{
+       int ret;
+       contact_t temp={0};
+
+       retv_if(NULL == value, CTS_ERR_ARG_NULL);
+       CTS_START_TIME_CHECK;
+
+       switch (op_code)
+       {
+       case CTS_GET_PERSON_NAME_VALUE:
+               ret = cts_get_data_info(CTS_GET_DATA_BY_CONTACT_ID,
+                               CTS_DATA_FIELD_NAME, person_id, &temp);
+               retvm_if(CTS_SUCCESS != ret, ret,
+                               "cts_get_data_info(CTS_GET_DATA_BY_CONTACT_ID) Failed(%d)", ret);
+               if (temp.name) {
+                       temp.name->v_type = CTS_VALUE_RDONLY_NAME;
+                       *value = (CTSvalue *)temp.name;
+               }else
+                       *value = NULL;
+               break;
+       case CTS_GET_PERSON_DEFAULT_NUMBER_VALUE:
+               ret = _cts_get_person_def_number_value(person_id, value);
+               retvm_if(ret < CTS_SUCCESS, ret, "_cts_get_person_def_number_value() Failed(%d)", ret);
+               break;
+       case CTS_GET_PERSON_DEFAULT_EMAIL_VALUE:
+               ret = _cts_get_person_def_email_value(person_id, value);
+               retvm_if(ret < CTS_SUCCESS, ret, "_cts_get_person_def_email_value() Failed(%d)", ret);
+               break;
+       default:
+               ERR("Invalid parameter : The op_code(%d) is not supported", op_code);
+               return CTS_ERR_ARG_INVALID;
+       }
+
+       if (NULL == *value)
+               return CTS_ERR_NO_DATA;
+
+       CTS_END_TIME_CHECK();
+       return ret;
+}
+
+
+int cts_check_linked_contact(int contact_id)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN];
+
+       snprintf(query, sizeof(query),
+                       "SELECT COUNT(person_id) FROM %s WHERE person_id = %d",
+                       CTS_TABLE_CONTACTS, contact_id);
+       ret = cts_query_get_first_int_result(query);
+       retvm_if(ret < CTS_SUCCESS, ret, "cts_query_get_first_int_result() Failed(%d)", ret);
+
+       if (0 == ret)
+               return CTS_LINKED_SECONDARY;
+       else if (1 == ret)
+               return CTS_LINKED_NONE;
+       else
+               return CTS_LINKED_PRIMARY;
+}
+
+
+int cts_delete_person(int index)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN];
+
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE person_id = %d",
+                       CTS_TABLE_PERSONS, index);
+       ret = cts_query_exec(query);
+       retvm_if(CTS_SUCCESS != ret, ret, "cts_query_exec() Failed(%d)", ret);
+
+       return CTS_SUCCESS;
+}
+
+
+int cts_person_garbagecollection(void)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MIN_LEN];
+
+       snprintf(query, sizeof(query), "SELECT MIN(contact_id), person_id FROM %s "
+               "WHERE person_id NOT IN (SELECT person_id FROM %s WHERE contact_id = person_id) "
+               "GROUP BY person_id", CTS_TABLE_CONTACTS, CTS_TABLE_CONTACTS);
+
+       stmt = cts_query_prepare(query);
+       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
+
+       while (CTS_TRUE == cts_stmt_step(stmt)) {
+               int contact_id, person_id;
+
+               contact_id = cts_stmt_get_int(stmt, 0);
+               person_id = cts_stmt_get_int(stmt, 1);
+
+               snprintf(query, sizeof(query),
+                               "UPDATE %s SET person_id=%d WHERE person_id=%d",
+                               CTS_TABLE_CONTACTS, contact_id, person_id);
+               ret = cts_query_exec(query);
+               if (CTS_SUCCESS != ret) {
+                       ERR("cts_query_exec() Failed(%d)", ret);
+                       cts_stmt_finalize(stmt);
+                       return ret;
+               }
+               snprintf(query, sizeof(query),
+                               "UPDATE %s SET person_id=%d WHERE person_id=%d",
+                               CTS_TABLE_PERSONS, contact_id, person_id);
+               ret = cts_query_exec(query);
+               if (CTS_SUCCESS != ret) {
+                       ERR("cts_query_exec() Failed(%d)", ret);
+                       cts_stmt_finalize(stmt);
+                       return ret;
+               }
+       }
+       cts_stmt_finalize(stmt);
+
+       return CTS_SUCCESS;
+}
+
+/**
+ * This function deletes all contacts related with a person.
+ * It is not only deletes contact records from contact table,
+ * but also clears up all the info of these contacts(group relation info, favorites info and etc.).
+ *
+ * @param[in] index The index of person to delete in database.
+ * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
+ */
+API int contacts_svc_delete_person(int index)
+{
+       CTS_FN_CALL;
+       int ret;
+       char query[CTS_SQL_MIN_LEN];
+
+       ret = contacts_svc_begin_trans();
+       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "INSERT INTO %s SELECT contact_id, addrbook_id, %d FROM %s WHERE person_id = %d",
+                       CTS_TABLE_DELETEDS, cts_get_next_ver(), CTS_TABLE_CONTACTS, index);
+       ret = cts_query_exec(query);
+       if (CTS_SUCCESS != ret)
+       {
+               ERR("cts_query_exec() Failed(%d)", ret);
+               contacts_svc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE person_id = %d",
+                       CTS_TABLE_CONTACTS, index);
+       ret = cts_query_exec(query);
+       if (CTS_SUCCESS != ret) {
+               ERR("cts_query_exec() Failed(%d)", ret);
+               contacts_svc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE person_id = %d",
+                       CTS_TABLE_PERSONS, index);
+       ret = cts_query_exec(query);
+       if (CTS_SUCCESS != ret) {
+               ERR("cts_query_exec() Failed(%d)", ret);
+               contacts_svc_end_trans(false);
+               return ret;
+       }
+
+       cts_set_contact_noti();
+
+       ret = contacts_svc_end_trans(true);
+       if (ret < CTS_SUCCESS)
+               return ret;
+       else
+               return CTS_SUCCESS;
+}
+
+
diff --git a/src/cts-person.h b/src/cts-person.h
new file mode 100755 (executable)
index 0000000..e2e0a01
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjae Shin <yj99.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#ifndef __CONTACTS_PERSON_H__
+#define __CONTACTS_PERSON_H__
+
+#include "cts-contact.h"
+
+int cts_insert_person(int contact_id, int outgoing_cnt);
+int cts_delete_person(int index);
+int cts_person_garbagecollection(void);
+
+int cts_person_change_primary_contact(int person_id);
+
+enum {
+       CTS_LINKED_NONE,
+       CTS_LINKED_PRIMARY,
+       CTS_LINKED_SECONDARY,
+};
+int cts_check_linked_contact(int contact_id);
+
+//<!--
+/**
+ * @defgroup   CONTACTS_SVC_PERSON Person
+ * @ingroup    CONTACTS_SVC
+ * @addtogroup CONTACTS_SVC_PERSON
+ * @{
+ *
+ * This interface provides methods for linking.
+ *
+ * The person means linked contacts.\n
+ * If contact is not linked, the related person is same with contact.\n
+ * So contacts_svc_get_person() and contacts_svc_get_person_value return same value with
+ * contacts_svc_get_contact() and contacts_svc_get_contact_value().
+ */
+
+/**
+ * This function links a sub_person to base_person.
+ *
+ * @param[in] base_person_id The index of base person
+ * @param[in] sub_person_id The index of sub person
+ * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
+ */
+int contacts_svc_link_person(int base_person_id, int sub_person_id);
+
+/**
+ * This function unlinks a contact to person.
+ *
+ * @param[in] person_id The index of person
+ * @param[in] contact_id The index of contact to unlink
+ * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
+ */
+int contacts_svc_unlink_person(int person_id, int contact_id);
+
+/**
+ * This function gets person record which has the index from the database.
+ * If person has linked contacts, this function return merged record;
+ * Obtained person record should be freed by using contacts_svc_struct_free().
+ *
+ * @param[in] index The index of person to get
+ * @param[out] person Points of the person record which is returned
+ * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
+ * @par example
+ * @code
+ void get_person(void)
+ {
+    int ret=-1;
+    CTSstruct *person = NULL;
+    CTSvalue *name;
+    GSList *get_list, *cursor;
+
+    ret = contacts_svc_get_person(1, &person);
+    if(ret < 0)
+    {
+       printf("No found record\n");
+       return;
+    }
+
+    contacts_svc_struct_get_value(person, CTS_CF_NAME_VALUE, &name);
+    printf("First Name : %s\n", contacts_svc_value_get_str(name, CTS_NAME_VAL_FIRST_STR));
+    printf("Last Name : %s\n", contacts_svc_value_get_str(name, CTS_NAME_VAL_LAST_STR));
+    printf("Additional Name : %s\n", contacts_svc_value_get_str(name, CTS_NAME_VAL_ADDITION_STR));
+    printf("Display Name : %s\n", contacts_svc_value_get_str(name, CTS_NAME_VAL_DISPLAY_STR));
+    printf("Prefix Name : %s\n", contacts_svc_value_get_str(name, CTS_NAME_VAL_PREFIX_STR));
+    printf("Suffix Name : %s\n", contacts_svc_value_get_str(name, CTS_NAME_VAL_SUFFIX_STR));
+
+    get_list = NULL;
+    contacts_svc_struct_get_list(person, CTS_CF_NUMBER_LIST, &get_list);
+
+    cursor = get_list;
+    for(;cursor;cursor=g_slist_next(cursor))
+    {
+       printf("number Type = %d",
+          contacts_svc_value_get_int(cursor->data, CTS_NUM_VAL_TYPE_INT));
+
+       printf("Number = %s\n",
+          contacts_svc_value_get_str(cursor->data, CTS_NUM_VAL_NUMBER_STR));
+    }
+
+    get_list = NULL;
+    contacts_svc_struct_get_list(person, CTS_CF_EMAIL_LIST, &get_list);
+
+    cursor = get_list;
+    for(;cursor;cursor=g_slist_next(cursor))
+    {
+       printf("email Type = %d",
+          contacts_svc_value_get_int(cursor->data, CTS_EMAIL_VAL_TYPE_INT));
+
+       printf("email = %s\n",
+          contacts_svc_value_get_str(cursor->data, CTS_EMAIL_VAL_ADDR_STR));
+    }
+
+    contacts_svc_struct_free(person);
+ }
+ * @endcode
+ */
+int contacts_svc_get_person(int person_id, CTSstruct **person);
+
+/**
+ * This function gets index of person related with user_data.
+ * index is found by op_code with user_data related with op_code(#cts_find_op).
+ * @param[in] op_code #cts_find_op
+ * @param[in] user_data The parameter for searching
+ * @return index of found person on success, Negative value(#cts_error) on error
+ * @par example
+ * @code
+ void get_person(void)
+ {
+    int index, ret=-1;
+    CTSstruct *person = NULL;
+
+    index = contacts_svc_find_person_by(CTS_FIND_BY_NUMBER, "0123456789");
+    if(index > CTS_SUCCESS) {
+       ret = contacts_svc_get_person(index, &person);
+       if(ret < 0) {
+          printf("No found record\n");
+          return;
+       }
+    }
+ }
+ * @endcode
+ */
+int contacts_svc_find_person_by(cts_find_op op_code, const char *user_data);
+
+/**
+ * Use for contacts_svc_get_person_value().
+ */
+typedef enum {
+       CTS_GET_PERSON_NAME_VALUE, /**< Use #NAMEVALUE */
+       CTS_GET_PERSON_DEFAULT_NUMBER_VALUE,/**< related with person id. Use #NUMBERVALUE */
+       CTS_GET_PERSON_DEFAULT_EMAIL_VALUE,/**< related with person id. Use #EMAILVALUE */
+}cts_get_person_val_op;
+/**
+ * This function can get a value data related with person_id and op_code.
+ * The value data is decided by op_code(#cts_get_person_val_op)
+ * The gotten value is readonly.
+ * Obtained record should be freed by using contacts_svc_value_free().
+ * @return #CTS_SUCCESS, Negative value(#cts_error) on error
+ * @param[in] op_code #cts_get_person_val_op
+ * @param[in] person_id The person index
+ * @param[out] value Points of the contacts service value(#CTSvalue) which is returned
+ * @par example
+ * @code
+ void get_person_default_num(int person_id)
+ {
+    int index, ret;
+    CTSvalue *number=NULL;
+    const char *default_num;
+
+    ret = contacts_svc_get_person_value(CTS_GET_PERSON_DEFAULT_NUMBER_VALUE, person_id, &number);
+    if(ret < CTS_SUCCESS) {
+       printf("contacts_svc_get_contact_value() Failed(%d)\n", ret);
+       return;
+    }
+
+    default_num = contacts_svc_value_get_str(number, CTS_NUM_VAL_NUMBER_STR);
+    printf("The default Number is %s\n", default_num);
+    contacts_svc_value_free(number);
+ }
+ * @endcode
+ */
+int contacts_svc_get_person_value(cts_get_person_val_op op_code, int person_id, CTSvalue **value);
+
+/**
+ * This function deletes all contacts related with a person.
+ * It is not only deletes contact records from contact table,
+ * but also clears up all the info of these contacts(group relation info, favorites info and etc.).
+ *
+ * @param[in] index The index of person to delete in database.
+ * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
+ */
+int contacts_svc_delete_person(int index);
+
+/**
+ * @}
+ */
+//-->
+
+#endif //__CONTACTS_PERSON_H__
+
index de0673d..5725410 100755 (executable)
  * limitations under the License.
  *
  */
+
+#include <sys/types.h>
+#include <regex.h>
+
 #include "cts-internal.h"
 #include "cts-schema.h"
 #include "cts-sqlite.h"
@@ -97,22 +101,20 @@ static int cts_phonelog_accumulation_handle(cts_plog *plog)
        return CTS_SUCCESS;
 }
 
+//extra_data1 : duration, message_id, email_id
+//extra_data2 : short message, email subject
 static inline int cts_insert_phonelog(cts_plog *plog)
 {
        int ret;
        cts_stmt stmt = NULL;
-       char clean_num[CTS_NUMBER_MAX_LEN], query[CTS_SQL_MAX_LEN] = {0};
+       char clean_num[CTS_NUMBER_MAX_LEN] = {0};
+       char query[CTS_SQL_MAX_LEN] = {0};
        const char *normal_num;
 
        retvm_if(plog->log_type <= CTS_PLOG_TYPE_NONE
                        || CTS_PLOG_TYPE_MAX <= plog->log_type,
                        CTS_ERR_ARG_INVALID, "phonelog type(%d) is invaid", plog->log_type);
 
-       cts_clean_number(plog->number, clean_num, sizeof(clean_num));
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
        snprintf(query, sizeof(query), "INSERT INTO %s("
                        "number, normal_num, related_id, log_type, log_time, data1, data2) "
                        "VALUES(?, ?, ?, %d, %d, %d, ?)",
@@ -120,16 +122,15 @@ static inline int cts_insert_phonelog(cts_plog *plog)
                        plog->log_time, plog->extra_data1);
 
        stmt = cts_query_prepare(query);
-       if (NULL == stmt) {
-               ERR("cts_query_prepare() Failed");
-               contacts_svc_end_trans(false);
-               return CTS_ERR_DB_FAILED;
-       }
+       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
 
-       if (*clean_num) {
-               cts_stmt_bind_text(stmt, 1, clean_num);
-               normal_num = cts_normalize_number(clean_num);
-               cts_stmt_bind_text(stmt, 2, normal_num);
+       cts_stmt_bind_text(stmt, 1, plog->number);
+       if (plog->log_type < CTS_PLOG_TYPE_EMAIL_RECEIVED) {
+               ret = cts_clean_number(plog->number, clean_num, sizeof(clean_num));
+               if (0 < ret) {
+                       normal_num = cts_normalize_number(clean_num);
+                       cts_stmt_bind_text(stmt, 2, normal_num);
+               }
        }
 
        if (0 < plog->related_id)
@@ -143,7 +144,6 @@ static inline int cts_insert_phonelog(cts_plog *plog)
        {
                ERR("cts_stmt_step() Failed(%d)", ret);
                cts_stmt_finalize(stmt);
-               contacts_svc_end_trans(false);
                return ret;
        }
        cts_stmt_finalize(stmt);
@@ -152,11 +152,7 @@ static inline int cts_insert_phonelog(cts_plog *plog)
                        || CTS_PLOG_TYPE_VIDEO_OUTGOING == plog->log_type)
        {
                ret = cts_phonelog_accumulation_handle(plog);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_phonelog_accumulation_handle() Failed");
-                       contacts_svc_end_trans(false);
-                       return ret;
-               }
+               retvm_if(CTS_SUCCESS != ret, ret, "cts_phonelog_accumulation_handle() Failed");
        }
 
        if (CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN == plog->log_type ||
@@ -164,15 +160,9 @@ static inline int cts_insert_phonelog(cts_plog *plog)
                cts_set_missed_call_noti();
 
        cts_set_plog_noti();
-       ret = contacts_svc_end_trans(true);
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
+       return CTS_SUCCESS;
 }
 
-//extra_data1 : duration, message_id
-//extra_data2 : short message
 API int contacts_svc_insert_phonelog(CTSvalue* phone_log)
 {
        int ret;
@@ -181,15 +171,27 @@ API int contacts_svc_insert_phonelog(CTSvalue* phone_log)
        retv_if(NULL == phone_log, CTS_ERR_ARG_NULL);
        retvm_if(plog->id, CTS_ERR_ARG_INVALID, "The phone_log has ID(%d)", plog->id);
 
+       ret = contacts_svc_begin_trans();
+       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
+
        ret = cts_insert_phonelog(plog);
-       retvm_if(CTS_SUCCESS != ret, ret,"cts_insert_phonelog() Failed(%d)", ret);
+       if (CTS_SUCCESS != ret)
+       {
+               ERR("cts_insert_phonelog() Failed(%d)", ret);
+               contacts_svc_end_trans(false);
+               return ret;
+       }
 
        if (0 < plog->related_id) {
                ret = cts_increase_outgoing_count(plog->related_id);
                warn_if(CTS_SUCCESS != ret, "cts_increase_outgoing_count() Failed(%d)", ret);
        }
 
-       return CTS_SUCCESS;
+       ret = contacts_svc_end_trans(true);
+       if (ret < CTS_SUCCESS)
+               return ret;
+       else
+               return CTS_SUCCESS;
 }
 
 API int contacts_svc_delete_phonelog(cts_del_plog_op op_code, ...)
index 19b0a71..71bda48 100755 (executable)
     CTSvalue *plog;
 
     plog = contacts_svc_value_new(CTS_VALUE_PHONELOG);
-    contacts_svc_value_set_str(plog, CTS_PLOG_VAL_NUMBER_STR, "0123456789");
+    contacts_svc_value_set_str(plog, CTS_PLOG_VAL_ADDRESS_STR, "0123456789");
     contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TIME_INT,(int) time(NULL));
     contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TYPE_INT,
                                      CTS_PLOG_TYPE_VOICE_INCOMMING);
     contacts_svc_value_set_int(plog, CTS_PLOG_VAL_DURATION_INT, 65);
     contacts_svc_insert_phonelog(plog);
 
-    contacts_svc_value_set_str(plog, CTS_PLOG_VAL_NUMBER_STR, "0987654321");
+    contacts_svc_value_set_str(plog, CTS_PLOG_VAL_ADDRESS_STR, "0987654321");
     contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TIME_INT,(int) time(NULL));
     contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TYPE_INT,
                                      CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN);
     contacts_svc_value_set_int(plog, CTS_PLOG_VAL_DURATION_INT, 65);
     contacts_svc_insert_phonelog(plog);
 
-    contacts_svc_value_set_str(plog, CTS_PLOG_VAL_NUMBER_STR, "0987654321");
+    contacts_svc_value_set_str(plog, CTS_PLOG_VAL_ADDRESS_STR, "0987654321");
     contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TIME_INT,(int) time(NULL));
     contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TYPE_INT,
                                      CTS_PLOG_TYPE_VOICE_INCOMMING);
@@ -77,7 +77,7 @@ int contacts_svc_insert_phonelog(CTSvalue* phone_log);
  */
 typedef enum{
        CTS_PLOG_DEL_BY_ID, /**< .*/
-       CTS_PLOG_DEL_BY_NUMBER, /**< .*/
+       CTS_PLOG_DEL_BY_NUMBER, /**< number or email address */
        CTS_PLOG_DEL_NO_NUMBER, /**< .*/
        CTS_PLOG_DEL_BY_MSGID, /**< .*/
 }cts_del_plog_op;
@@ -151,7 +151,7 @@ char* contacts_svc_phonelog_get_last_number(cts_plog_get_last_op op);
        return;
     }
 
-    printf("Number : %s\n", contacts_svc_value_get_str(plog, CTS_PLOG_VAL_NUMBER_STR));
+    printf("Number : %s\n", contacts_svc_value_get_str(plog, CTS_PLOG_VAL_ADDRESS_STR));
     printf("Related ID : %d\n", contacts_svc_value_get_int(plog, CTS_PLOG_VAL_ID_INT));
     printf("Time : %d\n", contacts_svc_value_get_int(plog, CTS_PLOG_VAL_LOG_TIME_INT));
     printf("Type : %d\n", contacts_svc_value_get_int(plog, CTS_PLOG_VAL_LOG_TYPE_INT));
diff --git a/src/cts-restriction.c b/src/cts-restriction.c
new file mode 100755 (executable)
index 0000000..ab2b7ab
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjae Shin <yj99.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "cts-internal.h"
+#include "cts-sqlite.h"
+#include "cts-schema.h"
+
+static const char *CTS_RESTRICTION_CHECK_FILE="/opt/data/contacts-svc/.CONTACTS_SVC_RESTRICTION_CHECK";
+static int cts_restriction_permit;
+
+int cts_restriction_init(void)
+{
+       if (!cts_restriction_permit) {
+               int fd = open(CTS_RESTRICTION_CHECK_FILE, O_RDONLY);
+               if (0 <= fd) {
+                       close(fd);
+                       cts_restriction_permit = TRUE;
+               } else {
+                       ERR("Restriction Mode");
+               }
+       }
+       if (!cts_restriction_permit) {
+               int ret;
+               const char *query;
+               query = "CREATE TEMP VIEW "CTS_TABLE_RESTRICTED_DATA_VIEW" AS SELECT * FROM "CTS_TABLE_DATA" WHERE is_restricted != 1";
+
+               ret = cts_query_exec(query);
+               retvm_if(CTS_SUCCESS != ret, ret, "cts_query_exec() Failed(%d)", ret);
+       }
+       return CTS_SUCCESS;
+}
+
+void cts_restriction_final(void)
+{
+       cts_restriction_permit = FALSE;
+}
+
+int cts_restriction_get_permit(void)
+{
+       return cts_restriction_permit;
+}
+
+/**
+ * This function make restricted contact.
+ * If process does not have permission for restriction, this function will be failed.
+ *
+ * @param[in] contact The contacts service struct
+ * @return     #CTS_SUCCESS on success, Negative value(#cts_error) on error
+ */
+API int contacts_svc_struct_set_restriction(CTSstruct *contact)
+{
+       contact_t *record = (contact_t *)contact;
+
+       retv_if(NULL == contact, CTS_ERR_ARG_NULL);
+       retv_if(FALSE == cts_restriction_permit, CTS_ERR_ENV_INVALID);
+
+       record->is_restricted = TRUE;
+
+       return CTS_SUCCESS;
+}
+
diff --git a/src/cts-restriction.h b/src/cts-restriction.h
new file mode 100755 (executable)
index 0000000..3ad8a9a
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjae Shin <yj99.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#ifndef __CTS_FACEBOOK_H__
+#define __CTS_FACEBOOK_H__
+
+int cts_restriction_init(void);
+void cts_restriction_final(void);
+
+int cts_restriction_get_permit(void);
+
+#endif //__CTS_FACEBOOK_H__
+
index 8f72597..c0028c3 100755 (executable)
@@ -32,6 +32,7 @@
 #define CTS_SCHEMA_TABLE_TOTAL 10
 
 // Tables
+#define CTS_TABLE_PERSONS "persons"
 #define CTS_TABLE_CONTACTS "contacts"
 #define CTS_TABLE_GROUPS "groups"
 #define CTS_TABLE_ADDRESSBOOKS "addressbooks"
 #define CTS_TABLE_PHONELOG_ACC "phonelog_accumulation"
 #define CTS_TABLE_GROUPING_INFO "group_relations"
 #define CTS_TABLE_DELETEDS "deleteds"
+#define CTS_TABLE_GROUP_DELETEDS "group_deleteds"
 #define CTS_TABLE_CUSTOM_TYPES "custom_types"
 #define CTS_TABLE_SIM_SERVICES "sim_services"
 #define CTS_TABLE_SPEEDDIALS "speeddials"
 #define CTS_TABLE_VERSION "cts_version"
+#define CTS_TABLE_MY_PROFILES "my_profiles"
+
+#define CTS_TABLE_RESTRICTED_DATA_VIEW "restricted_data"
 
 #define CTS_SCHEMA_DATA_NAME_LANG_INFO "data1"
 #define CTS_SCHEMA_DATA_NAME_LOOKUP "data8"
index ae664a4..a1e5fd6 100755 (executable)
@@ -29,6 +29,7 @@
 #include "cts-normalize.h"
 #include "cts-list.h"
 #include "cts-pthread.h"
+#include "cts-restriction.h"
 #include "cts-service.h"
 
 static int cts_conn_refcnt = 0;
@@ -65,6 +66,13 @@ API int contacts_svc_connect(void)
                        cts_mutex_unlock(CTS_MUTEX_CONNECTION);
                        return ret;
                }
+               ret = cts_restriction_init();
+               if (ret != CTS_SUCCESS) {
+                       ERR("cts_restriction_init() Failed(%d)", ret);
+                       cts_socket_final();
+                       cts_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return ret;
+               }
 
                cts_register_noti();
                cts_conn_refcnt = 1;
@@ -87,6 +95,7 @@ API int contacts_svc_disconnect(void)
                cts_socket_final();
                cts_deregister_noti();
                cts_db_close();
+               cts_restriction_final();
                cts_conn_refcnt--;
        }
        else
index 29dbf8c..a4cf002 100755 (executable)
@@ -134,6 +134,35 @@ int cts_request_sim_import(void)
        return msg.val;
 }
 
+int cts_request_sim_export(int index)
+{
+       int i, ret;
+       cts_socket_msg msg={0};
+       char src[64] = {0};
+
+       retvm_if(-1 == cts_csockfd, CTS_ERR_ENV_INVALID, "socket is not connected");
+
+       snprintf(src, sizeof(src), "%d", index);
+       msg.type = CTS_REQUEST_EXPORT_SIM;
+       msg.attach_num = 1;
+       msg.attach_sizes[0] = strlen(src);
+
+       ret = cts_safe_write(cts_csockfd, (char *)&msg, sizeof(msg));
+       retvm_if(-1 == ret, CTS_ERR_SOCKET_FAILED, "cts_safe_write() Failed(errno = %d)", errno);
+
+       ret = cts_safe_write(cts_csockfd, src, msg.attach_sizes[0]);
+       retvm_if(-1 == ret, CTS_ERR_SOCKET_FAILED, "cts_safe_write() Failed(errno = %d)", errno);
+
+       ret = cts_socket_handle_return(cts_csockfd, &msg);
+       retvm_if(CTS_SUCCESS != ret, ret, "cts_socket_handle_return() Failed(%d)", ret);
+       CTS_DBG("attach_num = %d", msg.attach_num);
+
+       for (i=0;i<msg.attach_num;i++)
+               cts_remove_invalid_msg(cts_csockfd, msg.attach_sizes[i]);
+
+       return msg.val;
+}
+
 int cts_request_normalize_str(const char *src, char *dest, int dest_size)
 {
        int i, ret;
index 4aa8278..2563d07 100755 (executable)
@@ -33,6 +33,7 @@ enum{
        CTS_REQUEST_IMPORT_SIM,
        CTS_REQUEST_NORMALIZE_STR,
        CTS_REQUEST_NORMALIZE_NAME,
+       CTS_REQUEST_EXPORT_SIM,
 };
 //#define CTS_REQUEST_IMPORT_SIM "cts_request_import_sim"
 //#define CTS_REQUEST_NORMALIZE_STR "cts_request_normalize_str"
@@ -53,6 +54,7 @@ int cts_socket_init(void);
 int cts_request_normalize_name(char dest[][CTS_SQL_MAX_LEN]);
 int cts_request_normalize_str(const char * src, char * dest, int dest_size);
 int cts_request_sim_import(void);
+int cts_request_sim_export(int index);
 void cts_socket_final(void);
 
 #endif //__CTS_SOCKET_H__
index e5b0443..bc47d5a 100755 (executable)
@@ -23,6 +23,7 @@
 
 #include "cts-internal.h"
 #include "cts-schema.h"
+#include "cts-im.h"
 #include "cts-sqlite.h"
 
 static sqlite3 *cts_db;
@@ -256,7 +257,7 @@ int cts_stmt_bind_messenger(cts_stmt stmt, int start_cnt, cts_messenger *im_stru
        if (im_struct->im_id)
                sqlite3_bind_text(stmt, start_cnt+1, im_struct->im_id,
                                strlen(im_struct->im_id), SQLITE_STATIC);
-       if (0 == im_struct->type) {
+       if (CTS_IM_TYPE_NONE == im_struct->type) {
                if (im_struct->svc_name)
                        sqlite3_bind_text(stmt, start_cnt+2, im_struct->svc_name,
                                        strlen(im_struct->svc_name), SQLITE_STATIC);
index 094e6bc..056a17b 100755 (executable)
@@ -596,6 +596,8 @@ static inline cts_group* cts_struct_dup_grouprel(const cts_group *src)
                        result->name = strdup(src->name);
                if (src->ringtone_path)
                        result->ringtone_path = strdup(src->ringtone_path);
+               if (src->img_path)
+                       result->img_path = strdup(src->img_path);
        }
 
        return result;
index ff3140b..23b0103 100755 (executable)
@@ -33,12 +33,13 @@ static shortcut_list *favorite_list_mempool=NULL;
 static cts_group *group_list_mempool=NULL;
 static cts_addrbook *addrbook_list_mempool=NULL;
 static sdn_list *sdn_list_mempool=NULL;
+static osp_list *osp_list_mempool=NULL;
+
 
 API CTSstruct* contacts_svc_struct_new(cts_struct_type type)
 {
        CTSstruct* ret_val;
-       switch (type)
-       {
+       switch (type) {
        case CTS_STRUCT_CONTACT:
                ret_val = (CTSstruct*)calloc(1, sizeof(contact_t));
                if (ret_val) ret_val->s_type = CTS_STRUCT_CONTACT;
@@ -75,6 +76,7 @@ static void cts_group_free(gpointer data, gpointer user_data)
 
        free(data0->name);
        free(data0->ringtone_path);
+       free(data0->img_path);
        free(data0->vcard_group);
        free(data);
 }
@@ -248,8 +250,7 @@ API int contacts_svc_struct_free(CTSstruct* structure)
 {
        retv_if(NULL == structure, CTS_ERR_ARG_NULL);
 
-       switch (structure->s_type)
-       {
+       switch (structure->s_type) {
        case CTS_STRUCT_CONTACT:
                cts_contact_free((contact_t *)structure);
                free(structure);
@@ -271,8 +272,7 @@ API int contacts_svc_struct_get_list(CTSstruct *contact,
        retvm_if(CTS_STRUCT_CONTACT != contact->s_type, CTS_ERR_ARG_INVALID,
                        "The contact(%d) must be type of CTS_STRUCT_CONTACT.", contact->s_type);
 
-       switch (field)
-       {
+       switch (field) {
        case CTS_CF_NUMBER_LIST:
                *retlist = record->numbers;
                break;
@@ -312,8 +312,7 @@ static cts_extend* cts_extend_slist_search(int type, GSList *list)
 {
        cts_extend *tmp_extend;
        GSList *tmp_gslist=list;
-       while (tmp_gslist)
-       {
+       while (tmp_gslist) {
                tmp_extend = tmp_gslist->data;
                retvm_if(CTS_VALUE_EXTEND != tmp_extend->v_type, NULL,
                                "List has other type");
@@ -328,8 +327,7 @@ static inline int cts_contact_get_value(contact_t *contact,
                cts_struct_field field, CTSvalue** retval)
 {
 
-       switch (field)
-       {
+       switch (field) {
        case CTS_CF_NAME_VALUE:
                *retval = (CTSvalue *)contact->name;
                break;
@@ -359,8 +357,7 @@ API int contacts_svc_struct_get_value(CTSstruct *structure,
        retv_if(NULL == structure, CTS_ERR_ARG_NULL);
        retv_if(NULL == retval, CTS_ERR_ARG_NULL);
 
-       switch (structure->s_type)
-       {
+       switch (structure->s_type) {
        case CTS_STRUCT_CONTACT:
                ret = cts_contact_get_value((contact_t *)structure, field, retval);
                if (CTS_SUCCESS != ret)
@@ -395,24 +392,19 @@ static inline int cts_struct_store_num_list(contact_t *contact, GSList* list)
        cts_number *tmp_number;
 
        GSList *new_gslist=NULL, *tmp_gslist=list, *prev=NULL;
-       if (contact->numbers && tmp_gslist == contact->numbers)
-       {
-               while (tmp_gslist)
-               {
+       if (contact->numbers && tmp_gslist == contact->numbers) {
+               while (tmp_gslist) {
                        tmp_number = tmp_gslist->data;
-                       if (tmp_number)
-                       {
+                       if (tmp_number) {
                                retvm_if(CTS_VALUE_NUMBER != tmp_number->v_type, CTS_ERR_ARG_INVALID,
                                                "List has other type");
 
-                               if (!tmp_number->id && tmp_number->deleted)
-                               {
+                               if (!tmp_number->id && tmp_number->deleted) {
                                        CTS_REMOVE_GSLIST_ITEM(number, numbers);
                                        continue;
                                }
 
-                               if (!tmp_number->embedded)
-                               {
+                               if (!tmp_number->embedded) {
                                        tmp_number->embedded = true;
                                        tmp_number->number = SAFE_STRDUP(tmp_number->number);
                                }
@@ -421,17 +413,13 @@ static inline int cts_struct_store_num_list(contact_t *contact, GSList* list)
                        tmp_gslist = tmp_gslist->next;
                }
        }
-       else
-       {
-               while (tmp_gslist)
-               {
+       else {
+               while (tmp_gslist) {
                        tmp_number = tmp_gslist->data;
-                       if (tmp_number)
-                       {
+                       if (tmp_number) {
                                retvm_if(tmp_number && CTS_VALUE_NUMBER != tmp_number->v_type, CTS_ERR_ARG_INVALID,
                                                "List has other type");
-                               if (!tmp_number->embedded)
-                               {
+                               if (!tmp_number->embedded) {
                                        tmp_number->embedded = true;
                                        tmp_number->number = SAFE_STRDUP(tmp_number->number);
                                        new_gslist = g_slist_append(new_gslist, tmp_number);
@@ -449,13 +437,10 @@ static inline int cts_struct_store_email_list(contact_t *contact, GSList* list)
        cts_email *tmp_email;
 
        GSList *new_gslist=NULL, *tmp_gslist=list, *prev=NULL;
-       if (contact->emails && tmp_gslist == contact->emails)
-       {
-               while (tmp_gslist)
-               {
+       if (contact->emails && tmp_gslist == contact->emails) {
+               while (tmp_gslist) {
                        tmp_email = tmp_gslist->data;
-                       if (tmp_email)
-                       {
+                       if (tmp_email) {
                                retvm_if(CTS_VALUE_EMAIL != tmp_email->v_type, CTS_ERR_ARG_INVALID,
                                                "List has other type");
 
@@ -464,8 +449,7 @@ static inline int cts_struct_store_email_list(contact_t *contact, GSList* list)
                                        continue;
                                }
 
-                               if (!tmp_email->embedded)
-                               {
+                               if (!tmp_email->embedded) {
                                        tmp_email->embedded = true;
                                        tmp_email->email_addr = SAFE_STRDUP(tmp_email->email_addr);
                                }
@@ -474,17 +458,13 @@ static inline int cts_struct_store_email_list(contact_t *contact, GSList* list)
                        tmp_gslist = tmp_gslist->next;
                }
        }
-       else
-       {
-               while (tmp_gslist)
-               {
+       else {
+               while (tmp_gslist) {
                        tmp_email = tmp_gslist->data;
-                       if (tmp_email)
-                       {
+                       if (tmp_email) {
                                retvm_if(CTS_VALUE_EMAIL != tmp_email->v_type, CTS_ERR_ARG_INVALID,
                                                "List has other type");
-                               if (!tmp_email->embedded)
-                               {
+                               if (!tmp_email->embedded) {
                                        tmp_email->embedded = true;
                                        tmp_email->email_addr = SAFE_STRDUP(tmp_email->email_addr);
                                        new_gslist = g_slist_append(new_gslist, tmp_email);
@@ -502,13 +482,10 @@ static inline int cts_struct_store_grouprel_list(contact_t *contact, GSList* lis
        cts_group *tmp_group;
 
        GSList *new_gslist=NULL, *tmp_gslist=list, *prev=NULL;
-       if (contact->grouprelations && tmp_gslist == contact->grouprelations)
-       {
-               while (tmp_gslist)
-               {
+       if (contact->grouprelations && tmp_gslist == contact->grouprelations) {
+               while (tmp_gslist) {
                        tmp_group = tmp_gslist->data;
-                       if (tmp_group)
-                       {
+                       if (tmp_group) {
                                retvm_if(CTS_VALUE_GROUP_RELATION != tmp_group->v_type, CTS_ERR_ARG_INVALID,
                                                "List has other type");
 
@@ -523,17 +500,13 @@ static inline int cts_struct_store_grouprel_list(contact_t *contact, GSList* lis
                        tmp_gslist = tmp_gslist->next;
                }
        }
-       else
-       {
-               while (tmp_gslist)
-               {
+       else {
+               while (tmp_gslist) {
                        tmp_group = tmp_gslist->data;
-                       if (tmp_group)
-                       {
+                       if (tmp_group) {
                                retvm_if(CTS_VALUE_GROUP_RELATION != tmp_group->v_type, CTS_ERR_ARG_INVALID,
                                                "List has other type");
-                               if (!tmp_group->embedded)
-                               {
+                               if (!tmp_group->embedded) {
                                        tmp_group->embedded = true;
                                        new_gslist = g_slist_append(new_gslist, tmp_group);
                                }
@@ -550,13 +523,10 @@ static inline int cts_struct_store_event_list(contact_t *contact, GSList* list)
        cts_event *tmp_event;
 
        GSList *new_gslist=NULL, *tmp_gslist=list, *prev=NULL;
-       if (contact->events && tmp_gslist == contact->events)
-       {
-               while (tmp_gslist)
-               {
+       if (contact->events && tmp_gslist == contact->events) {
+               while (tmp_gslist) {
                        tmp_event = tmp_gslist->data;
-                       if (tmp_event)
-                       {
+                       if (tmp_event) {
                                retvm_if(CTS_VALUE_EVENT != tmp_event->v_type, CTS_ERR_ARG_INVALID,
                                                "List has other type");
 
@@ -571,17 +541,13 @@ static inline int cts_struct_store_event_list(contact_t *contact, GSList* list)
                        tmp_gslist = tmp_gslist->next;
                }
        }
-       else
-       {
-               while (tmp_gslist)
-               {
+       else {
+               while (tmp_gslist) {
                        tmp_event = tmp_gslist->data;
-                       if (tmp_event)
-                       {
+                       if (tmp_event) {
                                retvm_if(CTS_VALUE_EVENT != tmp_event->v_type, CTS_ERR_ARG_INVALID,
                                                "List has other type");
-                               if (!tmp_event->embedded)
-                               {
+                               if (!tmp_event->embedded) {
                                        tmp_event->embedded = true;
                                        new_gslist = g_slist_append(new_gslist, tmp_event);
                                }
@@ -598,13 +564,10 @@ static inline int cts_struct_store_messenger_list(contact_t *contact, GSList* li
        cts_messenger *tmp_messenger;
 
        GSList *new_gslist=NULL, *tmp_gslist=list, *prev=NULL;
-       if (contact->messengers && tmp_gslist == contact->messengers)
-       {
-               while (tmp_gslist)
-               {
+       if (contact->messengers && tmp_gslist == contact->messengers) {
+               while (tmp_gslist) {
                        tmp_messenger = tmp_gslist->data;
-                       if (tmp_messenger)
-                       {
+                       if (tmp_messenger) {
                                retvm_if(CTS_VALUE_MESSENGER != tmp_messenger->v_type, CTS_ERR_ARG_INVALID,
                                                "List has other type");
 
@@ -624,17 +587,13 @@ static inline int cts_struct_store_messenger_list(contact_t *contact, GSList* li
                        tmp_gslist = tmp_gslist->next;
                }
        }
-       else
-       {
-               while (tmp_gslist)
-               {
+       else {
+               while (tmp_gslist) {
                        tmp_messenger = tmp_gslist->data;
-                       if (tmp_messenger)
-                       {
+                       if (tmp_messenger) {
                                retvm_if(CTS_VALUE_MESSENGER != tmp_messenger->v_type, CTS_ERR_ARG_INVALID,
                                                "List has other type");
-                               if (!tmp_messenger->embedded)
-                               {
+                               if (!tmp_messenger->embedded) {
                                        tmp_messenger->embedded = true;
                                        tmp_messenger->im_id = SAFE_STRDUP(tmp_messenger->im_id);
                                        tmp_messenger->svc_name = SAFE_STRDUP(tmp_messenger->svc_name);
@@ -654,13 +613,10 @@ static inline int cts_struct_store_postal_list(contact_t *contact, GSList* list)
        cts_postal *tmp_postal;
 
        GSList *new_gslist=NULL, *tmp_gslist=list, *prev=NULL;
-       if (contact->postal_addrs && tmp_gslist == contact->postal_addrs)
-       {
-               while (tmp_gslist)
-               {
+       if (contact->postal_addrs && tmp_gslist == contact->postal_addrs) {
+               while (tmp_gslist) {
                        tmp_postal = tmp_gslist->data;
-                       if (tmp_postal)
-                       {
+                       if (tmp_postal) {
                                retvm_if(CTS_VALUE_POSTAL != tmp_postal->v_type, CTS_ERR_ARG_INVALID,
                                                "List has other type");
 
@@ -684,11 +640,9 @@ static inline int cts_struct_store_postal_list(contact_t *contact, GSList* list)
                        tmp_gslist = tmp_gslist->next;
                }
        }
-       else
-       {
+       else {
                //retvm_if(NULL != contact->postal_addrs, CTS_ERR_ARG_INVALID, "New list can be stored when struct has no list");
-               while (tmp_gslist)
-               {
+               while (tmp_gslist) {
                        tmp_postal = tmp_gslist->data;
                        if (tmp_postal) {
                                retvm_if(tmp_postal && CTS_VALUE_POSTAL != tmp_postal->v_type, CTS_ERR_ARG_INVALID,
@@ -717,13 +671,10 @@ static inline int cts_struct_store_web_list(contact_t *contact, GSList* list)
        cts_web *tmp_web;
 
        GSList *new_gslist=NULL, *tmp_gslist=list, *prev=NULL;
-       if (contact->web_addrs && tmp_gslist == contact->web_addrs)
-       {
-               while (tmp_gslist)
-               {
+       if (contact->web_addrs && tmp_gslist == contact->web_addrs) {
+               while (tmp_gslist) {
                        tmp_web = tmp_gslist->data;
-                       if (tmp_web)
-                       {
+                       if (tmp_web) {
                                retvm_if(CTS_VALUE_WEB != tmp_web->v_type, CTS_ERR_ARG_INVALID,
                                                "List has other type");
 
@@ -741,13 +692,10 @@ static inline int cts_struct_store_web_list(contact_t *contact, GSList* list)
                        tmp_gslist = tmp_gslist->next;
                }
        }
-       else
-       {
-               while (tmp_gslist)
-               {
+       else {
+               while (tmp_gslist) {
                        tmp_web = tmp_gslist->data;
-                       if (tmp_web)
-                       {
+                       if (tmp_web) {
                                retvm_if(tmp_web && CTS_VALUE_WEB != tmp_web->v_type, CTS_ERR_ARG_INVALID,
                                                "List has other type");
                                if (!tmp_web->embedded) {
@@ -768,13 +716,10 @@ static inline int cts_struct_store_nickname_list(contact_t *contact, GSList* lis
        cts_nickname *tmp_nickname;
 
        GSList *new_gslist=NULL, *tmp_gslist=list, *prev=NULL;
-       if (contact->nicknames && tmp_gslist == contact->nicknames)
-       {
-               while (tmp_gslist)
-               {
+       if (contact->nicknames && tmp_gslist == contact->nicknames) {
+               while (tmp_gslist) {
                        tmp_nickname = tmp_gslist->data;
-                       if (tmp_nickname)
-                       {
+                       if (tmp_nickname) {
                                retvm_if(CTS_VALUE_NICKNAME != tmp_nickname->v_type, CTS_ERR_ARG_INVALID,
                                                "List has other type");
 
@@ -792,17 +737,14 @@ static inline int cts_struct_store_nickname_list(contact_t *contact, GSList* lis
                        tmp_gslist = tmp_gslist->next;
                }
        }
-       else
-       {
+       else {
                //retvm_if(NULL != contact->web_addrs, CTS_ERR_ARG_INVALID, "New list can be stored when struct has no list");
-               while (tmp_gslist)
-               {
+               while (tmp_gslist) {
                        tmp_nickname = tmp_gslist->data;
                        if (tmp_nickname) {
                                retvm_if(tmp_nickname && CTS_VALUE_NICKNAME != tmp_nickname->v_type, CTS_ERR_ARG_INVALID,
                                                "List has other type");
-                               if (!tmp_nickname->embedded)
-                               {
+                               if (!tmp_nickname->embedded) {
                                        tmp_nickname->embedded = true;
                                        tmp_nickname->nick = SAFE_STRDUP(tmp_nickname->nick);
                                        new_gslist = g_slist_append(new_gslist, tmp_nickname);
@@ -825,8 +767,7 @@ API int contacts_svc_struct_store_list(CTSstruct *contact,
        retvm_if(CTS_STRUCT_CONTACT != contact->s_type, CTS_ERR_ARG_INVALID,
                        "The contact(%d) must be type of CTS_STRUCT_CONTACT.", contact->s_type);
 
-       switch (field)
-       {
+       switch (field) {
        case CTS_CF_NUMBER_LIST:
                ret = cts_struct_store_num_list((contact_t *)contact, list);
                retvm_if(CTS_SUCCESS != ret, ret, "cts_struct_store_num_list() Failed(%d)",ret);
@@ -869,8 +810,7 @@ API int contacts_svc_struct_store_list(CTSstruct *contact,
 
 static inline void cts_contact_store_name(contact_t *contact, cts_name *value)
 {
-       if (contact->name)
-       {
+       if (contact->name) {
                if (value->is_changed) {
                        FREEandSTRDUP(contact->name->first, value->first);
                        FREEandSTRDUP(contact->name->last, value->last);
@@ -881,8 +821,7 @@ static inline void cts_contact_store_name(contact_t *contact, cts_name *value)
                        contact->name->is_changed = true;
                }
        }
-       else
-       {
+       else {
                //contact->name = (cts_name *)contacts_svc_value_new(CTS_VALUE_NAME);
                contact->name = value;
                contact->name->embedded = true;
@@ -897,8 +836,7 @@ static inline void cts_contact_store_name(contact_t *contact, cts_name *value)
 
 static inline void cts_contact_store_base(contact_t *contact, cts_ct_base *value)
 {
-       if (contact->base)
-       {
+       if (contact->base) {
                if (value->uid_changed) {
                        FREEandSTRDUP(contact->base->uid, value->uid);
                        contact->base->uid_changed = true;
@@ -920,8 +858,7 @@ static inline void cts_contact_store_base(contact_t *contact, cts_ct_base *value
                        contact->base->note_changed = true;
                }
        }
-       else
-       {
+       else {
                contact->base = value;
                contact->base->embedded = true;
                contact->base->uid = SAFE_STRDUP(value->uid);
@@ -934,16 +871,14 @@ static inline void cts_contact_store_base(contact_t *contact, cts_ct_base *value
 
 static inline void cts_contact_store_company(contact_t *contact, cts_company *value)
 {
-       if (contact->company)
-       {
+       if (contact->company) {
                FREEandSTRDUP(contact->company->name, value->name);
                FREEandSTRDUP(contact->company->department, value->department);
                FREEandSTRDUP(contact->company->jot_title, value->jot_title);
                FREEandSTRDUP(contact->company->role, value->role);
                FREEandSTRDUP(contact->company->assistant_name, value->assistant_name);
        }
-       else
-       {
+       else {
                //contact->company = (cts_company *)contacts_svc_value_new(CTS_VALUE_COMPANY);
                contact->company = value;
                contact->company->embedded = true;
@@ -961,8 +896,7 @@ static inline int cts_contact_store_extend(contact_t *contact,
        cts_extend *stored_extend;
 
        stored_extend = cts_extend_slist_search(type, contact->extended_values);
-       if (NULL == stored_extend)
-       {
+       if (NULL == stored_extend) {
                retvm_if(value->embedded, CTS_ERR_ARG_INVALID, "This Value is already stored");
                value->embedded = true;
                value->type = type;
@@ -977,8 +911,7 @@ static inline int cts_contact_store_extend(contact_t *contact,
                value->data9 = SAFE_STRDUP(value->data9);
                value->data10 = SAFE_STRDUP(value->data10);
        }
-       else
-       {
+       else {
                retvm_if(stored_extend == value, CTS_SUCCESS, "This value is already stored");
 
                FREEandSTRDUP(stored_extend->data2, value->data2);
@@ -1007,8 +940,7 @@ API int contacts_svc_struct_store_value(CTSstruct *contact,
        CTS_DBG("contact type = %d, field = %d, value type = %d",
                        contact->s_type, field, value->v_type);
 
-       switch (field)
-       {
+       switch (field) {
        case CTS_CF_NAME_VALUE:
                retvm_if(CTS_VALUE_NAME != value->v_type, CTS_ERR_ARG_INVALID,
                                "The value must be a CTS_VALUE_NAME for field(CTS_CF_NAME_VALUE).");
@@ -1041,8 +973,7 @@ API int contacts_svc_struct_store_value(CTSstruct *contact,
 API CTSvalue* contacts_svc_value_new(cts_value_type type)
 {
        CTSvalue* ret_val;
-       switch ((int)type)
-       {
+       switch ((int)type) {
        case CTS_VALUE_BASIC:
                ret_val = (CTSvalue*)calloc(1, sizeof(cts_basic));
                break;
@@ -1162,6 +1093,15 @@ API CTSvalue* contacts_svc_value_new(cts_value_type type)
                else
                        ret_val = (CTSvalue*)calloc(1, sizeof(sdn_list));
                break;
+       case CTS_VALUE_LIST_OSP:
+               if (osp_list_mempool) {
+                       memset(osp_list_mempool, 0x00, sizeof(osp_list));
+                       ret_val = (CTSvalue*)osp_list_mempool;
+                       osp_list_mempool = NULL;
+               }
+               else
+                       ret_val = (CTSvalue*)calloc(1, sizeof(osp_list));
+               break;
        default:
                ERR("your type is Not supported");
                return NULL;
@@ -1186,9 +1126,9 @@ static inline void cts_internal_value_info_free(CTSvalue *value)
        cts_group *group;
        cts_addrbook *ab;
        sdn_list *sdn;
+       osp_list *osp;
 
-       switch (value->v_type)
-       {
+       switch (value->v_type) {
        case CTS_VALUE_LIST_CONTACT:
        case CTS_VALUE_LIST_NUMBERINFO:
        case CTS_VALUE_LIST_EMAILINFO:
@@ -1207,6 +1147,23 @@ static inline void cts_internal_value_info_free(CTSvalue *value)
                        if (contact_list_mempool != contact)
                                free(contact);
                break;
+       case CTS_VALUE_LIST_OSP:
+               osp = (osp_list *)value;
+               free(osp->img_path);
+               free(osp->first);
+               free(osp->last);
+               free(osp->display);
+               free(osp->def_num);
+               free(osp->def_email);
+               free(osp->normalize);
+
+               if (!osp_list_mempool) {
+                       osp_list_mempool = osp;
+               }
+               else
+                       if (osp_list_mempool != osp)
+                               free(osp);
+               break;
        case CTS_VALUE_LIST_PLOG:
                plog = (plog_list *)value;
                free(plog->first);
@@ -1243,6 +1200,9 @@ static inline void cts_internal_value_info_free(CTSvalue *value)
        case CTS_VALUE_LIST_GROUP:
                group = (cts_group *)value;
                free(group->name);
+               free(group->ringtone_path);
+               free(group->img_path);
+               free(group->vcard_group);
 
                if (!group_list_mempool) {
                        group_list_mempool = group;
@@ -1325,6 +1285,7 @@ API int contacts_svc_value_free(CTSvalue *value)
                        if (value->embedded) {
                                free(((cts_group *)value)->name);
                                free(((cts_group *)value)->ringtone_path);
+                               free(((cts_group *)value)->img_path);
                        }
                        break;
                case CTS_VALUE_ADDRESSBOOK:
@@ -1356,8 +1317,7 @@ static inline int cts_value_get_int_base(cts_ct_base *value, int field)
 {
        int ret = 0;
 
-       switch (field)
-       {
+       switch (field) {
        case CTS_BASE_VAL_ID_INT:
                ret = value->id;
                break;
@@ -1367,6 +1327,9 @@ static inline int cts_value_get_int_base(cts_ct_base *value, int field)
        case CTS_BASE_VAL_ADDRESSBOOK_ID_INT:
                ret = value->addrbook_id;
                break;
+       case CTS_BASE_VAL_PERSON_ID_INT:
+               ret = value->person_id;
+               break;
        default:
                ERR("The field(%d) is not supported in value(Base_info)", field);
                break;
@@ -1378,8 +1341,7 @@ static inline int cts_value_get_int_plog_list(plog_list *value, int field)
 {
        int ret = 0;
 
-       switch (field)
-       {
+       switch (field) {
        case CTS_LIST_PLOG_ID_INT:
                ret = value->id;
                break;
@@ -1410,8 +1372,7 @@ static inline int cts_value_get_int_plog(cts_plog *value, int field)
 {
        int ret = 0;
 
-       switch (field)
-       {
+       switch (field) {
        case CTS_PLOG_VAL_ID_INT:
                ret = value->id;
                break;
@@ -1439,8 +1400,7 @@ static inline int cts_value_get_int_change_list(change_list *value, int field)
 {
        int ret = 0;
 
-       switch (field)
-       {
+       switch (field) {
        case CTS_LIST_CHANGE_ID_INT:
                ret = value->id;
                break;
@@ -1450,6 +1410,9 @@ static inline int cts_value_get_int_change_list(change_list *value, int field)
        case CTS_LIST_CHANGE_VER_INT:
                ret = value->changed_ver;
                break;
+       case CTS_LIST_CHANGE_ADDRESSBOOK_ID_INT:
+               ret = value->addressbook_id;
+               break;
        default:
                ERR("The field(%d) is not supported in value(change list)", field);
                break;
@@ -1461,8 +1424,7 @@ static inline int cts_value_get_int_shortcut_list(shortcut_list *value, int fiel
 {
        int ret = 0;
 
-       switch (field)
-       {
+       switch (field) {
        case CTS_LIST_SHORTCUT_ID_INT:
                ret = value->id;
                break;
@@ -1486,8 +1448,7 @@ static inline int cts_value_get_int_addrbook(cts_addrbook *value, int field)
 {
        int ret = 0;
 
-       switch (field)
-       {
+       switch (field) {
        case CTS_ADDRESSBOOK_VAL_ID_INT:
                ret = value->id;
                break;
@@ -1507,13 +1468,39 @@ static inline int cts_value_get_int_addrbook(cts_addrbook *value, int field)
        return ret;
 }
 
+static inline int cts_value_get_int_osp(osp_list *value, int field)
+{
+       int ret = 0;
+
+       switch (field) {
+       case CTS_LIST_OSP_PERSON_ID_INT:
+               ret = value->person_id;
+               break;
+       case CTS_LIST_OSP_CONTACT_ID_INT:
+               ret = value->contact_id;
+               break;
+       case CTS_LIST_OSP_ADDRESSBOOK_ID_INT:
+               ret = value->addrbook_id;
+               break;
+       case CTS_LIST_OSP_DEF_NUM_TYPE_INT:
+               ret = value->def_num_type;
+               break;
+       case CTS_LIST_OSP_DEF_EMAIL_TYPE_INT:
+               ret = value->def_email_type;
+               break;
+       default:
+               ERR("The field(%d) is not supported in value(osp_list)", field);
+               break;
+       }
+       return ret;
+}
+
 API int contacts_svc_value_get_int(CTSvalue *value, int field)
 {
        int ret = 0;
        retvm_if(NULL == value, 0, "The Parameter(value) is NULL");
 
-       switch (value->v_type)
-       {
+       switch (value->v_type) {
        case CTS_VALUE_BASIC:
                retvm_if(CTS_BASIC_VAL_INT != ((cts_basic*)value)->type, 0,
                                "The type of Basic_value is not integer");
@@ -1555,9 +1542,11 @@ API int contacts_svc_value_get_int(CTSvalue *value, int field)
        case CTS_VALUE_LIST_CONTACT:
        case CTS_VALUE_LIST_NUMS_EMAILS:
                if (CTS_LIST_CONTACT_ID_INT == field)
-                       ret = ((contact_list *)value)->id;
+                       ret = ((contact_list *)value)->contact_id;
                else if (CTS_LIST_CONTACT_ADDRESSBOOK_ID_INT == field)
-                       ret = ((contact_list *)value)->acc_id;
+                       ret = ((contact_list *)value)->addrbook_id;
+               else if (CTS_LIST_CONTACT_PERSON_ID_INT == field)
+                       ret = ((contact_list *)value)->person_id;
                else
                        ERR("The field(%d) is not supported in value(contact_list)", field);
                break;
@@ -1567,9 +1556,12 @@ API int contacts_svc_value_get_int(CTSvalue *value, int field)
                break;
        case CTS_VALUE_LIST_NUMBERINFO:
        case CTS_VALUE_LIST_EMAILINFO: // CTS_LIST_EMAIL_CONTACT_ID_INT is same to CTS_LIST_NUM_CONTACT_ID_INT
-               retvm_if(CTS_LIST_NUM_CONTACT_ID_INT != field, 0,
-                               "The field(%d) is not supported in value(Number list)", field);
-               ret = ((contact_list*)value)->id;
+               if (CTS_LIST_NUM_CONTACT_ID_INT == field)
+                       ret = ((contact_list *)value)->contact_id;
+               else if (CTS_LIST_NUM_PERSON_ID_INT == field)
+                       ret = ((contact_list *)value)->person_id;
+               else
+                       ERR("The field(%d) is not supported in value(Number list)", field);
                break;
        case CTS_VALUE_LIST_CUSTOM_NUM_TYPE:
                if (CTS_LIST_CUSTOM_NUM_TYPE_ID_INT == field)
@@ -1631,6 +1623,9 @@ API int contacts_svc_value_get_int(CTSvalue *value, int field)
                else
                        ERR("Not supported field(%d)", field);
                break;
+       case CTS_VALUE_LIST_OSP:
+               ret = cts_value_get_int_osp((osp_list *)value, field);
+               break;
        case CTS_VALUE_PHONELOG:
                /* phonelog value is write only */
        case CTS_VALUE_COMPANY:
@@ -1638,7 +1633,7 @@ API int contacts_svc_value_get_int(CTSvalue *value, int field)
        case CTS_VALUE_NAME:
                /* name value doesn't have interger value */
        default:
-               ERR("The value has unsupported type");
+               ERR("The value has unsupported type(%d)", value->v_type);
                break;
        }
        return ret;
@@ -1648,8 +1643,7 @@ double contacts_svc_value_get_dbl(CTSvalue *value, int field)
 {
        retv_if(NULL == value, CTS_ERR_ARG_NULL);
 
-       switch (value->v_type)
-       {
+       switch (value->v_type) {
        case CTS_VALUE_BASIC:
                retvm_if(CTS_BASIC_VAL_DBL != ((cts_basic*)value)->type, 0.0,
                                "The type of value is not double");
@@ -1664,7 +1658,7 @@ double contacts_svc_value_get_dbl(CTSvalue *value, int field)
        case CTS_VALUE_GROUP_RELATION:
        case CTS_VALUE_COMPANY:
        default:
-               ERR("The value has unsupported type");
+               ERR("The value has unsupported type(%d)", value->v_type);
                return CTS_ERR_ARG_INVALID;
        }
 
@@ -1672,10 +1666,9 @@ double contacts_svc_value_get_dbl(CTSvalue *value, int field)
 
 API bool contacts_svc_value_get_bool(CTSvalue *value, int field)
 {
-       retvm_if(NULL == value, false, "The Parameter(value) is NULL");
+       retv_if(NULL == value, false);
 
-       switch (value->v_type)
-       {
+       switch (value->v_type) {
        case CTS_VALUE_CONTACT_BASE_INFO:
                if (CTS_BASE_VAL_FAVORITE_BOOL == field) {
                        return ((cts_ct_base*)value)->is_favorite;
@@ -1789,7 +1782,7 @@ API bool contacts_svc_value_get_bool(CTSvalue *value, int field)
        case CTS_VALUE_COMPANY:
                /* company value doesn't have boolean value */
        default:
-               ERR("The value has unsupported type");
+               ERR("The value has unsupported type(%d)", value->v_type);
                return false;
        }
 }
@@ -1799,8 +1792,7 @@ static inline char* cts_value_get_str_name(int op_code,
 {
        char *ret_val;
 
-       switch (field)
-       {
+       switch (field) {
        case CTS_NAME_VAL_FIRST_STR:
                HANDLE_STEAL_STRING(op_code, ret_val, value->first);
                break;
@@ -1832,8 +1824,7 @@ static inline char* cts_value_get_str_extend(int op_code,
 {
        char *ret_val;
 
-       switch (field)
-       {
+       switch (field) {
        case CTS_EXTEND_VAL_DATA2_STR:
                HANDLE_STEAL_STRING(op_code, ret_val, value->data2);
                break;
@@ -1874,8 +1865,7 @@ static inline char* cts_value_get_str_base(int op_code,
 {
        char *ret_val;
 
-       switch (field)
-       {
+       switch (field) {
        case CTS_BASE_VAL_IMG_PATH_STR:
                HANDLE_STEAL_STRING(op_code, ret_val, value->img_path);
                if (NULL == ret_val && value->vcard_img_path) {
@@ -1909,8 +1899,7 @@ static inline char* cts_value_get_str_contact_list(int op_code,
                contact_list *value, int field)
 {
        char *ret_val;
-       switch (field)
-       {
+       switch (field) {
        case CTS_LIST_CONTACT_FIRST_STR:
                HANDLE_STEAL_STRING(op_code, ret_val, value->first);
                break;
@@ -1947,8 +1936,7 @@ static inline char* cts_value_get_str_num_email_list(int op_code,
                contact_list *value, int field)
 {
        char *ret_val;
-       switch (field)
-       {
+       switch (field) {
        case CTS_LIST_NUM_CONTACT_FIRST_STR:
                HANDLE_STEAL_STRING(op_code, ret_val, value->first);
                break;
@@ -1972,12 +1960,45 @@ static inline char* cts_value_get_str_num_email_list(int op_code,
        return ret_val;
 }
 
+static inline char* cts_value_get_str_osp_list(int op_code,
+               osp_list *value, int field)
+{
+       char *ret_val;
+       switch (field) {
+       case CTS_LIST_OSP_FIRST_STR:
+               HANDLE_STEAL_STRING(op_code, ret_val, value->first);
+               break;
+       case CTS_LIST_OSP_LAST_STR:
+               HANDLE_STEAL_STRING(op_code, ret_val, value->last);
+               break;
+       case CTS_LIST_OSP_DISPLAY_STR:
+               HANDLE_STEAL_STRING(op_code, ret_val, value->display);
+               break;
+       case CTS_LIST_OSP_IMG_PATH_STR:
+               HANDLE_STEAL_STRING(op_code, ret_val, value->img_path);
+               break;
+       case CTS_LIST_OSP_DEF_NUM_STR:
+               HANDLE_STEAL_STRING(op_code, ret_val, value->def_num);
+               break;
+       case CTS_LIST_OSP_DEF_EMAIL_STR:
+               HANDLE_STEAL_STRING(op_code, ret_val, value->def_email);
+               break;
+       case CTS_LIST_OSP_NORMALIZED_STR:
+               HANDLE_STEAL_STRING(op_code, ret_val, value->normalize);
+               break;
+       default:
+               ERR("The parameter(field:%d) is not interpreted", field);
+               ret_val = NULL;
+               break;
+       }
+       return ret_val;
+}
+
 static inline char* cts_value_get_str_favorite_list(int op_code,
                shortcut_list *value, int field)
 {
        char *ret_val;
-       switch (field)
-       {
+       switch (field) {
        case CTS_LIST_SHORTCUT_FIRST_NAME_STR:
                HANDLE_STEAL_STRING(op_code, ret_val, value->first);
                break;
@@ -2005,8 +2026,7 @@ static inline char* cts_value_get_str_plog_list(int op_code,
                plog_list *value, int field)
 {
        char *ret_val;
-       switch (field)
-       {
+       switch (field) {
        case CTS_LIST_PLOG_FIRST_NAME_STR:
                HANDLE_STEAL_STRING(op_code, ret_val, value->first);
                break;
@@ -2037,8 +2057,7 @@ static inline char* cts_value_get_str_postal(int op_code,
                cts_postal *value, int field)
 {
        char *ret_val;
-       switch (field)
-       {
+       switch (field) {
        case CTS_POSTAL_VAL_POBOX_STR:
                HANDLE_STEAL_STRING(op_code, ret_val, value->pobox);
                break;
@@ -2072,8 +2091,7 @@ static inline char* cts_value_get_str_company(int op_code,
                cts_company *value, int field)
 {
        char *ret_val;
-       switch (field)
-       {
+       switch (field) {
        case CTS_COMPANY_VAL_NAME_STR:
                HANDLE_STEAL_STRING(op_code, ret_val, value->name);
                break;
@@ -2102,8 +2120,7 @@ static inline char* cts_value_get_str_im(int op_code,
                cts_messenger *value, int field)
 {
        char *ret_val;
-       switch (field)
-       {
+       switch (field) {
        case CTS_MESSENGER_VAL_IM_ID_STR:
                HANDLE_STEAL_STRING(op_code, ret_val, value->im_id);
                break;
@@ -2121,13 +2138,39 @@ static inline char* cts_value_get_str_im(int op_code,
        return ret_val;
 }
 
+static inline char* cts_value_get_str_group(int op_code,
+               cts_group *value, int field)
+{
+       char *ret_val;
+       switch (field) {
+       case CTS_GROUP_VAL_NAME_STR:
+               HANDLE_STEAL_STRING(op_code, ret_val, value->name);
+               break;
+       case CTS_GROUP_VAL_RINGTONE_STR:
+               HANDLE_STEAL_STRING(op_code, ret_val, value->ringtone_path);
+               break;
+       case CTS_GROUP_VAL_IMG_PATH_STR:
+               if (false == value->img_loaded) {
+                       value->img_path = cts_get_img(CTS_GROUP_IMAGE_LOCATION, value->id, NULL, 0);
+                       value->img_loaded = true;
+               }
+               HANDLE_STEAL_STRING(op_code, ret_val, value->img_path);
+               break;
+       default:
+               ERR("The parameter(field:%d) is not interpreted", field);
+               ret_val = NULL;
+               break;
+       }
+
+       return ret_val;
+}
+
 static char* cts_value_handle_str(int op_code, CTSvalue *value, int field)
 {
        char *ret_val;
        retvm_if(NULL == value, NULL, "The Parameter(value) is NULL");
 
-       switch (value->v_type)
-       {
+       switch (value->v_type) {
        case CTS_VALUE_BASIC:
                retvm_if(CTS_BASIC_VAL_STR != ((cts_basic *)value)->type, NULL,
                                "The type of value is not string");
@@ -2154,6 +2197,9 @@ static char* cts_value_handle_str(int op_code, CTSvalue *value, int field)
        case CTS_VALUE_LIST_NUMS_EMAILS:
                ret_val = cts_value_get_str_contact_list(op_code, (contact_list *)value, field);
                break;
+       case CTS_VALUE_LIST_OSP:
+               ret_val = cts_value_get_str_osp_list(op_code, (osp_list *)value, field);
+               break;
        case CTS_VALUE_LIST_NUMBERINFO:
        case CTS_VALUE_LIST_EMAILINFO:
                ret_val = cts_value_get_str_num_email_list(op_code, (contact_list *)value, field);
@@ -2167,8 +2213,13 @@ static char* cts_value_handle_str(int op_code, CTSvalue *value, int field)
        case CTS_VALUE_MESSENGER:
                ret_val = cts_value_get_str_im(op_code, (cts_messenger *)value, field);
                break;
+       case CTS_VALUE_GROUP:
+       case CTS_VALUE_GROUP_RELATION:
+       case CTS_VALUE_LIST_GROUP:
+               ret_val = cts_value_get_str_group(op_code, (cts_group *)value, field);
+               break;
        case CTS_VALUE_RDONLY_PLOG:
-               if (CTS_PLOG_VAL_NUMBER_STR == field) {
+               if (CTS_PLOG_VAL_ADDRESS_STR == field) {
                        HANDLE_STEAL_STRING(op_code, ret_val, ((cts_plog *)value)->number);
                } else if (CTS_PLOG_VAL_SHORTMSG_STR == field) {
                        HANDLE_STEAL_STRING(op_code, ret_val, ((cts_plog *)value)->extra_data2);
@@ -2195,18 +2246,6 @@ static char* cts_value_handle_str(int op_code, CTSvalue *value, int field)
                                "This field(%d) is not supported in value(addressbook)", field);
                HANDLE_STEAL_STRING(op_code, ret_val, ((cts_addrbook *)value)->name);
                break;
-       case CTS_VALUE_GROUP_RELATION:
-               if (CTS_GROUPREL_VAL_NAME_STR == field) {
-                       HANDLE_STEAL_STRING(op_code, ret_val, ((cts_group *)value)->name);
-               }
-               else if (CTS_GROUPREL_VAL_RINGTONE_STR == field) {
-                       HANDLE_STEAL_STRING(op_code, ret_val, ((cts_group *)value)->ringtone_path);
-               }
-               else {
-                       ERR("Not supported field(%d)", field);
-                       ret_val = NULL;
-               }
-               break;
        case CTS_VALUE_WEB:
                if (CTS_WEB_VAL_ADDR_STR == field) {
                        HANDLE_STEAL_STRING(op_code, ret_val, ((cts_web *)value)->url);
@@ -2225,27 +2264,6 @@ static char* cts_value_handle_str(int op_code, CTSvalue *value, int field)
                        ret_val = NULL;
                }
                break;
-       case CTS_VALUE_GROUP:
-               if (CTS_GROUP_VAL_NAME_STR == field) {
-                       HANDLE_STEAL_STRING(op_code, ret_val, ((cts_group *)value)->name);
-               }
-               else if (CTS_GROUP_VAL_RINGTONE_STR == field) {
-                       HANDLE_STEAL_STRING(op_code, ret_val, ((cts_group *)value)->ringtone_path);
-               }
-               else {
-                       ERR("Not supported field(%d)", field);
-                       ret_val = NULL;
-               }
-               break;
-       case CTS_VALUE_LIST_GROUP:
-               if (CTS_LIST_GROUP_NAME_STR == field) {
-                       HANDLE_STEAL_STRING(op_code, ret_val, ((cts_group *)value)->name);
-               }
-               else {
-                       ERR("Not supported field(%d)", field);
-                       ret_val = NULL;
-               }
-               break;
        case CTS_VALUE_LIST_CUSTOM_NUM_TYPE:
                if (CTS_LIST_CUSTOM_NUM_TYPE_NAME_STR == field) {
                        HANDLE_STEAL_STRING(op_code, ret_val, ((numtype_list *)value)->name);
@@ -2273,7 +2291,7 @@ static char* cts_value_handle_str(int op_code, CTSvalue *value, int field)
        case CTS_VALUE_EVENT:
                /* evet value doesn't have string value */
        default:
-               ERR("The value has unsupported type");
+               ERR("The value has unsupported type(%d)", value->v_type);
                ret_val = NULL;
                break;
        }
@@ -2292,8 +2310,7 @@ API char* contacts_svc_value_steal_str(CTSvalue *value, int field)
 
 static inline int cts_value_set_int_plog(cts_plog *value, int field, int intval)
 {
-       switch (field)
-       {
+       switch (field) {
        case CTS_PLOG_VAL_LOG_TIME_INT:
                value->log_time = intval;
                break;
@@ -2317,8 +2334,7 @@ static inline int cts_value_set_int_plog(cts_plog *value, int field, int intval)
 static inline int cts_value_set_int_addrbook(cts_addrbook *value,
                int field, int intval)
 {
-       switch (field)
-       {
+       switch (field) {
        case CTS_ADDRESSBOOK_VAL_ACC_ID_INT:
                value->acc_id = intval;
                break;
@@ -2339,8 +2355,7 @@ API int contacts_svc_value_set_int(CTSvalue *value, int field, int intval)
 {
        retv_if(NULL == value, CTS_ERR_ARG_NULL);
 
-       switch (value->v_type)
-       {
+       switch (value->v_type) {
        case CTS_VALUE_BASIC:
                ((cts_basic*)value)->type = CTS_BASIC_VAL_INT;
                ((cts_basic*)value)->val.i = intval;
@@ -2350,12 +2365,16 @@ API int contacts_svc_value_set_int(CTSvalue *value, int field, int intval)
                                "Not supported field");
                ((cts_extend *)value)->data1 = intval;
                break;
-       case CTS_VALUE_EMAIL:
        case CTS_VALUE_NUMBER:
                retvm_if(CTS_NUM_VAL_TYPE_INT != field, CTS_ERR_ARG_INVALID,
                                "Not supported field");
                ((cts_number *)value)->type = intval;
                break;
+       case CTS_VALUE_EMAIL:
+               retvm_if(CTS_EMAIL_VAL_TYPE_INT != field, CTS_ERR_ARG_INVALID,
+                               "Not supported field");
+               ((cts_email *)value)->type = intval;
+               break;
        case CTS_VALUE_PHONELOG:
                return cts_value_set_int_plog((cts_plog *)value, field, intval);
        case CTS_VALUE_GROUP_RELATION:
@@ -2387,8 +2406,7 @@ API int contacts_svc_value_set_int(CTSvalue *value, int field, int intval)
                        ((cts_event *)value)->type = intval;
                else if (CTS_EVENT_VAL_DATE_INT == field)
                        ((cts_event *)value)->date = intval;
-               else
-               {
+               else {
                        ERR("Not supported field");
                        return CTS_ERR_ARG_INVALID;
                }
@@ -2407,7 +2425,7 @@ API int contacts_svc_value_set_int(CTSvalue *value, int field, int intval)
        case CTS_VALUE_CONTACT_BASE_INFO:
                /* base_info value doesn't have integer value for set */
        default:
-               ERR("The value has unsupported type");
+               ERR("The value has unsupported type(%d)", value->v_type);
                return CTS_ERR_ARG_INVALID;
        }
 
@@ -2418,8 +2436,7 @@ int contacts_svc_value_set_dbl(CTSvalue *value, int field, double dblval)
 {
        retv_if(NULL == value, CTS_ERR_ARG_NULL);
 
-       switch (value->v_type)
-       {
+       switch (value->v_type) {
        case CTS_VALUE_BASIC:
                ((cts_basic*)value)->type = CTS_BASIC_VAL_DBL;
                ((cts_basic*)value)->val.d = dblval;
@@ -2435,7 +2452,7 @@ int contacts_svc_value_set_dbl(CTSvalue *value, int field, double dblval)
        case CTS_VALUE_NAME:
        case CTS_VALUE_CONTACT_BASE_INFO:
        default:
-               ERR("The value has unsupported type");
+               ERR("The value has unsupported type(%d)", value->v_type);
                return CTS_ERR_ARG_INVALID;
        }
 
@@ -2447,8 +2464,7 @@ API int contacts_svc_value_set_bool(CTSvalue *value,
 {
        retv_if(NULL == value, CTS_ERR_ARG_NULL);
 
-       switch (value->v_type)
-       {
+       switch (value->v_type) {
        case CTS_VALUE_CONTACT_BASE_INFO:
                if (CTS_BASE_VAL_FAVORITE_BOOL == field)
                        ((cts_ct_base*)value)->is_favorite = boolval;
@@ -2549,7 +2565,7 @@ API int contacts_svc_value_set_bool(CTSvalue *value,
        case CTS_VALUE_NAME:
                /* name value doesn't have boolean value */
        default:
-               ERR("The value has unsupported type");
+               ERR("The value has unsupported type(%d)", value->v_type);
                return CTS_ERR_ARG_INVALID;
        }
 
@@ -2558,8 +2574,7 @@ API int contacts_svc_value_set_bool(CTSvalue *value,
 
 static inline int cts_value_set_str_base(cts_ct_base *base, int field, char *strval)
 {
-       switch (field)
-       {
+       switch (field) {
        case CTS_BASE_VAL_IMG_PATH_STR:
                if (base->embedded)
                        FREEandSTRDUP(base->img_path, strval);
@@ -2596,7 +2611,7 @@ static inline int cts_value_set_str_base(cts_ct_base *base, int field, char *str
                base->full_img_changed = true;
                break;
        default:
-               ERR("Not supported field");
+               ERR("Not supported field(%d)", field);
                return CTS_ERR_ARG_INVALID;
        }
        return CTS_SUCCESS;
@@ -2604,8 +2619,7 @@ static inline int cts_value_set_str_base(cts_ct_base *base, int field, char *str
 
 static inline int cts_value_set_str_name(cts_name *name, int field, char *strval)
 {
-       switch (field)
-       {
+       switch (field) {
        case CTS_NAME_VAL_FIRST_STR:
                if (name->embedded) {
                        FREEandSTRDUP(name->first, strval);
@@ -2649,7 +2663,7 @@ static inline int cts_value_set_str_name(cts_name *name, int field, char *strval
                        name->suffix = strval;
                break;
        default:
-               ERR("Not supported field");
+               ERR("Not supported field(%d)", field);
                return CTS_ERR_ARG_INVALID;
        }
        name->is_changed = true;
@@ -2658,8 +2672,7 @@ static inline int cts_value_set_str_name(cts_name *name, int field, char *strval
 
 static inline int cts_value_set_str_postal(cts_postal *postal, int field, char *strval)
 {
-       switch (field)
-       {
+       switch (field) {
        case CTS_POSTAL_VAL_POBOX_STR:
                if (postal->embedded) {
                        FREEandSTRDUP(postal->pobox, strval);
@@ -2710,7 +2723,7 @@ static inline int cts_value_set_str_postal(cts_postal *postal, int field, char *
                        postal->country = strval;
                break;
        default:
-               ERR("Not supported field");
+               ERR("Not supported field(%d)", field);
                return CTS_ERR_ARG_INVALID;
        }
        return CTS_SUCCESS;
@@ -2719,8 +2732,7 @@ static inline int cts_value_set_str_postal(cts_postal *postal, int field, char *
 static inline int cts_value_set_str_company(
                cts_company *com, int field, char *strval)
 {
-       switch (field)
-       {
+       switch (field) {
        case CTS_COMPANY_VAL_NAME_STR:
                if (com->embedded) {
                        FREEandSTRDUP(com->name, strval);
@@ -2757,7 +2769,7 @@ static inline int cts_value_set_str_company(
                        com->assistant_name = strval;
                break;
        default:
-               ERR("Not supported field");
+               ERR("Not supported field(%d)", field);
                return CTS_ERR_ARG_INVALID;
        }
        return CTS_SUCCESS;
@@ -2766,8 +2778,7 @@ static inline int cts_value_set_str_company(
 static inline int cts_value_set_str_group(
                cts_group *group, int field, char *strval)
 {
-       switch (field)
-       {
+       switch (field) {
        case CTS_GROUP_VAL_NAME_STR:
                if (group->embedded) {
                        FREEandSTRDUP(group->name, strval);
@@ -2782,8 +2793,16 @@ static inline int cts_value_set_str_group(
                else
                        group->ringtone_path = strval;
                break;
+       case CTS_GROUP_VAL_IMG_PATH_STR:
+               if (group->embedded) {
+                       FREEandSTRDUP(group->img_path, strval);
+               }
+               else
+                       group->img_path = strval;
+               group->img_loaded = true;
+               break;
        default:
-               ERR("Not supported field");
+               ERR("Not supported field(%d)", field);
                return CTS_ERR_ARG_INVALID;
        }
        return CTS_SUCCESS;
@@ -2791,8 +2810,7 @@ static inline int cts_value_set_str_group(
 
 static inline int cts_value_set_str_extend(cts_extend *extend, int field, char *strval)
 {
-       switch (field)
-       {
+       switch (field) {
        case CTS_EXTEND_VAL_DATA2_STR:
                if (extend->embedded) {
                        FREEandSTRDUP(extend->data2, strval);
@@ -2858,7 +2876,7 @@ static inline int cts_value_set_str_extend(cts_extend *extend, int field, char *
                        extend->data10 = strval;
                break;
        default:
-               ERR("Not supported field");
+               ERR("Not supported field(%d)", field);
                return CTS_ERR_ARG_INVALID;
        }
        return CTS_SUCCESS;
@@ -2867,8 +2885,7 @@ static inline int cts_value_set_str_extend(cts_extend *extend, int field, char *
 
 static inline int cts_value_set_str_im(cts_messenger *im, int field, char *strval)
 {
-       switch (field)
-       {
+       switch (field) {
        case CTS_MESSENGER_VAL_IM_ID_STR:
                if (im->embedded)
                        FREEandSTRDUP(im->im_id, strval);
@@ -2888,7 +2905,7 @@ static inline int cts_value_set_str_im(cts_messenger *im, int field, char *strva
                        im->svc_op = strval;
                break;
        default:
-               ERR("Not supported field");
+               ERR("Not supported field(%d)", field);
                return CTS_ERR_ARG_INVALID;
        }
        return CTS_SUCCESS;
@@ -2906,8 +2923,7 @@ API int contacts_svc_value_set_str(CTSvalue *value, int field, const char *strva
        else
                str = NULL;
 
-       switch (value->v_type)
-       {
+       switch (value->v_type) {
        case CTS_VALUE_BASIC:
                ((cts_basic*)value)->type = CTS_BASIC_VAL_STR;
                if (value->embedded)
@@ -2952,12 +2968,11 @@ API int contacts_svc_value_set_str(CTSvalue *value, int field, const char *strva
                ((cts_group *)value)->name = str;
                break;
        case CTS_VALUE_PHONELOG:  /* phonelog value never be embedded*/
-               if (CTS_PLOG_VAL_NUMBER_STR == field)
+               if (CTS_PLOG_VAL_ADDRESS_STR == field)
                        ((cts_plog *)value)->number = str;
                else if (CTS_PLOG_VAL_SHORTMSG_STR == field)
                        ((cts_plog *)value)->extra_data2 = str;
-               else
-               {
+               else {
                        ERR("Not supported field");
                        return CTS_ERR_ARG_INVALID;
                }
@@ -2987,7 +3002,7 @@ API int contacts_svc_value_set_str(CTSvalue *value, int field, const char *strva
        case CTS_VALUE_EVENT:
                /* evet value doesn't have string value */
        default:
-               ERR("The value has unsupported type");
+               ERR("The value has unsupported type(%d)", value->v_type);
                return CTS_ERR_ARG_INVALID;
        }
 
index d39b6a8..1bba9bc 100755 (executable)
@@ -97,6 +97,7 @@ typedef struct {
        bool note_changed;
        bool is_favorite;
        int id;
+       int person_id;
        int changed_time;
        int addrbook_id;
        char *uid;
@@ -201,12 +202,13 @@ typedef struct {
        int v_type:16;
        bool embedded;
        bool deleted;
+       bool img_loaded;
        int id;
        int addrbook_id;
        char *name;
        char *ringtone_path;
        char *vcard_group;
-       //   char *image_path;
+       char *img_path;
 }cts_group; //CTS_GROUP_VAL_ or CTS_GROUPREL_VAL_
 
 typedef struct {
@@ -238,7 +240,7 @@ typedef struct {
        bool deleted;
        int id;
        char *number;
-       int related_id; /* contact id */
+       int related_id; /* person id */
        int log_time;
        int log_type;
        int extra_data1; /* duration, message_id */
@@ -278,13 +280,15 @@ typedef struct {
        int extra_data1; /* duration, message_id */
        char *extra_data2; /*short message*/
        int related_id; /* contact id */
+       int person_id;
 }plog_list;//CTS_LIST_PLOG_
 
 typedef struct {
        int v_type:16;
        bool embedded;
-       int id;
-       int acc_id;
+       int person_id;
+       int contact_id;
+       int addrbook_id;
        char *img_path;
        char *first;
        char *last;
@@ -296,6 +300,23 @@ typedef struct {
 typedef struct {
        int v_type:16;
        bool embedded;
+       int person_id;
+       int contact_id;
+       int addrbook_id;
+       char *img_path;
+       char *first;
+       char *last;
+       char *display;
+       int def_num_type;
+       char *def_num;
+       int def_email_type;
+       char *def_email;
+       char *normalize;
+}osp_list;//OSPLIST
+
+typedef struct {
+       int v_type:16;
+       bool embedded;
        char *name;
        char *number;
 }sdn_list;//SDNLIST
@@ -306,6 +327,7 @@ typedef struct {
        int changed_type:8;
        int id;
        int changed_ver;
+       int addressbook_id;
 }change_list;//CTS_LIST_CHANGE_
 
 typedef struct {
@@ -327,6 +349,7 @@ typedef struct {
        int v_type:16;
        bool embedded;
        int id;
+       int person_id;
        int contact_id;
        char *first;
        char *last;
@@ -339,6 +362,7 @@ typedef struct {
 
 typedef struct {
        int s_type;
+       int is_restricted;
        cts_ct_base *base;
        cts_name *name;
        GSList *numbers;
@@ -373,6 +397,7 @@ enum{
        CTS_VALUE_RDONLY_COMPANY,
        CTS_VALUE_LIST_SHORTCUT,
        CTS_VALUE_RDONLY_PLOG,
+       CTS_VALUE_LIST_OSP,
 };
 
 //basic
@@ -466,7 +491,8 @@ enum BASEVALUE {
        CTS_BASE_VAL_UID_STR, /**< A globally (including outside of the device) unique ID. */
        CTS_BASE_VAL_ADDRESSBOOK_ID_INT, /**< read only. Each contact is assigned to a addressbook. */
        CTS_BASE_VAL_FULL_IMG_PATH_STR, /**< For full screen image. Should include extension at path */
-       CTS_BASE_VAL_FAVORITE_BOOL /**< read only. Use contacts_svc_set_favorite(CTS_FAVOR_CONTACT). It can assign for handling struct. But the changes are ignored */
+       CTS_BASE_VAL_FAVORITE_BOOL, /**< read only. Use contacts_svc_set_favorite(CTS_FAVOR_CONTACT). It can assign for handling struct. But the changes are ignored */
+       CTS_BASE_VAL_PERSON_ID_INT /**< read only */
 };
 
 /**
@@ -505,14 +531,25 @@ enum EMAILVALUE {
 };
 
 /**
+ * group
+ */
+enum GROUPVALUE {
+       CTS_GROUP_VAL_ID_INT = 0, /**< read only */
+       CTS_GROUP_VAL_ADDRESSBOOK_ID_INT = 1, /**< . */
+       CTS_GROUP_VAL_NAME_STR = 2,/**< . */
+       CTS_GROUP_VAL_RINGTONE_STR = 3,/**< . */
+       CTS_GROUP_VAL_IMG_PATH_STR = 4,/**< . */
+};
+
+/**
  * group relation information for contact
  */
 enum GROUPRELATIONVALUE {
-       CTS_GROUPREL_VAL_ID_INT, /**< [write only]group id */
-       CTS_GROUPREL_VAL_DELETE_BOOL,/**< request to delete in the list of #CTSstruct. */
-       CTS_GROUPREL_VAL_NAME_STR,/**< read only, but it can assign for handling struct(Not recommend) */
-       CTS_GROUPREL_VAL_RINGTONE_STR,/**< read only */
-       //   CTS_GROUPREL_VAL_IMG_PATH_STR,
+       CTS_GROUPREL_VAL_ID_INT = CTS_GROUP_VAL_ID_INT, /**< [write only]group id */
+       CTS_GROUPREL_VAL_DELETE_BOOL = 1,/**< request to delete in the list of #CTSstruct. */
+       CTS_GROUPREL_VAL_NAME_STR = CTS_GROUP_VAL_NAME_STR,/**< read only, but it can assign for handling struct(Not recommend) */
+       CTS_GROUPREL_VAL_RINGTONE_STR = CTS_GROUP_VAL_RINGTONE_STR,/**< read only */
+   CTS_GROUPREL_VAL_IMG_PATH_STR = CTS_GROUP_VAL_IMG_PATH_STR,/**< read only */
 };
 
 /**
@@ -583,25 +620,18 @@ enum NICKNAMEVALUE {
  * phone log
  */
 enum PHONELOGVALUE {
-       CTS_PLOG_VAL_NUMBER_STR,/**< .*/
+       CTS_PLOG_VAL_ADDRESS_STR = 0,/**< number or email address*/
        CTS_PLOG_VAL_ID_INT,/**< read only */
        CTS_PLOG_VAL_LOG_TIME_INT,/**< The time since the Epoch (00:00:00 UTC, January 1, 1970), measured in seconds.*/
        CTS_PLOG_VAL_LOG_TYPE_INT,/**< #PLOGTYPE */
        CTS_PLOG_VAL_DURATION_INT,/**< seconds. */
-       CTS_PLOG_VAL_SHORTMSG_STR,/**< . */
-       CTS_PLOG_VAL_MSGID_INT,/**< . */
+       CTS_PLOG_VAL_SHORTMSG_STR,/**<  message short message or email subject */
+       CTS_PLOG_VAL_MSGID_INT,/**< message id or email id */
        CTS_PLOG_VAL_RELATED_ID_INT,/**< contact id */
 };
 
-/**
- * group
- */
-enum GROUPVALUE {
-       CTS_GROUP_VAL_ID_INT, /**< read only */
-       CTS_GROUP_VAL_ADDRESSBOOK_ID_INT, /**< . */
-       CTS_GROUP_VAL_NAME_STR,/**< . */
-       CTS_GROUP_VAL_RINGTONE_STR,/**< . */
-};
+/** deprecated */
+#define CTS_PLOG_VAL_NUMBER_STR CTS_PLOG_VAL_ADDRESS_STR
 
 /**
  * addressbook
index 9e50cf7..daba106 100755 (executable)
@@ -102,6 +102,10 @@ enum PLOGTYPE{
        CTS_PLOG_TYPE_SMS_OUTGOING = 104,/**< . */
        CTS_PLOG_TYPE_SMS_BLOCKED = 105,/**< . */
        CTS_PLOG_TYPE_MMS_BLOCKED = 106,/**< . */
+
+       CTS_PLOG_TYPE_EMAIL_RECEIVED = 201,/**<.*/
+       CTS_PLOG_TYPE_EMAIL_SENT = 202,/**<.*/
+
        CTS_PLOG_TYPE_MAX
 };
 
index 9504310..4d252ef 100755 (executable)
@@ -35,6 +35,7 @@
 #include "cts-vcard.h"
 #include "cts-pthread.h"
 #include "cts-types.h"
+#include "cts-restriction.h"
 #include "cts-utils.h"
 
 static const char *CTS_NOTI_CONTACT_CHANGED=CTS_NOTI_CONTACT_CHANGED_DEF;
@@ -45,9 +46,10 @@ static const char *CTS_NOTI_ADDRBOOK_CHANGED="/opt/data/contacts-svc/.CONTACTS_S
 static const char *CTS_NOTI_GROUP_CHANGED="/opt/data/contacts-svc/.CONTACTS_SVC_GROUP_CHANGED";
 static const char *CTS_NOTI_GROUP_RELATION_CHANGED="/opt/data/contacts-svc/.CONTACTS_SVC_GROUP_REL_CHANGED";
 static const char *CTS_NOTI_MISSED_CALL_CHANGED="/opt/data/contacts-svc/.CONTACTS_SVC_MISSED_CHANGED";
+static const char *CTS_NOTI_LINK_CHANGED="/opt/data/contacts-svc/.CONTACTS_SVC_LINK_CHANGED";
 
-static const char *CTS_VCONF_SORTING_ORDER="db/service/contacts/name_sorting_order";
-static const char *CTS_VCONF_DISPLAY_ORDER=CTS_VCONF_DISPLAY_ORDER_DEF;
+static const char *CTS_VCONF_SORTING_ORDER=VCONFKEY_CONTACTS_SVC_NAME_SORTING_ORDER;
+static const char *CTS_VCONF_DISPLAY_ORDER=VCONFKEY_CONTACTS_SVC_NAME_DISPLAY_ORDER;
 
 static int transaction_count = 0;
 static int transaction_ver = 0;
@@ -61,6 +63,7 @@ static bool speed_change=false;
 static bool addrbook_change=false;
 static bool group_change=false;
 static bool group_rel_change=false;
+static bool link_change=false;
 
 static int name_sorting_order = -1;
 static int name_display_order = -1;
@@ -119,6 +122,10 @@ void cts_set_group_rel_noti(void)
 {
        group_rel_change = true;
 }
+void cts_set_link_noti(void)
+{
+       link_change = true;
+}
 
 static inline void cts_noti_publish_contact_change(void)
 {
@@ -192,6 +199,15 @@ static inline void cts_noti_publish_group_rel_change(void)
        }
 }
 
+static inline void cts_noti_publish_link_change(void)
+{
+       int fd = open(CTS_NOTI_LINK_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               link_change = false;
+       }
+}
+
 #define CTS_COMMIT_TRY_MAX 500000 // For 3second
 API int contacts_svc_begin_trans(void)
 {
@@ -220,7 +236,7 @@ API int contacts_svc_begin_trans(void)
                version_up = false;
        }
        transaction_count++;
-       CTS_DBG("transaction_count : %d.", transaction_count);
+       INFO("transaction_count : %d", transaction_count);
        cts_mutex_unlock(CTS_MUTEX_TRANSACTION);
 
        return CTS_SUCCESS;
@@ -236,6 +252,7 @@ static inline void cts_cancel_changes(void)
        addrbook_change = false;
        group_change = false;
        group_rel_change = false;
+       link_change = false;
 }
 
 API int contacts_svc_end_trans(bool is_success)
@@ -246,6 +263,7 @@ API int contacts_svc_end_trans(bool is_success)
        cts_mutex_lock(CTS_MUTEX_TRANSACTION);
 
        transaction_count--;
+       INFO("%s, transaction_count : %d", is_success?"True": "False",  transaction_count);
 
        if (0 != transaction_count) {
                CTS_DBG("contact transaction_count : %d.", transaction_count);
@@ -294,6 +312,7 @@ API int contacts_svc_end_trans(bool is_success)
        if (addrbook_change) cts_noti_publish_addrbook_change();
        if (group_change) cts_noti_publish_group_change();
        if (group_rel_change) cts_noti_publish_group_rel_change();
+       if (link_change) cts_noti_publish_link_change();
 
        return transaction_ver;
 }
@@ -440,6 +459,12 @@ static inline const char* cts_noti_get_file_path(int type)
        case CTS_SUBSCRIBE_ADDRESSBOOK_CHANGE:
                noti = CTS_NOTI_ADDRBOOK_CHANGED;
                break;
+       case CTS_SUBSCRIBE_LINK_CHANGE:
+               noti = CTS_NOTI_LINK_CHANGED;
+               break;
+       case CTS_SUBSCRIBE_GROUP_RELATION_CHANGE: //for OSP
+               noti = CTS_NOTI_GROUP_RELATION_CHANGED;
+               break;
        default:
                ERR("Invalid parameter : The type(%d) is not supported", type);
                return NULL;
@@ -553,7 +578,7 @@ API int contacts_svc_get_image(cts_img_t img_type, int index, char **img_path)
        return CTS_SUCCESS;
 }
 
-int cts_delete_image_file(int img_type, int index)
+int cts_contact_delete_image_file(int img_type, int index)
 {
        int ret;
        cts_stmt stmt;
@@ -587,28 +612,15 @@ int cts_delete_image_file(int img_type, int index)
        return CTS_SUCCESS;
 }
 
-int cts_add_image_file(int img_type, int index, char *src_img, char *dest_name, int dest_size)
+static int cts_copy_file(const char *src, const char *dest)
 {
-       int src_fd;
-       int dest_fd;
-       int size;
        int ret;
-       char *ext;
+       int size;
+       int src_fd, dest_fd;
        char buf[CTS_COPY_SIZE_MAX];
-       char dest[CTS_IMG_PATH_SIZE_MAX];
 
-       retvm_if(NULL == src_img, CTS_ERR_ARG_INVALID, "img_path is NULL");
-
-       ext = strrchr(src_img, '.');
-       if (NULL == ext || strchr(ext, '/'))
-               ext = "";
-
-       size = snprintf(dest, sizeof(dest), "%s/%d-%d%s",
-                       CTS_IMAGE_LOCATION, index, img_type, ext);
-       retvm_if(size<=0, CTS_ERR_FAIL, "snprintf() Failed(%d)", errno);
-
-       src_fd = open(src_img, O_RDONLY);
-       retvm_if(src_fd < 0, CTS_ERR_IO_ERR, "Open(%s) Failed(%d)", src_img, errno);
+       src_fd = open(src, O_RDONLY);
+       retvm_if(src_fd < 0, CTS_ERR_IO_ERR, "Open(%s) Failed(%d)", src, errno);
        dest_fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0660);
        if (dest_fd < 0) {
                ERR("Open(%s) Failed(%d)", dest, errno);
@@ -639,26 +651,115 @@ int cts_add_image_file(int img_type, int index, char *src_img, char *dest_name,
        fchmod(dest_fd, CTS_SECURITY_DEFAULT_PERMISSION);
        close(src_fd);
        close(dest_fd);
+
+       return CTS_SUCCESS;
+}
+
+int cts_contact_add_image_file(int img_type, int index, char *src_img, char *dest_name, int dest_size)
+{
+       int ret;
+       char *ext;
+       char dest[CTS_IMG_PATH_SIZE_MAX];
+
+       retvm_if(NULL == src_img, CTS_ERR_ARG_INVALID, "img_path is NULL");
+
+       ext = strrchr(src_img, '.');
+       if (NULL == ext || strchr(ext, '/'))
+               ext = "";
+
+       snprintf(dest, sizeof(dest), "%s/%d-%d%s",
+                       CTS_IMAGE_LOCATION, index, img_type, ext);
+
+       ret = cts_copy_file(src_img, dest);
+       retvm_if(CTS_SUCCESS != ret, ret, "cts_copy_file() Failed(%d)", ret);
+
        snprintf(dest_name, dest_size, "%d-%d%s", index, img_type, ext);
        return CTS_SUCCESS;
 }
 
-int cts_update_image_file(int img_type, int index, char *src_img, char *dest_name, int dest_size)
+int cts_contact_update_image_file(int img_type, int index, char *src_img, char *dest_name, int dest_size)
 {
        int ret;
 
-       ret = cts_delete_image_file(img_type, index);
+       ret = cts_contact_delete_image_file(img_type, index);
        retvm_if(CTS_SUCCESS != ret && CTS_ERR_DB_RECORD_NOT_FOUND != ret,
-               ret, "cts_delete_image_file() Failed(%d)", ret);
+               ret, "cts_contact_delete_image_file() Failed(%d)", ret);
 
        if (src_img) {
-               ret = cts_add_image_file(img_type, index, src_img, dest_name, dest_size);
-               retvm_if(CTS_SUCCESS != ret, ret, "cts_add_image_file() Failed(%d)", ret);
+               ret = cts_contact_add_image_file(img_type, index, src_img, dest_name, dest_size);
+               retvm_if(CTS_SUCCESS != ret, ret, "cts_contact_add_image_file() Failed(%d)", ret);
        }
 
        return ret;
 }
 
+/*
+ * This function is for MY profile and group image.
+ */
+char* cts_get_img(const char *dir, int index, char *dest, int dest_size)
+{
+       DIR *dp;
+       char *ret_val;
+       struct dirent *file_info;
+       char tmp_path[CTS_IMG_PATH_SIZE_MAX] = {0};
+
+       if (0 < index)
+               snprintf(tmp_path, sizeof(tmp_path), "%d", index);
+
+       dp = opendir(dir);
+       if (dp) {
+               while ((file_info = readdir(dp)) != NULL) {
+                       CTS_DBG("file = %s", file_info->d_name);
+                       if ('.' != *file_info->d_name) {
+                               if (0 == index || !strncmp(tmp_path, file_info->d_name, strlen(tmp_path))) {
+                                       if (dest) {
+                                               snprintf(dest, dest_size, "%s/%s", dir, file_info->d_name);
+                                               ret_val = dest;
+                                       } else {
+                                               snprintf(tmp_path, sizeof(tmp_path), "%s/%s", dir, file_info->d_name);
+                                               ret_val = strdup(tmp_path);
+                                       }
+                                       closedir(dp);
+                                       return ret_val;
+                               }
+                       }
+               }
+               closedir(dp);
+       }
+
+       return NULL;
+}
+
+/*
+ * This function is for MY profile and group image.
+ */
+int cts_set_img(const char *dir, int index, const char *path)
+{
+       int ret;
+       char dest[CTS_IMG_PATH_SIZE_MAX];
+
+       if (cts_get_img(dir, index, dest, sizeof(dest))) {
+               if (path && 0 == strcmp(dest, path))
+                       return CTS_SUCCESS;
+               ret = unlink(dest);
+               retvm_if(ret < 0, CTS_ERR_FAIL, "unlink(%s) Failed(%d)", dest, errno);
+       }
+
+       if (path) {
+               char *ext;
+               ext = strrchr(path, '.');
+               if (NULL == ext || strchr(ext, '/'))
+                       ext = "";
+
+               snprintf(dest, sizeof(dest), "%s/%d%s",
+                               dir, index, ext);
+               ret = cts_copy_file(path, dest);
+               retvm_if(CTS_SUCCESS != ret, ret, "cts_copy_file() Failed(%d)", ret);
+       }
+
+       return CTS_SUCCESS;
+}
+
 int cts_update_contact_changed_time(int contact_id)
 {
        int ret;
@@ -687,9 +788,9 @@ API int contacts_svc_save_image(cts_img_t img_type, int index, char *src_img)
        retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
 
        dest_img[0] = '\0';
-       ret = cts_update_image_file(img_type, index, src_img, dest_img, sizeof(dest_img));
+       ret = cts_contact_update_image_file(img_type, index, src_img, dest_img, sizeof(dest_img));
        if (CTS_SUCCESS != ret) {
-               ERR("cts_update_image_file() Failed(%d)", ret);
+               ERR("cts_contact_update_image_file() Failed(%d)", ret);
                contacts_svc_end_trans(false);
                return ret;
        }
@@ -724,25 +825,31 @@ API int contacts_svc_count_with_int(cts_count_int_op op_code, int search_value)
        cts_stmt stmt;
        char query[CTS_SQL_MIN_LEN] = {0};
 
-       switch (op_code)
-       {
+       switch ((int)op_code) {
        case CTS_GET_COUNT_CONTACTS_IN_ADDRESSBOOK:
                snprintf(query, sizeof(query),
-                               "SELECT COUNT(contact_id) FROM %s "
+                               "SELECT COUNT(DISTINCT person_id) FROM %s "
                                "WHERE addrbook_id = ?", CTS_TABLE_CONTACTS);
                break;
        case CTS_GET_COUNT_CONTACTS_IN_GROUP:
                snprintf(query, sizeof(query),
-                               "SELECT COUNT(contact_id) FROM %s WHERE group_id = ?",
-                               CTS_TABLE_GROUPING_INFO);
+                               "SELECT COUNT(DISTINCT person_id) "
+                               "FROM %s A, %s B ON A.contact_id = B.contact_id "
+                               "WHERE group_id = ?",
+                               CTS_TABLE_GROUPING_INFO, CTS_TABLE_CONTACTS);
                break;
        case CTS_GET_COUNT_NO_GROUP_CONTACTS_IN_ADDRESSBOOK:
                snprintf(query, sizeof(query),
-                               "SELECT COUNT(contact_id) FROM %s A "
+                               "SELECT COUNT(DISTINCT person_id) FROM %s A "
                                "WHERE addrbook_id = ? AND NOT EXISTS "
                                "(SELECT contact_id FROM %s WHERE contact_id=A.contact_id LIMIT 1)",
                                CTS_TABLE_CONTACTS, CTS_TABLE_GROUPING_INFO);
                break;
+       case CTS_GET_COUNT_GROUPS_IN_ADDRESSBOOK: // FIXME: should be removed (for OSP): CTS_GET_COUNT_GROUPS_IN_ADDRESSBOOK
+               snprintf(query, sizeof(query),
+                               "SELECT COUNT(*) FROM %s WHERE addrbook_id = ?",
+                               CTS_TABLE_GROUPS);
+               break;
        default:
                ERR("Invalid parameter : The op_code(%d) is not supported", op_code);
                return CTS_ERR_ARG_INVALID;
@@ -764,8 +871,15 @@ API int contacts_svc_count(cts_count_op op_code)
        switch ((int)op_code)
        {
        case CTS_GET_ALL_CONTACT:
-               snprintf(query, sizeof(query),"SELECT COUNT(*) FROM %s",
-                               CTS_TABLE_CONTACTS);
+               if (cts_restriction_get_permit())
+                       snprintf(query, sizeof(query),"SELECT COUNT(*) FROM %s",
+                               CTS_TABLE_PERSONS);
+               else
+                       snprintf(query, sizeof(query),"SELECT COUNT(*) FROM %s "
+                                               "WHERE person_id NOT IN "
+                                               "(SELECT contact_id FROM %s WHERE is_restricted = 1)",
+                               CTS_TABLE_PERSONS, CTS_TABLE_DATA);
+
                break;
        case CTS_GET_COUNT_SDN:
                snprintf(query, sizeof(query),"SELECT COUNT(*) FROM %s",
@@ -782,6 +896,32 @@ API int contacts_svc_count(cts_count_op op_code)
                                CTS_TABLE_PHONELOGS,
                                CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN, CTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN);
                break;
+       case CTS_GET_INCOMING_CALL:
+               snprintf(query, sizeof(query),
+                               "SELECT COUNT(*) FROM %s "
+                               "WHERE log_type = %d OR log_type = %d",
+                               CTS_TABLE_PHONELOGS,
+                               CTS_PLOG_TYPE_VOICE_INCOMMING, CTS_PLOG_TYPE_VIDEO_INCOMMING);
+               break;
+       case CTS_GET_OUTGOING_CALL:
+               snprintf(query, sizeof(query),
+                               "SELECT COUNT(*) FROM %s "
+                               "WHERE log_type = %d OR log_type = %d",
+                               CTS_TABLE_PHONELOGS,
+                               CTS_PLOG_TYPE_VOICE_OUTGOING, CTS_PLOG_TYPE_VIDEO_OUTGOING);
+               break;
+       case CTS_GET_MISSED_CALL:
+               snprintf(query, sizeof(query),
+                               "SELECT COUNT(*) FROM %s "
+                               "WHERE log_type BETWEEN %d AND %d",
+                               CTS_TABLE_PHONELOGS,
+                               CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN, CTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN);
+               break;
+       case CTS_GET_COUNT_ALL_GROUP: // FIXME: should be removed (for OSP): CTS_GET_COUNT_ALL_GROUP
+               snprintf(query, sizeof(query),
+                               "SELECT COUNT(*) FROM %s",
+                               CTS_TABLE_GROUPS);
+               break;
        default:
                ERR("Invalid parameter : The op_code(%d) is not supported", op_code);
                return CTS_ERR_ARG_INVALID;
@@ -864,41 +1004,42 @@ API int contacts_svc_import_sim(void)
        return ret;
 }
 
-int cts_increase_outgoing_count(int contact_id)
+API int contacts_svc_export_sim(int index)
 {
        int ret;
-       char query[CTS_SQL_MIN_LEN];
 
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
+       retvm_if(index <= 0, CTS_ERR_ARG_INVALID, "index is invalid", index);
+
+       cts_mutex_lock(CTS_MUTEX_SOCKET_FD);
+       ret = cts_request_sim_export(index);
+       cts_mutex_unlock(CTS_MUTEX_SOCKET_FD);
+
+       return ret;
+}
+
+int cts_increase_outgoing_count(int person_id)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN];
 
        snprintf(query, sizeof(query),
-                       "UPDATE %s SET outgoing_count = outgoing_count + 1 WHERE contact_id = %d",
-                       CTS_TABLE_CONTACTS, contact_id);
+                       "UPDATE %s SET outgoing_count = outgoing_count + 1 WHERE person_id = %d",
+                       CTS_TABLE_PERSONS, person_id);
 
        ret = cts_query_exec(query);
-       if (CTS_SUCCESS != ret)
-       {
-               ERR("cts_query_exec() Failed(%d)", ret);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
+       retvm_if(CTS_SUCCESS != ret, ret, "cts_query_exec() Failed(%d)", ret);
 
-       ret = contacts_svc_end_trans(true);
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
+       return CTS_SUCCESS;
 }
 
-API int contacts_svc_reset_outgoing_count(int contact_id)
+API int contacts_svc_reset_outgoing_count(int person_id)
 {
        int ret ;
        char query[CTS_SQL_MAX_LEN];
 
        snprintf(query, sizeof(query),
-                       "UPDATE %s SET outgoing_count = 0 WHERE contact_id = %d",
-                       CTS_TABLE_CONTACTS, contact_id);
+                       "UPDATE %s SET outgoing_count = 0 WHERE person_id = %d",
+                       CTS_TABLE_PERSONS, person_id);
 
        ret = contacts_svc_begin_trans();
        retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
index 9842c22..d83a14c 100755 (executable)
@@ -26,8 +26,9 @@
 #define CTS_IMG_PATH_SIZE_MAX 1024
 #define CTS_IMAGE_LOCATION "/opt/data/contacts-svc/img"
 #define CTS_VCARD_IMAGE_LOCATION "/opt/data/contacts-svc/img/vcard"
+#define CTS_GROUP_IMAGE_LOCATION "/opt/data/contacts-svc/img/group"
+#define CTS_MY_IMAGE_LOCATION "/opt/data/contacts-svc/img/my"
 #define CTS_NOTI_CONTACT_CHANGED_DEF "/opt/data/contacts-svc/.CONTACTS_SVC_DB_CHANGED"
-#define CTS_VCONF_DISPLAY_ORDER_DEF "db/service/contacts/name_display_order"
 
 void cts_deregister_noti(void);
 void cts_register_noti(void);
@@ -40,15 +41,20 @@ void cts_set_speed_noti(void);
 void cts_set_addrbook_noti(void);
 void cts_set_group_noti(void);
 void cts_set_group_rel_noti(void);
+void cts_set_link_noti(void);
 int cts_exist_file(char *path);
 int cts_convert_nicknames2textlist(GSList *src, char *dest, int dest_size);
 GSList* cts_convert_textlist2nicknames(char *text_list);
 int cts_increase_outgoing_count(int contact_id);
 int cts_get_next_ver(void);
 int cts_update_contact_changed_time(int contact_id);
-int cts_delete_image_file(int img_type, int index);
-int cts_add_image_file(int img_type, int index, char *src_img, char *dest_name, int dest_size);
-int cts_update_image_file(int img_type, int index, char *src_img, char *dest_name, int dest_size);
+int cts_contact_delete_image_file(int img_type, int index);
+int cts_contact_add_image_file(int img_type, int index, char *src_img, char *dest_name, int dest_size);
+int cts_contact_update_image_file(int img_type, int index, char *src_img, char *dest_name, int dest_size);
+
+char* cts_get_img(const char *dir, int index, char *dest, int dest_size);
+int cts_set_img(const char *dir, int index, const char *path);
+
 
 #ifndef __CONTACTS_SVC_H__
 //<!--
@@ -103,8 +109,8 @@ int contacts_svc_end_trans(bool is_success);
  * @see contacts_svc_get_order()
  */
 typedef enum{
-       CTS_ORDER_NAME_FIRSTLAST, /**<First Name first */
-       CTS_ORDER_NAME_LASTFIRST  /**<Last Name first */
+       CTS_ORDER_NAME_FIRSTLAST = 0, /**<First Name first */
+       CTS_ORDER_NAME_LASTFIRST = 1 /**<Last Name first */
 }cts_order_type;
 
 /**
@@ -143,7 +149,9 @@ typedef enum{
        CTS_SUBSCRIBE_GROUP_CHANGE,
        CTS_SUBSCRIBE_SPEEDDIAL_CHANGE,
        CTS_SUBSCRIBE_ADDRESSBOOK_CHANGE,
-       CTS_SUBSCRIBE_MISSED_CALL_CHANGE
+       CTS_SUBSCRIBE_MISSED_CALL_CHANGE,
+       CTS_SUBSCRIBE_LINK_CHANGE,
+       CTS_SUBSCRIBE_GROUP_RELATION_CHANGE /**< This is only for OSP. We cannot guarantee action for your use */
 }cts_subscribe_type;
 
 /**
@@ -213,6 +221,10 @@ typedef enum
        CTS_GET_COUNT_SDN, /**< The count of SDN(Service Dialing Number) in SIM */
        CTS_GET_ALL_PHONELOG, /**< The count of all phonelog */
        CTS_GET_UNSEEN_MISSED_CALL, /**< The count of unseen missed call */
+       CTS_GET_INCOMING_CALL, /**< The count of incomming call */
+       CTS_GET_OUTGOING_CALL, /**< The count of outgoing call */
+       CTS_GET_MISSED_CALL, /**< The count of missed call */
+       CTS_GET_COUNT_ALL_GROUP, /**< The count of groups */
 }cts_count_op;
 /**
  * This function gets count related with op_code.
@@ -230,6 +242,7 @@ typedef enum
        CTS_GET_COUNT_CONTACTS_IN_ADDRESSBOOK, /**< The count of contacts in the addressbook related to index(search_value) */
        CTS_GET_COUNT_CONTACTS_IN_GROUP, /**< The count of contacts in the group related to index(search_value) */
        CTS_GET_COUNT_NO_GROUP_CONTACTS_IN_ADDRESSBOOK, /**< The count of not assigned contacts in the addressbook related to index(search_value) */
+       CTS_GET_COUNT_GROUPS_IN_ADDRESSBOOK /**< The count of groups in the addressbook related to index(search_value) */
 }cts_count_int_op;
 /**
  * This function gets count related with op_code and search_value.
@@ -279,13 +292,20 @@ int contacts_svc_get_image(cts_img_t img_type, int index, char **img_path);
 int contacts_svc_import_sim(void);
 
 /**
+ * This function exports sim phonebook.
+ * @param[in] index index of contact
+ * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
+ */
+int contacts_svc_export_sim(int index);
+
+/**
  * This function sets the outgoing count of the contact to zero.
  *
- * @param[in] contact_id The index of contact
+ * @param[in] person_id The index of person
  * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
  * @see contacts_svc_get_list(), #CTS_LIST_OFTEN_USED_CONTACT
  */
-int contacts_svc_reset_outgoing_count(int contact_id);
+int contacts_svc_reset_outgoing_count(int person_id);
 
 //-->
 #endif //#ifndef __CONTACTS_SVC_H__
index 12deb30..e158bc4 100755 (executable)
@@ -8,7 +8,7 @@ ifdef REQUIRED_PKG
        LDFLAGS += `pkg-config --libs $(REQUIRED_PKG)`
 endif
 
-SRCS = contact-test.c phonelog-test.c change-noti-test.c group-test.c vcard2contact-test.c SIMimport-test.c addressbook-test.c
+SRCS = contact-test.c phonelog-test.c change-noti-test.c group-test.c vcard2contact-test.c SIMimport-test.c addressbook-test.c person-test.c restriction-test.c myprofile-test.c SIMexport-test.c
 TIMESRC = timetest.c
 OBJECTS = $(SRCS:.c=.o)
 TIMEOBJ = $(TIMESRC:.c=.o)
diff --git a/test/SIMexport-test.c b/test/SIMexport-test.c
new file mode 100755 (executable)
index 0000000..1230226
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjae Shin <yj99.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <stdio.h>
+#include <contacts-svc.h>
+
+int main(int argc, char *argv[])
+{
+       int pindex;
+       int ret;
+       if (argc < 2)
+               return 0;
+
+       printf("%d, %s, %s\n", argc, argv[0], argv[1]);
+       pindex = atoi(argv[1]);
+       if (pindex < 0)
+               return 0;
+       printf("person index : %d\n", pindex);
+       contacts_svc_connect();
+
+       ret = contacts_svc_export_sim(pindex);
+       printf("contacts_svc_export_sim() return %d\n", ret);
+
+       contacts_svc_disconnect();
+       return 0;
+}
+
+
index 754b0b7..fcba23a 100755 (executable)
@@ -34,7 +34,46 @@ static void plog_change_callback(void *data)
 
 static void contact_change_callback(void *data)
 {
+       int ret;
+       static int latest_ver = 0;
+       CTSiter *iter;
+
        printf("Contact data of contacts service is changed\n");
+
+       ret = contacts_svc_get_updated_contacts(0, latest_ver, &iter);
+       if (CTS_SUCCESS != ret) {
+               printf("contacts_svc_get_updated_contacts() Failed(%d)", ret);
+               return;
+       }
+
+       while (CTS_SUCCESS == contacts_svc_iter_next(iter)) {
+               int index;
+               CTSvalue *row_info = NULL;
+               row_info = contacts_svc_iter_get_info(iter);
+
+               index = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_ID_INT);
+               printf("(%8d) is ", index);
+               int type = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_TYPE_INT);
+               int ver = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_VER_INT);
+               if (CTS_OPERATION_INSERTED == type) {
+                       printf("Inserted at %d\n", ver);
+                       if (latest_ver < ver) latest_ver = ver;
+               }
+               else if (CTS_OPERATION_UPDATED == type) {
+                       printf("Updated at %d\n", ver);
+                       if (latest_ver < ver) latest_ver = ver;
+               }
+               else if (CTS_OPERATION_DELETED == type) {
+                       printf("Deleted at %d\n", ver);
+                       if (latest_ver < ver) latest_ver = ver;
+               }
+               else {
+                       printf("unknown type (%d)", type);
+               }
+
+               contacts_svc_value_free(row_info);
+       }
+       contacts_svc_iter_remove(iter);
 }
 
 static void missed_call_change_callback(void *data)
@@ -42,6 +81,94 @@ static void missed_call_change_callback(void *data)
        printf("Missed Call is changed\n");
 }
 
+static void group_change_callback(void *data)
+{
+       int ret;
+       static int latest_ver = 0;
+       CTSiter *iter;
+
+       printf("Group data of contacts service is changed\n");
+
+       ret = contacts_svc_get_updated_groups(0, latest_ver, &iter);
+       if (CTS_SUCCESS != ret) {
+               printf("contacts_svc_get_updated_groups() Failed(%d)", ret);
+               return;
+       }
+
+       while (CTS_SUCCESS == contacts_svc_iter_next(iter)) {
+               int index;
+               CTSvalue *row_info = NULL;
+               row_info = contacts_svc_iter_get_info(iter);
+
+               index = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_ID_INT);
+               printf("(%8d) is ", index);
+               int type = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_TYPE_INT);
+               int ver = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_VER_INT);
+               if (CTS_OPERATION_INSERTED == type) {
+                       printf("Inserted at %d\n", ver);
+                       if (latest_ver < ver) latest_ver = ver;
+               }
+               else if (CTS_OPERATION_UPDATED == type) {
+                       printf("Updated at %d\n", ver);
+                       if (latest_ver < ver) latest_ver = ver;
+               }
+               else if (CTS_OPERATION_DELETED == type) {
+                       printf("Deleted at %d\n", ver);
+                       if (latest_ver < ver) latest_ver = ver;
+               }
+               else {
+                       printf("unknown type (%d)", type);
+               }
+
+               contacts_svc_value_free(row_info);
+       }
+       contacts_svc_iter_remove(iter);
+}
+
+static void group_rel_change_callback(void *data)
+{
+       int ret;
+       static int latest_ver = 0;
+       CTSiter *iter;
+
+       printf("Group relation of contacts service is changed\n");
+
+       ret = contacts_svc_group_get_relation_changes(0, latest_ver, &iter);
+       if (CTS_SUCCESS != ret) {
+               printf("contacts_svc_group_get_relation_changes() Failed(%d)", ret);
+               return;
+       }
+
+       while (CTS_SUCCESS == contacts_svc_iter_next(iter)) {
+               int index;
+               CTSvalue *row_info = NULL;
+               row_info = contacts_svc_iter_get_info(iter);
+
+               index = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_ID_INT);
+               printf("(%8d) is ", index);
+               int type = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_TYPE_INT);
+               int ver = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_VER_INT);
+               if (CTS_OPERATION_INSERTED == type) {
+                       printf("Inserted at %d\n", ver);
+                       if (latest_ver < ver) latest_ver = ver;
+               }
+               else if (CTS_OPERATION_UPDATED == type) {
+                       printf("Updated at %d\n", ver);
+                       if (latest_ver < ver) latest_ver = ver;
+               }
+               else if (CTS_OPERATION_DELETED == type) {
+                       printf("Deleted at %d\n", ver);
+                       if (latest_ver < ver) latest_ver = ver;
+               }
+               else {
+                       printf("unknown type (%d)", type);
+               }
+
+               contacts_svc_value_free(row_info);
+       }
+       contacts_svc_iter_remove(iter);
+}
+
 int main()
 {
        GMainLoop *loop;
@@ -51,6 +178,8 @@ int main()
        contacts_svc_subscribe_change(CTS_SUBSCRIBE_PLOG_CHANGE, plog_change_callback, NULL);
        contacts_svc_subscribe_change(CTS_SUBSCRIBE_FAVORITE_CHANGE, favorite_change_callback, NULL);
        contacts_svc_subscribe_change(CTS_SUBSCRIBE_MISSED_CALL_CHANGE, missed_call_change_callback, NULL);
+       contacts_svc_subscribe_change(CTS_SUBSCRIBE_GROUP_CHANGE, group_change_callback, NULL);
+       contacts_svc_subscribe_change(CTS_SUBSCRIBE_GROUP_RELATION_CHANGE, group_rel_change_callback, NULL);
 
        loop = g_main_loop_new(NULL, FALSE);
        g_main_loop_run(loop);
@@ -58,7 +187,9 @@ int main()
        contacts_svc_unsubscribe_change(CTS_SUBSCRIBE_CONTACT_CHANGE, contact_change_callback);
        contacts_svc_unsubscribe_change(CTS_SUBSCRIBE_PLOG_CHANGE, plog_change_callback);
        contacts_svc_unsubscribe_change(CTS_SUBSCRIBE_FAVORITE_CHANGE, favorite_change_callback);
-       contacts_svc_unsubscribe_change(CTS_SUBSCRIBE_MISSED_CALL_CHANGE, favorite_change_callback);
+       contacts_svc_unsubscribe_change(CTS_SUBSCRIBE_MISSED_CALL_CHANGE, missed_call_change_callback);
+       contacts_svc_unsubscribe_change(CTS_SUBSCRIBE_GROUP_CHANGE, group_change_callback);
+       contacts_svc_unsubscribe_change(CTS_SUBSCRIBE_GROUP_RELATION_CHANGE, group_rel_change_callback);
 
        contacts_svc_disconnect();
        g_main_loop_unref(loop);
index fb387d5..b682da2 100755 (executable)
@@ -30,6 +30,7 @@ void insert_group(const char *group_name)
 
        contacts_svc_value_set_str(group, CTS_GROUP_VAL_NAME_STR, group_name);
        contacts_svc_value_set_str(group, CTS_GROUP_VAL_RINGTONE_STR,"/tmp/test.mp3");
+       contacts_svc_value_set_str(group, CTS_GROUP_VAL_IMG_PATH_STR,"/tmp/test.jpg");
 
        ret = contacts_svc_insert_group(0, group);
        if (ret < CTS_SUCCESS)
@@ -54,6 +55,9 @@ void get_group(void)
        if (contacts_svc_value_get_str(group, CTS_GROUP_VAL_RINGTONE_STR))
                printf("ringtone : %s\n",
                                contacts_svc_value_get_str(group, CTS_GROUP_VAL_RINGTONE_STR));
+       if (contacts_svc_value_get_str(group, CTS_GROUP_VAL_IMG_PATH_STR))
+               printf("image path : %s\n",
+                               contacts_svc_value_get_str(group, CTS_GROUP_VAL_IMG_PATH_STR));
 }
 
 void update_group(void)
@@ -68,6 +72,7 @@ void update_group(void)
 
        contacts_svc_value_set_str(group, CTS_GROUP_VAL_NAME_STR,"Fix-Friends");
        contacts_svc_value_set_str(group, CTS_GROUP_VAL_RINGTONE_STR,"/tmp/change.mp3");
+       contacts_svc_value_set_str(group, CTS_GROUP_VAL_IMG_PATH_STR,"/tmp/change.jpg");
 
        //free("Fix-Friends");
        //free("/tmp/change.mp3");
diff --git a/test/myprofile-test.c b/test/myprofile-test.c
new file mode 100755 (executable)
index 0000000..96ddd64
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjae Shin <yj99.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <stdio.h>
+
+#include <contacts-svc.h>
+
+static int insert_my_test(void)
+{
+       CTSstruct *contact;
+       CTSvalue *name, *number1, *number2;
+       CTSvalue *nick, *event, *company;
+       GSList *numbers, *nicknames, *events;
+       contact = contacts_svc_struct_new(CTS_STRUCT_CONTACT);
+
+       CTSvalue *base = contacts_svc_value_new(CTS_VALUE_CONTACT_BASE_INFO);
+       if (base) {
+               //contacts_svc_value_set_str(base, CTS_BASE_VAL_IMG_PATH_STR, "/opt/media/Images and videos/Wallpapers/Wallpaper3.jpg");
+       }
+       contacts_svc_struct_store_value(contact, CTS_CF_BASE_INFO_VALUE, base);
+       contacts_svc_value_free(base);
+
+       name = contacts_svc_value_new(CTS_VALUE_NAME);
+       if (name) {
+               contacts_svc_value_set_str(name, CTS_NAME_VAL_FIRST_STR, "MY");
+               contacts_svc_value_set_str(name, CTS_NAME_VAL_LAST_STR, "NAME");
+               contacts_svc_value_set_str(name, CTS_NAME_VAL_SUFFIX_STR, "TEST");
+       }
+       contacts_svc_struct_store_value(contact, CTS_CF_NAME_VALUE, name);
+       contacts_svc_value_free(name);
+
+       numbers = NULL;
+       number1 = contacts_svc_value_new(CTS_VALUE_NUMBER);
+       if (number1) {
+               contacts_svc_value_set_str(number1, CTS_NUM_VAL_NUMBER_STR, "7777777");
+               contacts_svc_value_set_int(number1, CTS_NUM_VAL_TYPE_INT,
+                               CTS_NUM_TYPE_CELL);
+               contacts_svc_value_set_bool(number1, CTS_NUM_VAL_DEFAULT_BOOL, true);
+       }
+       numbers = g_slist_append(numbers, number1);
+
+       number2 = contacts_svc_value_new(CTS_VALUE_NUMBER);
+       if (number2) {
+               contacts_svc_value_set_str(number2, CTS_NUM_VAL_NUMBER_STR, "3333333");
+               contacts_svc_value_set_int(number2, CTS_NUM_VAL_TYPE_INT,
+                               CTS_NUM_TYPE_WORK|CTS_NUM_TYPE_VOICE);
+       }
+       numbers = g_slist_append(numbers, number2);
+
+       contacts_svc_struct_store_list(contact, CTS_CF_NUMBER_LIST, numbers);
+       contacts_svc_value_free(number1);
+       contacts_svc_value_free(number2);
+       g_slist_free(numbers);
+
+       nicknames = NULL;
+       nick = contacts_svc_value_new(CTS_VALUE_NICKNAME);
+       if (nick)
+               contacts_svc_value_set_str(nick, CTS_NICKNAME_VAL_NAME_STR, "MYnickname");
+
+       nicknames = g_slist_append(nicknames, nick);
+       contacts_svc_struct_store_list(contact, CTS_CF_NICKNAME_LIST, nicknames);
+       contacts_svc_value_free(nick);
+       g_slist_free(nicknames);
+
+       nicknames = NULL;
+       contacts_svc_struct_get_list(contact, CTS_CF_NICKNAME_LIST, &nicknames);
+       if (nicknames)
+               nick = contacts_svc_value_new(CTS_VALUE_NICKNAME);
+       if (nick)
+               contacts_svc_value_set_str(nick, CTS_NICKNAME_VAL_NAME_STR, "MYnickname2");
+       nicknames = g_slist_append(nicknames, nick);
+       contacts_svc_struct_store_list(contact, CTS_CF_NICKNAME_LIST, nicknames);
+       contacts_svc_value_free(nick);
+       //never free nicknames
+
+       events = NULL;
+       event = contacts_svc_value_new(CTS_VALUE_EVENT);
+       if (event) {
+               contacts_svc_value_set_int(event, CTS_EVENT_VAL_DATE_INT, 20110526);
+               contacts_svc_value_set_int(event, CTS_EVENT_VAL_TYPE_INT, CTS_EVENT_TYPE_BIRTH);
+       }
+
+       events = g_slist_append(events, event);
+       contacts_svc_struct_store_list(contact, CTS_CF_EVENT_LIST, events);
+       contacts_svc_value_free(event);
+       g_slist_free(events);
+
+       company = contacts_svc_value_new(CTS_VALUE_COMPANY);
+       if (company) {
+               contacts_svc_value_set_str(company, CTS_COMPANY_VAL_NAME_STR, "Company");
+               contacts_svc_value_set_str(company, CTS_COMPANY_VAL_DEPARTMENT_STR, "department");
+               contacts_svc_value_set_str(company, CTS_COMPANY_VAL_JOB_TITLE_STR, "engineer");
+       }
+       contacts_svc_struct_store_value(contact, CTS_CF_COMPANY_VALUE, company);
+
+       int ret = contacts_svc_set_myprofile(contact);
+       contacts_svc_struct_free(contact);
+
+       return ret;
+}
+
+static void get_myprofile(void)
+{
+       int index=0, ret=-1;
+       CTSstruct *contact;
+       CTSvalue *value=NULL;
+       GSList *get_list, *cursor;
+
+       ret = contacts_svc_get_contact(0, &contact);
+       if (ret < 0) {
+               printf("No found record\n");
+               return;
+       }
+
+       contacts_svc_struct_get_value(contact, CTS_CF_NAME_VALUE, &value);
+       printf("First Name : %s\n", contacts_svc_value_get_str(value, CTS_NAME_VAL_FIRST_STR));
+       printf("Last Name : %s\n", contacts_svc_value_get_str(value, CTS_NAME_VAL_LAST_STR));
+       printf("Additional Name : %s\n", contacts_svc_value_get_str(value, CTS_NAME_VAL_ADDITION_STR));
+       printf("Display Name : %s\n", contacts_svc_value_get_str(value, CTS_NAME_VAL_DISPLAY_STR));
+       printf("Prefix Name : %s\n", contacts_svc_value_get_str(value, CTS_NAME_VAL_PREFIX_STR));
+       printf("Suffix Name : %s\n", contacts_svc_value_get_str(value, CTS_NAME_VAL_SUFFIX_STR));
+
+       value = NULL;
+       contacts_svc_struct_get_value(contact, CTS_CF_COMPANY_VALUE, &value);
+       printf("Company Name : %s\n", contacts_svc_value_get_str(value, CTS_COMPANY_VAL_NAME_STR));
+       printf("Company Department : %s\n", contacts_svc_value_get_str(value, CTS_COMPANY_VAL_DEPARTMENT_STR));
+
+       get_list = NULL;
+       contacts_svc_struct_get_list(contact, CTS_CF_NUMBER_LIST, &get_list);
+
+       for (cursor=get_list;cursor;cursor=g_slist_next(cursor))
+       {
+               int type;
+               type = contacts_svc_value_get_int(cursor->data, CTS_NUM_VAL_TYPE_INT);
+               printf("number Type = %d  ", type);
+
+               if (contacts_svc_value_get_bool(cursor->data, CTS_NUM_VAL_FAVORITE_BOOL))
+                       printf("(favorite)");
+               printf("Number = %s\n",
+                               contacts_svc_value_get_str(cursor->data, CTS_NUM_VAL_NUMBER_STR));
+       }
+
+       get_list = NULL;
+       contacts_svc_struct_get_list(contact, CTS_CF_EMAIL_LIST, &get_list);
+
+       cursor = get_list;
+       for (;cursor;cursor=g_slist_next(cursor))
+       {
+               printf("email Type = %d",
+                               contacts_svc_value_get_int(cursor->data, CTS_EMAIL_VAL_TYPE_INT));
+
+               printf("email = %s\n",
+                               contacts_svc_value_get_str(cursor->data, CTS_EMAIL_VAL_ADDR_STR));
+       }
+
+       get_list = NULL;
+       contacts_svc_struct_get_list(contact, CTS_CF_GROUPREL_LIST, &get_list);
+       cursor = get_list;
+       for (;cursor;cursor=g_slist_next(cursor))
+       {
+               printf("group = %s:",
+                               contacts_svc_value_get_str(cursor->data, CTS_GROUPREL_VAL_NAME_STR));
+
+               printf("%d\n",
+                               contacts_svc_value_get_int(cursor->data, CTS_GROUPREL_VAL_ID_INT));
+       }
+
+       get_list = NULL;
+       contacts_svc_struct_get_list(contact, CTS_CF_NICKNAME_LIST, &get_list);
+       cursor = get_list;
+       for (;cursor;cursor=g_slist_next(cursor))
+               printf("nickname = %s\n",
+                               contacts_svc_value_get_str(cursor->data, CTS_NICKNAME_VAL_NAME_STR));
+
+       if (index)
+               contacts_svc_struct_free(contact);
+}
+
+int main()
+{
+       contacts_svc_connect();
+       insert_my_test();
+       get_myprofile();
+       contacts_svc_disconnect();
+       return 0;
+}
diff --git a/test/person-test.c b/test/person-test.c
new file mode 100755 (executable)
index 0000000..e86583d
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjae Shin <yj99.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <stdio.h>
+#include <contacts-svc.h>
+
+
+static int make_preconditon(const char *first, const char *last, const char *num)
+{
+       int ret;
+       CTSstruct *contact;
+       CTSvalue *name, *number1, *base;
+       GSList *numbers;
+
+       contact = contacts_svc_struct_new(CTS_STRUCT_CONTACT);
+
+       name = contacts_svc_value_new(CTS_VALUE_NAME);
+       if (name) {
+               contacts_svc_value_set_str(name, CTS_NAME_VAL_FIRST_STR, first);
+               contacts_svc_value_set_str(name, CTS_NAME_VAL_LAST_STR, last);
+       }
+       contacts_svc_struct_store_value(contact, CTS_CF_NAME_VALUE, name);
+       contacts_svc_value_free(name);
+
+       numbers = NULL;
+       number1 = contacts_svc_value_new(CTS_VALUE_NUMBER);
+       if (number1) {
+               contacts_svc_value_set_str(number1, CTS_NUM_VAL_NUMBER_STR, num);
+               contacts_svc_value_set_int(number1, CTS_NUM_VAL_TYPE_INT,
+                               CTS_NUM_TYPE_CELL);
+               contacts_svc_value_set_bool(number1, CTS_NUM_VAL_DEFAULT_BOOL, true);
+       }
+       numbers = g_slist_append(numbers, number1);
+
+       contacts_svc_struct_store_list(contact, CTS_CF_NUMBER_LIST, numbers);
+       contacts_svc_value_free(number1);
+       g_slist_free(numbers);
+
+       contacts_svc_insert_contact(0, contact);
+       contacts_svc_struct_get_value(contact, CTS_CF_BASE_INFO_VALUE, &base);
+       ret = contacts_svc_value_get_int(base, CTS_BASE_VAL_PERSON_ID_INT);
+       contacts_svc_struct_free(contact);
+
+       return ret;
+}
+
+static void get_person(int id)
+{
+       int index=0, ret=-1;
+       CTSstruct *person;
+       CTSvalue *value=NULL;
+       GSList *get_list, *cursor;
+
+       ret = contacts_svc_get_person(id, &person);
+       if (ret < 0) {
+               printf("No found record\n");
+               return;
+       }
+       contacts_svc_struct_get_value(person, CTS_CF_NAME_VALUE, &value);
+       printf("First Name : %s\n", contacts_svc_value_get_str(value, CTS_NAME_VAL_FIRST_STR));
+       printf("Last Name : %s\n", contacts_svc_value_get_str(value, CTS_NAME_VAL_LAST_STR));
+       //printf("Additional Name : %s\n", contacts_svc_value_get_str(value, CTS_NAME_VAL_ADDITION_STR));
+       //printf("Display Name : %s\n", contacts_svc_value_get_str(value, CTS_NAME_VAL_DISPLAY_STR));
+       //printf("Prefix Name : %s\n", contacts_svc_value_get_str(value, CTS_NAME_VAL_PREFIX_STR));
+       //printf("Suffix Name : %s\n", contacts_svc_value_get_str(value, CTS_NAME_VAL_SUFFIX_STR));
+
+       get_list = NULL;
+       contacts_svc_struct_get_list(person, CTS_CF_NUMBER_LIST, &get_list);
+       for (cursor=get_list;cursor;cursor=g_slist_next(cursor))
+       {
+               int type;
+               type = contacts_svc_value_get_int(cursor->data, CTS_NUM_VAL_TYPE_INT);
+               printf("number Type = %d  ", type);
+
+               if (contacts_svc_value_get_bool(cursor->data, CTS_NUM_VAL_FAVORITE_BOOL))
+                       printf("(favorite)");
+               printf("Number = %s\n",
+                               contacts_svc_value_get_str(cursor->data, CTS_NUM_VAL_NUMBER_STR));
+               if (index)
+                       contacts_svc_set_favorite(CTS_FAVOR_NUMBER,
+                                       contacts_svc_value_get_int(cursor->data, CTS_NUM_VAL_ID_INT));
+       }
+
+       get_list = NULL;
+       contacts_svc_struct_get_list(person, CTS_CF_EMAIL_LIST, &get_list);
+
+       cursor = get_list;
+       for (;cursor;cursor=g_slist_next(cursor))
+       {
+               printf("email Type = %d",
+                               contacts_svc_value_get_int(cursor->data, CTS_EMAIL_VAL_TYPE_INT));
+
+               printf("email = %s\n",
+                               contacts_svc_value_get_str(cursor->data, CTS_EMAIL_VAL_ADDR_STR));
+       }
+
+       get_list = NULL;
+       contacts_svc_struct_get_list(person, CTS_CF_GROUPREL_LIST, &get_list);
+       cursor = get_list;
+       for (;cursor;cursor=g_slist_next(cursor))
+       {
+               printf("group = %s:",
+                               contacts_svc_value_get_str(cursor->data, CTS_GROUPREL_VAL_NAME_STR));
+
+               printf("%d\n",
+                               contacts_svc_value_get_int(cursor->data, CTS_GROUPREL_VAL_ID_INT));
+       }
+
+       contacts_svc_struct_free(person);
+}
+
+static void get_person_list(void)
+{
+       CTSiter *iter = NULL;
+       printf("Phone contact NUM = %d\n",
+                       contacts_svc_count(CTS_GET_ALL_CONTACT));
+
+       contacts_svc_get_list(CTS_LIST_ALL_CONTACT, &iter);
+
+       while (CTS_SUCCESS == contacts_svc_iter_next(iter))
+       {
+               CTSvalue *contact = NULL;
+               const char *first, *last, *display;
+               contact = contacts_svc_iter_get_info(iter);
+
+               printf("(%8d)", contacts_svc_value_get_int(contact, CTS_LIST_CONTACT_ID_INT));
+               display = contacts_svc_value_get_str(contact, CTS_LIST_CONTACT_DISPLAY_STR);
+               if (display)
+                       printf("%s :", display);
+               else
+               {
+                       first = contacts_svc_value_get_str(contact, CTS_LIST_CONTACT_FIRST_STR);
+                       last = contacts_svc_value_get_str(contact, CTS_LIST_CONTACT_LAST_STR);
+                       if (CTS_ORDER_NAME_FIRSTLAST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
+                               printf("%s %s :", first, last);
+                       else
+                               printf("%s %s :", last, first);
+               }
+               printf("%s", contacts_svc_value_get_str(contact, CTS_LIST_CONTACT_IMG_PATH_STR));
+               printf("\n");
+               contacts_svc_value_free(contact);
+       }
+       contacts_svc_iter_remove(iter);
+}
+
+int main(int argc, char **argv)
+{
+       int person1, person2;
+
+       contacts_svc_connect();
+
+       person1 = make_preconditon("111", "111", "11111111");
+       person2 = make_preconditon("222", "222", "22222222");
+       get_person_list();
+
+       contacts_svc_link_person(person1, person2);
+       get_person(person1);
+       get_person_list();
+
+       contacts_svc_unlink_person(person1, person2);
+       get_person_list();
+
+       contacts_svc_disconnect();
+
+       return 0;
+}
+
index aeb49f1..9dd79dd 100755 (executable)
@@ -30,21 +30,21 @@ void phonelog_insert_test(void)
        CTSvalue *plog;
 
        plog = contacts_svc_value_new(CTS_VALUE_PHONELOG);
-       contacts_svc_value_set_str(plog, CTS_PLOG_VAL_NUMBER_STR, "0123456789");
+       contacts_svc_value_set_str(plog, CTS_PLOG_VAL_ADDRESS_STR, "0123456789");
        contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TIME_INT,(int) time(NULL));
        contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TYPE_INT,
                        CTS_PLOG_TYPE_VOICE_INCOMMING);
        contacts_svc_value_set_int(plog, CTS_PLOG_VAL_DURATION_INT, 65);
        contacts_svc_insert_phonelog(plog);
 
-       contacts_svc_value_set_str(plog, CTS_PLOG_VAL_NUMBER_STR, "0987654321");
+       contacts_svc_value_set_str(plog, CTS_PLOG_VAL_ADDRESS_STR, "0987654321");
        contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TIME_INT,(int) time(NULL));
        contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TYPE_INT,
                        CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN);
        contacts_svc_value_set_int(plog, CTS_PLOG_VAL_DURATION_INT, 65);
        contacts_svc_insert_phonelog(plog);
 
-       contacts_svc_value_set_str(plog, CTS_PLOG_VAL_NUMBER_STR, "0987654321");
+       contacts_svc_value_set_str(plog, CTS_PLOG_VAL_ADDRESS_STR, "0987654321");
        contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TIME_INT,(int) time(NULL));
        contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TYPE_INT,
                        CTS_PLOG_TYPE_VOICE_INCOMMING);
@@ -54,6 +54,22 @@ void phonelog_insert_test(void)
 
        contacts_svc_value_free(plog);
 }
+
+void phonelog_insert_email_test()
+{
+       CTSvalue *plog;
+
+       plog = contacts_svc_value_new(CTS_VALUE_PHONELOG);
+       contacts_svc_value_set_str(plog, CTS_PLOG_VAL_NUMBER_STR, "kildong.hong@samsung.com");
+       contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TIME_INT, (int)time(NULL));
+       contacts_svc_value_set_int(plog, CTS_PLOG_VAL_LOG_TYPE_INT,
+                       CTS_PLOG_TYPE_EMAIL_RECEIVED);
+       contacts_svc_value_set_str(plog, CTS_PLOG_VAL_SHORTMSG_STR, "Subject : Hello~");
+       contacts_svc_value_set_int(plog, CTS_PLOG_VAL_MSGID_INT, 1);
+       contacts_svc_insert_phonelog(plog);
+       contacts_svc_value_free(plog);
+}
+
 void phonelog_modify_test(void)
 {
        contacts_svc_phonelog_set_seen(2, CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN);
@@ -62,12 +78,12 @@ void phonelog_modify_test(void)
        contacts_svc_delete_phonelog(CTS_PLOG_DEL_BY_NUMBER, "0123456789");
 }
 
-void phonelog_get_list_test(void)
+void phonelog_get_list_test(int op)
 {
        CTSiter *iter = NULL;
        char display[1024]={0};
 
-       contacts_svc_get_list(CTS_LIST_GROUPING_PLOG, &iter);
+       contacts_svc_get_list(op, &iter);
 
        while (CTS_SUCCESS == contacts_svc_iter_next(iter))
        {
@@ -169,10 +185,13 @@ int main()
        sleep(2);
        phonelog_insert_test();
        printf("grouping List 1 <<<<<<<<<<<\n");
-       phonelog_get_list_test();
+       phonelog_get_list_test(CTS_LIST_GROUPING_PLOG);
        phonelog_modify_test();
        printf("grouping List 2 <<<<<<<<<<<\n");
-       phonelog_get_list_test();
+       phonelog_get_list_test(CTS_LIST_GROUPING_PLOG);
+       printf("email List 2 <<<<<<<<<<<\n");
+       phonelog_insert_email_test();
+       phonelog_get_list_test(CTS_LIST_ALL_EMAIL_PLOG);
        printf("detail List <<<<<<<<<<<\n");
        phonelog_get_detail_list_test();
        printf("phonelog number List <<<<<<<<<<<\n");
diff --git a/test/restriction-test.c b/test/restriction-test.c
new file mode 100755 (executable)
index 0000000..c92b4d5
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjae Shin <yj99.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <stdlib.h>
+#include <fcntl.h>
+#include <contacts-svc.h>
+
+#include "test-log.h"
+
+static int fb_insert(int is_facebook)
+{
+       CTSstruct *contact;
+       CTSvalue *name, *number1, *number2;
+       CTSvalue *nick, *event;
+       GSList *numbers, *nicknames, *events;
+       contact = contacts_svc_struct_new(CTS_STRUCT_CONTACT);
+
+       CTSvalue *base = contacts_svc_value_new(CTS_VALUE_CONTACT_BASE_INFO);
+       if (base) {
+               //contacts_svc_value_set_str(base, CTS_BASE_VAL_IMG_PATH_STR, "/opt/media/Images and videos/Wallpapers/Wallpaper3.jpg");
+       }
+       contacts_svc_struct_store_value(contact, CTS_CF_BASE_INFO_VALUE, base);
+       contacts_svc_value_free(base);
+
+       name = contacts_svc_value_new(CTS_VALUE_NAME);
+       if (name) {
+               contacts_svc_value_set_str(name, CTS_NAME_VAL_FIRST_STR, "gildong");
+               contacts_svc_value_set_str(name, CTS_NAME_VAL_LAST_STR, "Hong");
+               contacts_svc_value_set_str(name, CTS_NAME_VAL_SUFFIX_STR, "engineer");
+       }
+       contacts_svc_struct_store_value(contact, CTS_CF_NAME_VALUE, name);
+       contacts_svc_value_free(name);
+
+       numbers = NULL;
+       number1 = contacts_svc_value_new(CTS_VALUE_NUMBER);
+       if (number1) {
+               contacts_svc_value_set_str(number1, CTS_NUM_VAL_NUMBER_STR, "0987654321");
+               contacts_svc_value_set_int(number1, CTS_NUM_VAL_TYPE_INT,
+                               CTS_NUM_TYPE_CELL);
+               contacts_svc_value_set_bool(number1, CTS_NUM_VAL_DEFAULT_BOOL, true);
+       }
+       numbers = g_slist_append(numbers, number1);
+
+       number2 = contacts_svc_value_new(CTS_VALUE_NUMBER);
+       if (number2) {
+               contacts_svc_value_set_str(number2, CTS_NUM_VAL_NUMBER_STR, "0123456789");
+               contacts_svc_value_set_int(number2, CTS_NUM_VAL_TYPE_INT,
+                               CTS_NUM_TYPE_WORK|CTS_NUM_TYPE_VOICE);
+       }
+       numbers = g_slist_append(numbers, number2);
+
+       contacts_svc_struct_store_list(contact, CTS_CF_NUMBER_LIST, numbers);
+       contacts_svc_value_free(number1);
+       contacts_svc_value_free(number2);
+       g_slist_free(numbers);
+
+       nicknames = NULL;
+       nick = contacts_svc_value_new(CTS_VALUE_NICKNAME);
+       if (nick)
+               contacts_svc_value_set_str(nick, CTS_NICKNAME_VAL_NAME_STR, "Samm");
+
+       nicknames = g_slist_append(nicknames, nick);
+       contacts_svc_struct_store_list(contact, CTS_CF_NICKNAME_LIST, nicknames);
+       contacts_svc_value_free(nick);
+       g_slist_free(nicknames);
+
+       nicknames = NULL;
+       contacts_svc_struct_get_list(contact, CTS_CF_NICKNAME_LIST, &nicknames);
+       if (nicknames)
+               nick = contacts_svc_value_new(CTS_VALUE_NICKNAME);
+       if (nick)
+               contacts_svc_value_set_str(nick, CTS_NICKNAME_VAL_NAME_STR, "3star");
+       nicknames = g_slist_append(nicknames, nick);
+       contacts_svc_struct_store_list(contact, CTS_CF_NICKNAME_LIST, nicknames);
+       contacts_svc_value_free(nick);
+       //never free nicknames
+
+       events = NULL;
+       event = contacts_svc_value_new(CTS_VALUE_EVENT);
+       if (event) {
+               contacts_svc_value_set_int(event, CTS_EVENT_VAL_DATE_INT, 20110526);
+               contacts_svc_value_set_int(event, CTS_EVENT_VAL_TYPE_INT, CTS_EVENT_TYPE_BIRTH);
+       }
+
+       events = g_slist_append(events, event);
+       contacts_svc_struct_store_list(contact, CTS_CF_EVENT_LIST, events);
+       contacts_svc_value_free(event);
+       g_slist_free(events);
+
+       if (is_facebook)
+               contacts_svc_struct_set_restriction(contact);
+       int ret = contacts_svc_insert_contact(0, contact);
+       contacts_svc_struct_free(contact);
+
+       return ret;
+}
+
+static inline void get_contact(int index)
+{
+       int ret;
+       CTSvalue *value=NULL;
+       GSList *get_list, *cursor;
+       CTSstruct *contact;
+
+       ret = contacts_svc_get_contact(index, &contact);
+       if (ret < CTS_SUCCESS) {
+               ERR("No found record");
+               return;
+       }
+
+       contacts_svc_struct_get_value(contact, CTS_CF_NAME_VALUE, &value);
+       INFO("First Name : %s", contacts_svc_value_get_str(value, CTS_NAME_VAL_FIRST_STR));
+       INFO("Last Name : %s", contacts_svc_value_get_str(value, CTS_NAME_VAL_LAST_STR));
+       INFO("Additional Name : %s", contacts_svc_value_get_str(value, CTS_NAME_VAL_ADDITION_STR));
+       INFO("Display Name : %s", contacts_svc_value_get_str(value, CTS_NAME_VAL_DISPLAY_STR));
+       INFO("Prefix Name : %s", contacts_svc_value_get_str(value, CTS_NAME_VAL_PREFIX_STR));
+       INFO("Suffix Name : %s", contacts_svc_value_get_str(value, CTS_NAME_VAL_SUFFIX_STR));
+
+       value = NULL;
+       contacts_svc_struct_get_value(contact, CTS_CF_COMPANY_VALUE, &value);
+       INFO("Company Name : %s", contacts_svc_value_get_str(value, CTS_COMPANY_VAL_NAME_STR));
+       INFO("Company Department : %s", contacts_svc_value_get_str(value, CTS_COMPANY_VAL_DEPARTMENT_STR));
+
+       get_list = NULL;
+       contacts_svc_struct_get_list(contact, CTS_CF_NUMBER_LIST, &get_list);
+
+       for (cursor=get_list;cursor;cursor=g_slist_next(cursor))
+       {
+               int type;
+
+               type = contacts_svc_value_get_int(cursor->data, CTS_NUM_VAL_TYPE_INT);
+               if (contacts_svc_value_get_bool(cursor->data, CTS_NUM_VAL_FAVORITE_BOOL))
+                       INFO("number Type = %d : %s(favorite)", type,
+                                       contacts_svc_value_get_str(cursor->data, CTS_NUM_VAL_NUMBER_STR));
+               else
+                       INFO("number Type = %d : %s", type,
+                                       contacts_svc_value_get_str(cursor->data, CTS_NUM_VAL_NUMBER_STR));
+       }
+
+       get_list = NULL;
+       contacts_svc_struct_get_list(contact, CTS_CF_EMAIL_LIST, &get_list);
+
+       cursor = get_list;
+       for (;cursor;cursor=g_slist_next(cursor))
+       {
+               INFO("email Type = %d : %s",
+                               contacts_svc_value_get_int(cursor->data, CTS_EMAIL_VAL_TYPE_INT),
+                               contacts_svc_value_get_str(cursor->data, CTS_EMAIL_VAL_ADDR_STR));
+       }
+
+       get_list = NULL;
+       contacts_svc_struct_get_list(contact, CTS_CF_GROUPREL_LIST, &get_list);
+       cursor = get_list;
+       for (;cursor;cursor=g_slist_next(cursor))
+       {
+               INFO("group = %s:%d",
+                       contacts_svc_value_get_str(cursor->data, CTS_GROUPREL_VAL_NAME_STR),
+                       contacts_svc_value_get_int(cursor->data, CTS_GROUPREL_VAL_ID_INT));
+       }
+
+       get_list = NULL;
+       contacts_svc_struct_get_list(contact, CTS_CF_NICKNAME_LIST, &get_list);
+       cursor = get_list;
+       for (;cursor;cursor=g_slist_next(cursor))
+               INFO("nickname = %s",
+                               contacts_svc_value_get_str(cursor->data, CTS_NICKNAME_VAL_NAME_STR));
+
+       contacts_svc_struct_free(contact);
+}
+
+static inline void get_contact_list(void)
+{
+       CTSiter *iter = NULL;
+       INFO("Phone contact NUM = %d", contacts_svc_count(CTS_GET_ALL_CONTACT));
+
+       contacts_svc_get_list(CTS_LIST_ALL_CONTACT, &iter);
+       //contacts_svc_get_list_with_int(CTS_LIST_MEMBERS_OF_ADDRESSBOOK_ID, 0, &iter);
+
+       while (CTS_SUCCESS == contacts_svc_iter_next(iter))
+       {
+               int index;
+               CTSvalue *contact = NULL;
+               const char *first, *last, *display, *img;
+               contact = contacts_svc_iter_get_info(iter);
+
+               index = contacts_svc_value_get_int(contact, CTS_LIST_CONTACT_ID_INT);
+               img = contacts_svc_value_get_str(contact, CTS_LIST_CONTACT_IMG_PATH_STR);
+               display = contacts_svc_value_get_str(contact, CTS_LIST_CONTACT_DISPLAY_STR);
+               if (display)
+                       INFO("(%8d)%s : %s", index, display, img);
+               else
+               {
+                       first = contacts_svc_value_get_str(contact, CTS_LIST_CONTACT_FIRST_STR);
+                       last = contacts_svc_value_get_str(contact, CTS_LIST_CONTACT_LAST_STR);
+                       if (CTS_ORDER_NAME_FIRSTLAST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
+                               INFO("(%8d)%s %s : %s", index, first, last, img);
+                       else
+                               INFO("(%8d)%s %s : %s", index, last, first, img);
+               }
+               contacts_svc_value_free(contact);
+       }
+       contacts_svc_iter_remove(iter);
+}
+
+int main()
+{
+       int id;
+       contacts_svc_connect();
+
+       id = fb_insert(1);
+       fb_insert(0);
+
+       get_contact(1);
+       get_contact_list();
+
+       contacts_svc_disconnect();
+       return 0;
+}
+
diff --git a/test/test-log.h b/test/test-log.h
new file mode 100755 (executable)
index 0000000..bfe8e85
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngjae Shin <yj99.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#ifndef __TEST_LOG_H__
+#define __TEST_LOG_H__
+
+#include <stdio.h>
+#include <unistd.h>
+
+#define PRT(prio, fmt, arg...) \
+       do { fprintf((prio?stderr:stdout),fmt"\n", ##arg); } while (0)
+#define INFO(fmt, arg...) PRT(0, fmt, ##arg)
+#define ERR(fmt, arg...) PRT(1,"\x1b[101;38m[ERROR]\x1b[0m%s :" fmt, __FUNCTION__, ##arg)
+#define DBG(fmt, arg...) \
+       do { \
+               printf("\x1b[105;37m[%s]\x1b[0m" fmt"\n", __FUNCTION__, ##arg); \
+       } while (0)
+
+#define TEST_FN_START DBG("[FUNC_START]")
+
+#endif /* __TEST_LOG_H__ */