diff options
65 files changed, 6315 insertions, 2330 deletions
diff --git a/.CONTACTS_SVC_GROUP_CHANGED b/.CONTACTS_SVC_GROUP_CHANGED deleted file mode 100644 index e69de29..0000000 --- a/.CONTACTS_SVC_GROUP_CHANGED +++ /dev/null diff --git a/.CONTACTS_SVC_MISSED_CHANGED b/.CONTACTS_SVC_MISSED_CHANGED deleted file mode 100644 index e69de29..0000000 --- a/.CONTACTS_SVC_MISSED_CHANGED +++ /dev/null diff --git a/.CONTACTS_SVC_PLOG_CHANGED b/.CONTACTS_SVC_PLOG_CHANGED deleted file mode 100644 index e69de29..0000000 --- a/.CONTACTS_SVC_PLOG_CHANGED +++ /dev/null diff --git a/.CONTACTS_SVC_SPEED_CHANGED b/.CONTACTS_SVC_SPEED_CHANGED deleted file mode 100644 index e69de29..0000000 --- a/.CONTACTS_SVC_SPEED_CHANGED +++ /dev/null diff --git a/CMakeLists.txt b/CMakeLists.txt index 7870785..27eab50 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/build-util/generator.sh b/build-util/generator.sh index 0bc0730..7078d54 100755 --- a/build-util/generator.sh +++ b/build-util/generator.sh @@ -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 diff --git a/debian/changelog b/debian/changelog index 89b5cd9..6bb3db3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -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 diff --git a/debian/contacts-service-bin.postinst.in b/debian/contacts-service-bin.postinst.in index 52e46f0..a853e91 100755 --- a/debian/contacts-service-bin.postinst.in +++ b/debian/contacts-service-bin.postinst.in @@ -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 diff --git a/debian/control b/debian/control index e061d95..3d3eb07 100644 --- a/debian/control +++ b/debian/control @@ -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 diff --git a/debian/libcontacts-service.postinst.in b/debian/libcontacts-service.postinst.in index d76c3a6..5f04744 100755 --- a/debian/libcontacts-service.postinst.in +++ b/debian/libcontacts-service.postinst.in @@ -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" diff --git a/debian/rules b/debian/rules index f2b94ce..5b1c2fe 100755 --- a/debian/rules +++ b/debian/rules @@ -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}; \ diff --git a/helper/CMakeLists.txt b/helper/CMakeLists.txt index 594c888..1de9483 100755 --- a/helper/CMakeLists.txt +++ b/helper/CMakeLists.txt @@ -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}) diff --git a/helper/helper-socket.c b/helper/helper-socket.c index f66f0b1..a9aae70 100755 --- a/helper/helper-socket.c +++ b/helper/helper-socket.c @@ -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); diff --git a/helper/internal.h b/helper/internal.h index 75a20e6..740fe93 100755 --- a/helper/internal.h +++ b/helper/internal.h @@ -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 diff --git a/helper/normalize.c b/helper/normalize.c index b27160c..fd1e394 100755 --- a/helper/normalize.c +++ b/helper/normalize.c @@ -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); diff --git a/helper/sim.c b/helper/sim.c index b99aa59..a65a1c6 100755 --- a/helper/sim.c +++ b/helper/sim.c @@ -19,8 +19,10 @@ * */ #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" @@ -35,74 +37,71 @@ #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; } diff --git a/helper/sim.h b/helper/sim.h index 8b3c769..c94934c 100755 --- a/helper/sim.h +++ b/helper/sim.h @@ -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); diff --git a/helper/sqlite.c b/helper/sqlite.c index 63bccc5..65bbefd 100755 --- a/helper/sqlite.c +++ b/helper/sqlite.c @@ -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); diff --git a/helper/utils.c b/helper/utils.c index b03857b..8cb968a 100755 --- a/helper/utils.c +++ b/helper/utils.c @@ -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; diff --git a/packaging/contacts-service.spec b/packaging/contacts-service.spec index e7aabfb..123ba70 100644 --- a/packaging/contacts-service.spec +++ b/packaging/contacts-service.spec @@ -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 diff --git a/.CONTACTS_SVC_AB_CHANGED b/res/.CONTACTS_SVC_GROUP_REL_CHANGED index e69de29..e69de29 100644 --- a/.CONTACTS_SVC_AB_CHANGED +++ b/res/.CONTACTS_SVC_GROUP_REL_CHANGED diff --git a/.CONTACTS_SVC_DB_CHANGED b/res/.CONTACTS_SVC_LINK_CHANGED index e69de29..e69de29 100644 --- a/.CONTACTS_SVC_DB_CHANGED +++ b/res/.CONTACTS_SVC_LINK_CHANGED diff --git a/.CONTACTS_SVC_FAVOR_CHANGED b/res/.CONTACTS_SVC_RESTRICTION_CHECK index e69de29..e69de29 100644 --- a/.CONTACTS_SVC_FAVOR_CHANGED +++ b/res/.CONTACTS_SVC_RESTRICTION_CHECK @@ -21,6 +21,12 @@ --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 diff --git a/src/cts-addressbook.c b/src/cts-addressbook.c index c032754..4769094 100755 --- a/src/cts-addressbook.c +++ b/src/cts-addressbook.c @@ -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 index 0000000..ec4fc94 --- /dev/null +++ b/src/cts-contact-read.c @@ -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; +} diff --git a/src/cts-contact.c b/src/cts-contact-write.c index ed997fe..590dd11 100755 --- a/src/cts-contact.c +++ b/src/cts-contact-write.c @@ -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; } diff --git a/src/cts-contact.h b/src/cts-contact.h index 0fd1531..f0dd35b 100755 --- a/src/cts-contact.h +++ b/src/cts-contact.h @@ -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, diff --git a/src/cts-favorite.c b/src/cts-favorite.c index c2d2655..b43e436 100755 --- a/src/cts-favorite.c +++ b/src/cts-favorite.c @@ -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"); diff --git a/src/cts-favorite.h b/src/cts-favorite.h index f62c02f..59e0f9d 100755 --- a/src/cts-favorite.h +++ b/src/cts-favorite.h @@ -24,6 +24,17 @@ //<!-- /** + * 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 @@ -34,14 +45,6 @@ */ /** - * 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. diff --git a/src/cts-group.c b/src/cts-group.c index 41d5de7..6277f74 100755 --- a/src/cts-group.c +++ b/src/cts-group.c @@ -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 index 0000000..5a21bf9 --- /dev/null +++ b/src/cts-im.c @@ -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 index 0000000..36d52c9 --- /dev/null +++ b/src/cts-im.h @@ -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 index 0000000..33d5445 --- /dev/null +++ b/src/cts-list-filter.c @@ -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 index 0000000..a2af59c --- /dev/null +++ b/src/cts-list-filter.h @@ -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__ + diff --git a/src/cts-list-info.c b/src/cts-list-info.c index c9e0204..a88b059 100755 --- a/src/cts-list-info.c +++ b/src/cts-list-info.c @@ -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; diff --git a/src/cts-list.c b/src/cts-list.c index 31aa8b1..727fb09 100755 --- a/src/cts-list.c +++ b/src/cts-list.c @@ -24,25 +24,26 @@ #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; +} + diff --git a/src/cts-list.h b/src/cts-list.h index a46356d..05b15e3 100755 --- a/src/cts-list.h +++ b/src/cts-list.h @@ -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__ diff --git a/src/cts-normalize.h b/src/cts-normalize.h index 644e9a1..d5036bd 100755 --- a/src/cts-normalize.h +++ b/src/cts-normalize.h @@ -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 index 0000000..09db7f5 --- /dev/null +++ b/src/cts-person.c @@ -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 index 0000000..e2e0a01 --- /dev/null +++ b/src/cts-person.h @@ -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__ + diff --git a/src/cts-phonelog.c b/src/cts-phonelog.c index de0673d..5725410 100755 --- a/src/cts-phonelog.c +++ b/src/cts-phonelog.c @@ -18,6 +18,10 @@ * 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, ...) diff --git a/src/cts-phonelog.h b/src/cts-phonelog.h index 19b0a71..71bda48 100755 --- a/src/cts-phonelog.h +++ b/src/cts-phonelog.h @@ -44,21 +44,21 @@ 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 index 0000000..ab2b7ab --- /dev/null +++ b/src/cts-restriction.c @@ -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 index 0000000..3ad8a9a --- /dev/null +++ b/src/cts-restriction.h @@ -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__ + diff --git a/src/cts-schema.h b/src/cts-schema.h index 8f72597..c0028c3 100755 --- a/src/cts-schema.h +++ b/src/cts-schema.h @@ -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" @@ -41,10 +42,14 @@ #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" diff --git a/src/cts-service.c b/src/cts-service.c index ae664a4..a1e5fd6 100755 --- a/src/cts-service.c +++ b/src/cts-service.c @@ -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 diff --git a/src/cts-socket.c b/src/cts-socket.c index 29dbf8c..a4cf002 100755 --- a/src/cts-socket.c +++ b/src/cts-socket.c @@ -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; diff --git a/src/cts-socket.h b/src/cts-socket.h index 4aa8278..2563d07 100755 --- a/src/cts-socket.h +++ b/src/cts-socket.h @@ -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__ diff --git a/src/cts-sqlite.c b/src/cts-sqlite.c index e5b0443..bc47d5a 100755 --- a/src/cts-sqlite.c +++ b/src/cts-sqlite.c @@ -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); diff --git a/src/cts-struct-ext.c b/src/cts-struct-ext.c index 094e6bc..056a17b 100755 --- a/src/cts-struct-ext.c +++ b/src/cts-struct-ext.c @@ -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; diff --git a/src/cts-struct.c b/src/cts-struct.c index ff3140b..23b0103 100755 --- a/src/cts-struct.c +++ b/src/cts-struct.c @@ -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; } diff --git a/src/cts-struct.h b/src/cts-struct.h index d39b6a8..1bba9bc 100755 --- a/src/cts-struct.h +++ b/src/cts-struct.h @@ -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 diff --git a/src/cts-types.h b/src/cts-types.h index 9e50cf7..daba106 100755 --- a/src/cts-types.h +++ b/src/cts-types.h @@ -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 }; diff --git a/src/cts-utils.c b/src/cts-utils.c index 9504310..4d252ef 100755 --- a/src/cts-utils.c +++ b/src/cts-utils.c @@ -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); diff --git a/src/cts-utils.h b/src/cts-utils.h index 9842c22..d83a14c 100755 --- a/src/cts-utils.h +++ b/src/cts-utils.h @@ -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__ diff --git a/test/Makefile b/test/Makefile index 12deb30..e158bc4 100755 --- a/test/Makefile +++ b/test/Makefile @@ -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 index 0000000..1230226 --- /dev/null +++ b/test/SIMexport-test.c @@ -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; +} + + diff --git a/test/change-noti-test.c b/test/change-noti-test.c index 754b0b7..fcba23a 100755 --- a/test/change-noti-test.c +++ b/test/change-noti-test.c @@ -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); diff --git a/test/group-test.c b/test/group-test.c index fb387d5..b682da2 100755 --- a/test/group-test.c +++ b/test/group-test.c @@ -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 index 0000000..96ddd64 --- /dev/null +++ b/test/myprofile-test.c @@ -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 index 0000000..e86583d --- /dev/null +++ b/test/person-test.c @@ -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; +} + diff --git a/test/phonelog-test.c b/test/phonelog-test.c index aeb49f1..9dd79dd 100755 --- a/test/phonelog-test.c +++ b/test/phonelog-test.c @@ -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 index 0000000..c92b4d5 --- /dev/null +++ b/test/restriction-test.c @@ -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 index 0000000..bfe8e85 --- /dev/null +++ b/test/test-log.h @@ -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__ */ |