tizen 2.3.1 release tizen_2.3.1 submit/tizen_2.3.1/20150915.081713 tizen_2.3.1_release
authorjk7744.park <jk7744.park@samsung.com>
Tue, 8 Sep 2015 13:33:01 +0000 (22:33 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Tue, 8 Sep 2015 13:33:01 +0000 (22:33 +0900)
354 files changed:
CMakeLists.txt
LICENSE.APLv2 [moved from LICENSE with 100% similarity]
NOTICE
build-util/DB-schema-gen2.c [moved from build-util/API-generator.c with 66% similarity]
build-util/generator.sh
client/CMakeLists.txt [new file with mode: 0755]
client/contacts-service2.pc.in [moved from contacts-service.pc.in with 65% similarity]
client/ctsvc_client_activity.c [new file with mode: 0644]
client/ctsvc_client_db.c [new file with mode: 0644]
client/ctsvc_client_group.c [new file with mode: 0644]
client/ctsvc_client_ipc.c [new file with mode: 0644]
client/ctsvc_client_ipc.h [new file with mode: 0644]
client/ctsvc_client_noti.c [new file with mode: 0644]
client/ctsvc_client_person.c [new file with mode: 0644]
client/ctsvc_client_phonelog.c [new file with mode: 0644]
client/ctsvc_client_service.c [new file with mode: 0644]
client/ctsvc_client_service.h [new file with mode: 0644]
client/ctsvc_client_setting.c [new file with mode: 0755]
common/ctsvc_db_notification.c [new file with mode: 0644]
common/ctsvc_filter.c [new file with mode: 0644]
common/ctsvc_filter.h [moved from src/cts-vcard-file.h with 63% similarity, mode: 0644]
common/ctsvc_inotify.c [new file with mode: 0755]
common/ctsvc_inotify.h [new file with mode: 0755]
common/ctsvc_internal.h [new file with mode: 0644]
common/ctsvc_list.c [new file with mode: 0644]
common/ctsvc_list.h [new file with mode: 0644]
common/ctsvc_localize_utils.c [new file with mode: 0755]
common/ctsvc_localize_utils.h [new file with mode: 0755]
common/ctsvc_mutex.c [new file with mode: 0755]
common/ctsvc_mutex.h [moved from src/cts-pthread.h with 78% similarity]
common/ctsvc_notify.h [new file with mode: 0644]
common/ctsvc_query.c [new file with mode: 0644]
common/ctsvc_query.h [new file with mode: 0644]
common/ctsvc_record.c [new file with mode: 0755]
common/ctsvc_record.h [new file with mode: 0644]
common/ctsvc_record_addressbook.c [new file with mode: 0644]
common/ctsvc_record_contact.c [new file with mode: 0755]
common/ctsvc_record_group.c [new file with mode: 0644]
common/ctsvc_record_my_profile.c [new file with mode: 0644]
common/ctsvc_record_person.c [new file with mode: 0755]
common/ctsvc_record_phonelog.c [new file with mode: 0644]
common/ctsvc_record_result.c [new file with mode: 0644]
common/ctsvc_record_sdn.c [new file with mode: 0644]
common/ctsvc_record_speeddial.c [new file with mode: 0644]
common/ctsvc_record_updated_info.c [new file with mode: 0755]
common/ctsvc_sim.c [new file with mode: 0644]
common/ctsvc_socket.c [new file with mode: 0644]
common/ctsvc_socket.h [new file with mode: 0644]
common/ctsvc_struct.h [new file with mode: 0644]
common/ctsvc_vcard.c [new file with mode: 0644]
common/ctsvc_vcard.h [new file with mode: 0644]
common/ctsvc_view.c [new file with mode: 0644]
common/ctsvc_view.h [new file with mode: 0644]
common/ipc/ctsvc_ipc_activity.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_activity_photo.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_address.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_addressbook.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_company.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_contact.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_define.h [new file with mode: 0644]
common/ipc/ctsvc_ipc_email.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_event.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_extension.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_group.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_grouprelation.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_image.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_marshal.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_marshal.h [new file with mode: 0644]
common/ipc/ctsvc_ipc_messenger.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_my_profile.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_name.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_nickname.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_note.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_number.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_person.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_phonelog.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_profile.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_relationship.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_result.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_sdn.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_simple_contact.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_speeddial.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_updated_info.c [new file with mode: 0644]
common/ipc/ctsvc_ipc_url.c [new file with mode: 0644]
contacts-service2.manifest [new file with mode: 0644]
debian/changelog [deleted file]
debian/compat [deleted file]
debian/contacts-service-bin.install.in [deleted file]
debian/contacts-service-bin.postinst.in [deleted file]
debian/control [deleted file]
debian/copyright [deleted file]
debian/dirs [deleted file]
debian/docs [deleted file]
debian/libcontacts-service-dev.install.in [deleted file]
debian/libcontacts-service.install.in [deleted file]
debian/libcontacts-service.postinst.in [deleted file]
debian/rules [deleted file]
doc/contacts_doc.h [new file with mode: 0644]
doc/images/Contact_structure.png [new file with mode: 0644]
doc/images/Creating_a_person_record.png [new file with mode: 0644]
doc/images/Link_person.png [new file with mode: 0644]
doc/images/Properties.png [new file with mode: 0644]
doc/images/Relationship_between_entities.png [new file with mode: 0644]
doc/images/Unlink_contact.png [new file with mode: 0644]
doc/images/contacts_structure.png [new file with mode: 0644]
helper/CMakeLists.txt [deleted file]
helper/contacts-svc-helper.sh [deleted file]
helper/helper-socket.c [deleted file]
helper/helper-socket.h [deleted file]
helper/internal.h [deleted file]
helper/localize.c [deleted file]
helper/localize.h [deleted file]
helper/main.c [deleted file]
helper/normalize.c [deleted file]
helper/normalize.h [deleted file]
helper/schema-recovery.c [deleted file]
helper/sim.c [deleted file]
helper/sim.h [deleted file]
helper/sqlite.c [deleted file]
helper/utils.c [deleted file]
helper/utils.h [deleted file]
image/SLP_ContactsService_PG_image001.PNG [deleted file]
include/ContactsService_PG.h [deleted file]
include/contacts-svc-struct.head [deleted file]
include/contacts-svc-struct.tail [deleted file]
include/contacts-svc-sub.tail [deleted file]
include/contacts-svc.head [deleted file]
include/contacts-svc.tail [deleted file]
include/contacts.h [moved from src/cts-im.c with 52% similarity]
include/contacts_activity.h [new file with mode: 0644]
include/contacts_db.h [new file with mode: 0755]
include/contacts_db_status.h [new file with mode: 0755]
include/contacts_errors.h [new file with mode: 0644]
include/contacts_filter.h [new file with mode: 0755]
include/contacts_group.h [new file with mode: 0644]
include/contacts_internal.h [moved from src/cts-restriction.h with 73% similarity, mode: 0644]
include/contacts_list.h [new file with mode: 0644]
include/contacts_person.h [new file with mode: 0644]
include/contacts_phone_log.h [new file with mode: 0644]
include/contacts_phone_log_internal.h [new file with mode: 0644]
include/contacts_query.h [new file with mode: 0644]
include/contacts_record.h [new file with mode: 0644]
include/contacts_service.h [new file with mode: 0755]
include/contacts_setting.h [new file with mode: 0755]
include/contacts_sim.h [new file with mode: 0644]
include/contacts_types.h [new file with mode: 0644]
include/contacts_vcard.h [new file with mode: 0644]
include/contacts_views.h [new file with mode: 0755]
native/ctsvc_activity.c [new file with mode: 0644]
native/ctsvc_activity.h [moved from test/SIMimport-test.c with 71% similarity, mode: 0644]
native/ctsvc_db_access_control.c [new file with mode: 0644]
native/ctsvc_db_access_control.h [new file with mode: 0644]
native/ctsvc_db_init.c [new file with mode: 0644]
native/ctsvc_db_init.h [new file with mode: 0644]
native/ctsvc_db_plugin_activity.c [new file with mode: 0644]
native/ctsvc_db_plugin_activity_photo.c [new file with mode: 0644]
native/ctsvc_db_plugin_activity_photo_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_activity_photo_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_address.c [new file with mode: 0644]
native/ctsvc_db_plugin_address_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_address_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_addressbook.c [new file with mode: 0644]
native/ctsvc_db_plugin_addressbook_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_addressbook_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_company.c [new file with mode: 0644]
native/ctsvc_db_plugin_company_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_company_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_contact.c [new file with mode: 0644]
native/ctsvc_db_plugin_contact_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_contact_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_email.c [new file with mode: 0644]
native/ctsvc_db_plugin_email_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_email_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_event.c [new file with mode: 0644]
native/ctsvc_db_plugin_event_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_event_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_extension.c [new file with mode: 0644]
native/ctsvc_db_plugin_extension_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_extension_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_group.c [new file with mode: 0644]
native/ctsvc_db_plugin_group_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_group_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_grouprelation.c [new file with mode: 0644]
native/ctsvc_db_plugin_image.c [new file with mode: 0644]
native/ctsvc_db_plugin_image_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_image_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_messenger.c [new file with mode: 0644]
native/ctsvc_db_plugin_messenger_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_messenger_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_my_profile.c [new file with mode: 0644]
native/ctsvc_db_plugin_name.c [new file with mode: 0644]
native/ctsvc_db_plugin_name_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_name_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_nickname.c [new file with mode: 0644]
native/ctsvc_db_plugin_nickname_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_nickname_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_note.c [new file with mode: 0644]
native/ctsvc_db_plugin_note_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_note_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_number.c [new file with mode: 0644]
native/ctsvc_db_plugin_number_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_number_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_person.c [new file with mode: 0644]
native/ctsvc_db_plugin_person_helper.c [new file with mode: 0755]
native/ctsvc_db_plugin_person_helper.h [new file with mode: 0755]
native/ctsvc_db_plugin_phonelog.c [new file with mode: 0644]
native/ctsvc_db_plugin_profile.c [new file with mode: 0644]
native/ctsvc_db_plugin_profile_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_profile_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_relationship.c [new file with mode: 0644]
native/ctsvc_db_plugin_relationship_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_relationship_helper.h [new file with mode: 0644]
native/ctsvc_db_plugin_sdn.c [new file with mode: 0644]
native/ctsvc_db_plugin_sdn.h [moved from include/contacts-svc-sub.head with 85% similarity, mode: 0644]
native/ctsvc_db_plugin_simple_contact.c [new file with mode: 0644]
native/ctsvc_db_plugin_speeddial.c [new file with mode: 0644]
native/ctsvc_db_plugin_url.c [new file with mode: 0644]
native/ctsvc_db_plugin_url_helper.c [new file with mode: 0644]
native/ctsvc_db_plugin_url_helper.h [moved from test/SIMexport-test.c with 57% similarity, mode: 0644]
native/ctsvc_db_query.c [new file with mode: 0755]
native/ctsvc_db_query.h [new file with mode: 0644]
native/ctsvc_group.c [new file with mode: 0644]
native/ctsvc_group.h [new file with mode: 0644]
native/ctsvc_localize.c [new file with mode: 0755]
native/ctsvc_localize.h [new file with mode: 0755]
native/ctsvc_localize_ch.c [new file with mode: 0755]
native/ctsvc_localize_ch.h [new file with mode: 0755]
native/ctsvc_localize_jp.c [new file with mode: 0644]
native/ctsvc_localize_jp.h [new file with mode: 0644]
native/ctsvc_localize_kor.c [new file with mode: 0644]
native/ctsvc_localize_kor.h [moved from src/cts-inotify.h with 57% similarity, mode: 0644]
native/ctsvc_normalize.c [new file with mode: 0644]
native/ctsvc_normalize.h [new file with mode: 0644]
native/ctsvc_notification.c [new file with mode: 0644]
native/ctsvc_notification.h [new file with mode: 0644]
native/ctsvc_number_utils.c [new file with mode: 0644]
native/ctsvc_number_utils.h [new file with mode: 0644]
native/ctsvc_person.c [new file with mode: 0644]
native/ctsvc_person.h [new file with mode: 0644]
native/ctsvc_phonelog.c [new file with mode: 0644]
native/ctsvc_phonelog.h [new file with mode: 0644]
native/ctsvc_schema.h [new file with mode: 0755]
native/ctsvc_service.c [new file with mode: 0644]
native/ctsvc_service.h [new file with mode: 0644]
native/ctsvc_setting.c [new file with mode: 0644]
native/ctsvc_setting.h [new file with mode: 0644]
native/ctsvc_sqlite.c [new file with mode: 0755]
native/ctsvc_sqlite.h [new file with mode: 0755]
native/ctsvc_utils.c [new file with mode: 0644]
native/ctsvc_utils.h [new file with mode: 0644]
packaging/contacts-service.service [new file with mode: 0644]
packaging/contacts-service.socket [new file with mode: 0644]
packaging/contacts-service.spec
res/.CONTACTS_SVC_ACTIVITY_CHANGED [moved from res/.CONTACTS_SVC_RESTRICTION_CHECK with 100% similarity]
res/.CONTACTS_SVC_ACTIVITY_PHOTO_CHANGED [moved from res/.CONTACTS_SVC_MISSED_CHANGED with 100% similarity]
res/.CONTACTS_SVC_ADDRESS_CHANGED [moved from res/.CONTACTS_SVC_LINK_CHANGED with 100% similarity]
res/.CONTACTS_SVC_COMPANY_CHANGED [moved from res/.CONTACTS_SVC_GROUP_REL_CHANGED with 100% similarity]
res/.CONTACTS_SVC_DATA_CHANGED [moved from res/.CONTACTS_SVC_FAVOR_CHANGED with 100% similarity]
res/.CONTACTS_SVC_EMAIL_CHANGED [new file with mode: 0644]
res/.CONTACTS_SVC_EVENT_CHANGED [new file with mode: 0644]
res/.CONTACTS_SVC_GROUP_RELATION_CHANGED [new file with mode: 0644]
res/.CONTACTS_SVC_IMAGE_CHANGED [new file with mode: 0644]
res/.CONTACTS_SVC_IPC_READY [new file with mode: 0644]
res/.CONTACTS_SVC_MESSENGER_CHANGED [new file with mode: 0644]
res/.CONTACTS_SVC_MY_PROFILE_CHANGED [new file with mode: 0644]
res/.CONTACTS_SVC_NAME_CHANGED [new file with mode: 0644]
res/.CONTACTS_SVC_NICKNAME_CHANGED [new file with mode: 0644]
res/.CONTACTS_SVC_NOTE_CHANGED [new file with mode: 0644]
res/.CONTACTS_SVC_NUMBER_CHANGED [new file with mode: 0644]
res/.CONTACTS_SVC_PERSON_CHANGED [new file with mode: 0644]
res/.CONTACTS_SVC_PROFILE_CHANGED [new file with mode: 0644]
res/.CONTACTS_SVC_RELATIONSHIP_CHANGED [new file with mode: 0644]
res/.CONTACTS_SVC_SDN_CHANGED [new file with mode: 0644]
res/.CONTACTS_SVC_URL_CHANGED [new file with mode: 0644]
schema.sql
server/CMakeLists.txt [new file with mode: 0755]
server/ctsvc_ipc_server.c [new file with mode: 0644]
server/ctsvc_ipc_server.h [new file with mode: 0644]
server/ctsvc_ipc_server2.c [new file with mode: 0644]
server/ctsvc_ipc_server2.h [new file with mode: 0644]
server/ctsvc_schema_recovery.c [new file with mode: 0755]
server/ctsvc_schema_recovery.h [moved from helper/schema-recovery.h with 73% similarity]
server/ctsvc_server.c [new file with mode: 0755]
server/ctsvc_server_bg.c [new file with mode: 0644]
server/ctsvc_server_bg.h [new file with mode: 0644]
server/ctsvc_server_change_subject.c [new file with mode: 0644]
server/ctsvc_server_change_subject.h [new file with mode: 0644]
server/ctsvc_server_sim.c [new file with mode: 0755]
server/ctsvc_server_sim.h [new file with mode: 0755]
server/ctsvc_server_socket.c [new file with mode: 0644]
server/ctsvc_server_socket.h [new file with mode: 0644]
server/ctsvc_server_sqlite.c [new file with mode: 0755]
server/ctsvc_server_sqlite.h [moved from helper/sqlite.h with 52% similarity]
server/ctsvc_server_update.c [new file with mode: 0755]
server/ctsvc_server_update.h [new file with mode: 0755]
server/ctsvc_server_utils.c [new file with mode: 0755]
server/ctsvc_server_utils.h [new file with mode: 0755]
src/cts-addressbook.c [deleted file]
src/cts-addressbook.h [deleted file]
src/cts-contact-read.c [deleted file]
src/cts-contact-write.c [deleted file]
src/cts-contact.h [deleted file]
src/cts-errors.h [deleted file]
src/cts-favorite.c [deleted file]
src/cts-favorite.h [deleted file]
src/cts-group.c [deleted file]
src/cts-group.h [deleted file]
src/cts-im.h [deleted file]
src/cts-inotify.c [deleted file]
src/cts-internal.h [deleted file]
src/cts-list-filter.c [deleted file]
src/cts-list-filter.h [deleted file]
src/cts-list-info.c [deleted file]
src/cts-list.c [deleted file]
src/cts-list.h [deleted file]
src/cts-normalize.c [deleted file]
src/cts-normalize.h [deleted file]
src/cts-person.c [deleted file]
src/cts-person.h [deleted file]
src/cts-phonelog.c [deleted file]
src/cts-phonelog.h [deleted file]
src/cts-pthread.c [deleted file]
src/cts-restriction.c [deleted file]
src/cts-schema.h [deleted file]
src/cts-service.c [deleted file]
src/cts-service.h [deleted file]
src/cts-socket.c [deleted file]
src/cts-socket.h [deleted file]
src/cts-sqlite.c [deleted file]
src/cts-sqlite.h [deleted file]
src/cts-struct-ext.c [deleted file]
src/cts-struct-ext.h [deleted file]
src/cts-struct.c [deleted file]
src/cts-struct.h [deleted file]
src/cts-types.c [deleted file]
src/cts-types.h [deleted file]
src/cts-utils.c [deleted file]
src/cts-utils.h [deleted file]
src/cts-vcard-file.c [deleted file]
src/cts-vcard.c [deleted file]
src/cts-vcard.h [deleted file]
test/Makefile [deleted file]
test/addressbook-test.c [deleted file]
test/change-noti-test.c [deleted file]
test/contact-test.c [deleted file]
test/group-test.c [deleted file]
test/myprofile-test.c [deleted file]
test/person-test.c [deleted file]
test/phonelog-test.c [deleted file]
test/restriction-test.c [deleted file]
test/test-log.h [deleted file]
test/timetest.c [deleted file]
test/timetest.h [deleted file]
test/vcard2contact-test.c [deleted file]

index 27eab50..1980114 100755 (executable)
@@ -1,5 +1,5 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-PROJECT(contacts-service C)
+PROJECT(contacts-service C CXX)
 
 #IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
 #      SET(CMAKE_BUILD_TYPE "Release")
@@ -13,54 +13,57 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX})
 SET(EXEC_PREFIX "\${prefix}")
 SET(LIBDIR "\${prefix}/lib")
 SET(INCLUDEDIR "\${prefix}/${DEST_INCLUDE_DIR}")
-SET(VERSION_MAJOR 0)
-SET(VERSION "${VERSION_MAJOR}.6.12")
 
 EXECUTE_PROCESS(COMMAND build-util/generator.sh)
 
+SET(PC_REQUIRED "capi-base-common")
+
 #INCLUDE_DIRECTORIES(${SRC_INCLUDE_DIR})
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -I${SRC_INCLUDE_DIR}")
 
-FILE(GLOB SRCS src/*.c)
-
 INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED glib-2.0 sqlite3 vconf dlog db-util)
+pkg_check_modules(pkgs REQUIRED glib-2.0 capi-base-common vconf dlog db-util icu-i18n security-server)
 
 FOREACH(flag ${pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
 
-SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -fdata-sections -ffunction-sections -Wl,--gc-sections")
 
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC")
 #SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
 #SET(CMAKE_C_FLAGS_RELEASE "-mabi=aapcs-linux -march=armv7-a -msoft-float -O2")
 
 ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
 
-ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
-SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION})
-TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} -lpthread)
-
-CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY)
-SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
-       "${PROJECT_NAME}.pc;include/contacts-svc-sub.h;include/contacts-svc.h;include/contacts-svc-struct.h;helper/schema.h")
-
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib)
-INSTALL(FILES ${PROJECT_NAME}.pc DESTINATION lib/pkgconfig)
+# for tizen open build test
+IF( ENABLE_SIM_FEATURE )
+       ADD_DEFINITIONS("-DENABLE_SIM_FEATURE")
+ENDIF( ENABLE_SIM_FEATURE )
+IF( ENABLE_LOG_FEATURE )
+       ADD_DEFINITIONS("-DENABLE_LOG_FEATURE")
+ENDIF( ENABLE_LOG_FEATURE )
 
-FILE(GLOB HEADER_FILES ${SRC_INCLUDE_DIR}/contacts-svc*.h)
-INSTALL(FILES ${HEADER_FILES} DESTINATION ${DEST_INCLUDE_DIR})
-INSTALL(FILES ${SRC_INCLUDE_DIR}/ContactsService_PG.h DESTINATION ${DEST_INCLUDE_DIR})
 
+# Install notification files
 FILE(GLOB NOTI_FILES ${CMAKE_SOURCE_DIR}/res/.CONTACTS_SVC_*)
-INSTALL(FILES ${NOTI_FILES} DESTINATION /opt/data/contacts-svc
+INSTALL(FILES ${NOTI_FILES} DESTINATION /opt/usr/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)
+# Install directory for image
+INSTALL(DIRECTORY DESTINATION /opt/usr/data/contacts-svc/img/contact)  # contact, my profile
+INSTALL(DIRECTORY DESTINATION /opt/usr/data/contacts-svc/img/group)            # group
+INSTALL(DIRECTORY DESTINATION /opt/usr/data/contacts-svc/img/logo)             # company logo
+INSTALL(DIRECTORY DESTINATION /opt/usr/data/contacts-svc/img/vcard)            # vcard
+
+# Install header file
+FILE(GLOB HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)
+INSTALL(FILES ${HEADER_FILES} DESTINATION ${DEST_INCLUDE_DIR})
+
+# Install DB file
+FILE(GLOB DB_FILES ${CMAKE_CURRENT_SOURCE_DIR}/build-util/.contacts-svc.db*)
+INSTALL(FILES ${DB_FILES} DESTINATION /opt/usr/dbspace)
 
-ADD_SUBDIRECTORY(helper)
+ADD_SUBDIRECTORY(client)
+ADD_SUBDIRECTORY(server)
 
similarity index 100%
rename from LICENSE
rename to LICENSE.APLv2
diff --git a/NOTICE b/NOTICE
index fd4209d..d4bc6d5 100644 (file)
--- a/NOTICE
+++ b/NOTICE
@@ -1 +1,3 @@
 Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE.APLv2 file for Apache license, version 2 terms and conditions.
similarity index 66%
rename from build-util/API-generator.c
rename to build-util/DB-schema-gen2.c
index ee62026..7ffdf13 100755 (executable)
  * limitations under the License.
  *
  */
-#define _GNU_SOURCE
 #include <stdio.h>
 #include <stdlib.h>
 
 int main(int argc, char **argv)
 {
        FILE *fp;
-       char *line = NULL;
-       size_t len = 0;
-       ssize_t read;
+       int c;
 
        fp = fopen(argv[1], "r");
        if (fp == NULL)
                exit(EXIT_FAILURE);
 
-       while ((read = getline(&line, &len, fp)) != -1) {
-               if (len >= 6 && '/'==line[0]
-                               && '/'==line[1]
-                               && '<'==line[2]
-                               && '!'==line[3]
-                               && '-'==line[4]
-                               && '-'==line[5])
+       do{
+               c = fgetc(fp);
+               switch (c)
+               {
+               case '-':
+                       if ('-' == (c = fgetc(fp))) {
+                               while ('\n' != c && EOF != c)
+                                       c = fgetc(fp);
+                               printf("\n");
+                       }
+                       else printf("-%c",c);
                        break;
-       }
-
-       while ((read = getline(&line, &len, fp)) != -1) {
-               if (len >= 5 && '/'==line[0]
-                               && '/'==line[1]
-                               && '-'==line[2]
-                               && '-'==line[3]
-                               && '>'==line[4])
+               case EOF:
+                       break;
+               default:
+                       printf("%c",c);
                        break;
-               printf("%s", line);
-       }
+               }
+       }while(EOF != c);
 
-       free(line);
        exit(EXIT_SUCCESS);
 }
 
index 7078d54..69ab788 100755 (executable)
 
 #!/bin/sh
 
-echo "###### API Generator #####"
+echo "###### DB Generator #####"
 
 cd build-util
 make
 
-#contacts-svc.h
-cat ../include/contacts-svc.head > ../include/contacts-svc.h
-./API-generator ../src/cts-service.h >> ../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
-
-# contacts-svc-struct.h
-cat ../include/contacts-svc-struct.head > ../include/contacts-svc-struct.h
-./API-generator ../src/cts-struct.h >> ../include/contacts-svc-struct.h
-./API-generator ../src/cts-struct-ext.h >> ../include/contacts-svc-struct.h
-cat ../include/contacts-svc-struct.tail >> ../include/contacts-svc-struct.h
-
-# contacts-svc-sub.h
-cat ../include/contacts-svc-sub.head > ../include/contacts-svc-sub.h
-./API-generator ../src/cts-phonelog.h >> ../include/contacts-svc-sub.h
-./API-generator ../src/cts-favorite.h >> ../include/contacts-svc-sub.h
-./API-generator ../src/cts-group.h >> ../include/contacts-svc-sub.h
-./API-generator ../src/cts-im.h >> ../include/contacts-svc-sub.h
-./API-generator ../src/cts-types.h >> ../include/contacts-svc-sub.h
-cat ../include/contacts-svc-sub.tail >> ../include/contacts-svc-sub.h
-
-# Schema
-echo "static const char *schema_query = \"\\" > ../helper/schema.h
-./DB-schema-gen ../schema.sql >> ../helper/schema.h
-echo \"\; >> ../helper/schema.h
+# Make DB schema for generating DB file when running contacts server daemon
+echo "static const char *schema_query = \"\\" > ../server/schema.h
+./DB-schema-gen ../schema.sql >> ../server/schema.h
+echo \"\; >> ../server/schema.h
+
+# Make DB file at builing time
+echo "sqlite3 .contacts-svc.db \"" > DB-schema-create.sh
+./DB-schema-gen2 ../schema.sql >> DB-schema-create.sh
+echo \" >> DB-schema-create.sh
+chmod +x DB-schema-create.sh
+./DB-schema-create.sh
+rm DB-schema-create.sh
 
 
 make clean
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..59140bd
--- /dev/null
@@ -0,0 +1,106 @@
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/client)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common/ipc)
+
+SET(CLIENT contacts-service2)
+
+SET(SRCS
+       ctsvc_client_activity.c
+       ctsvc_client_db.c
+       ctsvc_client_group.c
+       ctsvc_client_person.c
+       ctsvc_client_service.c
+       ctsvc_client_ipc.c
+       ctsvc_client_noti.c
+       ctsvc_client_setting.c
+
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_marshal.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_addressbook.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_contact.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_my_profile.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_group.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_person.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_result.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_simple_contact.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_result.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_updated_info.c
+
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_activity.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_activity_photo.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_address.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_company.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_email.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_event.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_grouprelation.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_messenger.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_name.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_nickname.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_note.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_number.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_relationship.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_image.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_url.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_extension.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_profile.c
+
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_db_notification.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_filter.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_inotify.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_list.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_localize_utils.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_mutex.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_query.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_addressbook.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_contact.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_my_profile.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_group.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_person.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_result.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_updated_info.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_socket.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_vcard.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_view.c
+)
+
+IF( ENABLE_SIM_FEATURE )
+SET(SRCS ${SRCS}
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_sdn.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_sdn.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_sim.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_speeddial.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_speeddial.c
+)
+ENDIF( ENABLE_SIM_FEATURE )
+
+IF( ENABLE_LOG_FEATURE )
+SET(SRCS ${SRCS}
+       ctsvc_client_phonelog.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_phonelog.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_phonelog.c
+)
+ENDIF( ENABLE_LOG_FEATURE )
+
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(client_pkgs REQUIRED pims-ipc gobject-2.0)
+
+FOREACH(flag ${client_pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC")
+
+CONFIGURE_FILE(${CLIENT}.pc.in ${CLIENT}.pc @ONLY)
+
+ADD_DEFINITIONS("-D_CONTACTS_IPC_CLIENT")
+
+ADD_LIBRARY(${CLIENT} SHARED ${SRCS})
+SET_TARGET_PROPERTIES(${CLIENT} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${CLIENT} PROPERTIES VERSION ${FULLVER})
+TARGET_LINK_LIBRARIES(${CLIENT} ${client_pkgs_LDFLAGS} ${pkgs_LDFLAGS} -lpthread)
+
+INSTALL(TARGETS ${CLIENT} DESTINATION lib)
+INSTALL(FILES ${CLIENT}.pc DESTINATION lib/pkgconfig)
+
similarity index 65%
rename from contacts-service.pc.in
rename to client/contacts-service2.pc.in
index cdaf2a5..2b393a2 100644 (file)
@@ -5,9 +5,9 @@ exec_prefix=@EXEC_PREFIX@
 libdir=@LIBDIR@
 includedir=@INCLUDEDIR@
 
-Name: @PROJECT_NAME@
+Name: @TARGET@
 Description: @PROJECT_NAME@ library
-Version: @VERSION@
-Requires: glib-2.0
-Libs: -L${libdir} -l@PROJECT_NAME@
+Version: @FULLVER@
+Requires: glib-2.0 @PC_REQUIRED@
+Libs: -L${libdir} -l@CLIENT@
 Cflags: -I${includedir}
diff --git a/client/ctsvc_client_activity.c b/client/ctsvc_client_activity.c
new file mode 100644 (file)
index 0000000..64b3dbb
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <glib.h>
+#include <pims-ipc-data.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_ipc_define.h"
+#include "ctsvc_ipc_marshal.h"
+#include "ctsvc_client_ipc.h"
+
+API int contacts_activity_delete_by_contact_id(int contact_id)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(contact_id <= 0,CONTACTS_ERROR_INVALID_PARAMETER,"id should be greater than 0");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int( contact_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call( CTSVC_IPC_ACTIVITY_MODULE, CTSVC_IPC_SERVER_ACTIVITY_DELETE_BY_CONTACT_ID, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check result
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata, &size);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_activity_delete_by_account_id(int account_id)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(account_id <= 0,CONTACTS_ERROR_INVALID_PARAMETER,"id should be greater than 0");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int( account_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call( CTSVC_IPC_ACTIVITY_MODULE, CTSVC_IPC_SERVER_ACTIVITY_DELETE_BY_ACCOUNT_ID, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check result
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata, &size);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
\ No newline at end of file
diff --git a/client/ctsvc_client_db.c b/client/ctsvc_client_db.c
new file mode 100644 (file)
index 0000000..06df89b
--- /dev/null
@@ -0,0 +1,1711 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+#include <pims-ipc.h>
+#include <pims-ipc-data.h>
+
+#include "contacts.h"
+#include "contacts_internal.h"
+
+#include "ctsvc_internal.h"
+#include "ctsvc_list.h"
+#include "ctsvc_record.h"
+#include "ctsvc_query.h"
+#include "ctsvc_inotify.h"
+
+#include "ctsvc_ipc_define.h"
+#include "ctsvc_ipc_marshal.h"
+#include "ctsvc_view.h"
+
+#include "ctsvc_client_ipc.h"
+
+#include "ctsvc_mutex.h"
+
+typedef struct {
+       void *callback;
+       void *user_data;
+}ctsvc_ipc_async_userdata_s;
+
+static void __ctsvc_ipc_client_insert_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata);
+static void __ctsvc_ipc_client_update_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata);
+static void __ctsvc_ipc_client_delete_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata);
+
+void __ctsvc_ipc_client_insert_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata)
+{
+       ctsvc_ipc_async_userdata_s *sync_data = (ctsvc_ipc_async_userdata_s *)userdata;
+       int ret = CONTACTS_ERROR_NONE;
+       int *ids = NULL;
+       int count = 0;
+
+       if (data_out)
+       {
+               // check outdata
+               ctsvc_ipc_unmarshal_int(data_out, &ret);
+
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int i=0;
+                       int transaction_ver = 0;
+                       ctsvc_ipc_unmarshal_int(data_out, &transaction_ver);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+
+                       ctsvc_ipc_unmarshal_int(data_out, &count);
+                       ids = calloc(count, sizeof(int));
+                       for(i=0;i<count;i++)
+                       {
+                               ctsvc_ipc_unmarshal_int(data_out, &(ids[i]));
+                       }
+               }
+       }
+
+       if (sync_data->callback)
+       {
+               contacts_db_insert_result_cb callback = sync_data->callback;
+               callback(ret, ids, count, sync_data->user_data);
+       }
+       free(ids);
+
+       ctsvc_inotify_call_blocked_callback();
+
+       CONTACTS_FREE(sync_data);
+
+       return ;
+}
+
+void __ctsvc_ipc_client_update_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata)
+{
+       ctsvc_ipc_async_userdata_s *sync_data = (ctsvc_ipc_async_userdata_s *)userdata;
+       int ret = CONTACTS_ERROR_NONE;
+
+       if (data_out)
+       {
+               // check outdata
+               ctsvc_ipc_unmarshal_int(data_out, &ret);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       ctsvc_ipc_unmarshal_int(data_out, &transaction_ver);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+       }
+
+       if (sync_data->callback)
+       {
+               contacts_db_result_cb callback = sync_data->callback;
+               callback(ret, sync_data->user_data);
+       }
+
+       ctsvc_inotify_call_blocked_callback();
+
+       CONTACTS_FREE(sync_data);
+
+       return ;
+}
+void __ctsvc_ipc_client_delete_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata)
+{
+       ctsvc_ipc_async_userdata_s *sync_data = (ctsvc_ipc_async_userdata_s *)userdata;
+       int ret = CONTACTS_ERROR_NONE;
+
+       if (data_out)
+       {
+               // check outdata
+               ctsvc_ipc_unmarshal_int(data_out, &ret);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       ctsvc_ipc_unmarshal_int(data_out, &transaction_ver);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+       }
+
+       if (sync_data->callback)
+       {
+               contacts_db_result_cb callback = sync_data->callback;
+               callback(ret, sync_data->user_data);
+       }
+
+       ctsvc_inotify_call_blocked_callback();
+
+       CONTACTS_FREE(sync_data);
+
+       return ;
+}
+
+API int contacts_db_insert_record( contacts_record_h record, int *id )
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       if (id)
+               *id = 0;
+
+       RETVM_IF(record==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"record is NULL");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_record(record,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_INSERT_RECORD, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check outdata
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+
+                       if (id)
+                               *id = *(int*)pims_ipc_data_get(outdata,&size);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int        contacts_db_get_record( const char* view_uri, int id, contacts_record_h* out_record )
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(view_uri==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"view_uri is NULL");
+       RETVM_IF(id<0,CONTACTS_ERROR_INVALID_PARAMETER,"id<0");
+       RETVM_IF(out_record==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"record is NULL");
+       *out_record = NULL;
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_string(view_uri,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int(id,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_RECORD, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check outdata
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+               if (ret == CONTACTS_ERROR_NONE)
+               {
+                       ret = ctsvc_ipc_unmarshal_record(outdata,out_record);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_db_update_record( contacts_record_h record )
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(record==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"record is NULL");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_record(record,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_UPDATE_RECORD, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check outdata
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_db_delete_record( const char* view_uri, int id )
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(view_uri==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"view_uri is NULL");
+       RETVM_IF(id<=0,CONTACTS_ERROR_INVALID_PARAMETER,"id <= 0");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_string(view_uri,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int(id,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_DELETE_RECORD, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check outdata
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_db_replace_record( contacts_record_h record, int id )
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : record is NULL");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL) {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_record(record, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int(id, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE,
+                               CTSVC_IPC_SERVER_DB_REPLACE_RECORD, indata, &outdata) != 0) {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata) {
+               // check outdata
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_db_get_all_records( const char* view_uri, int offset, int limit, contacts_list_h* out_list )
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(out_list==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"list is NULL");
+       *out_list = NULL;
+       RETVM_IF(view_uri==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"view_uri is NULL");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_string(view_uri,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int(offset,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int(limit,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_ALL_RECORDS, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check outdata
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+               if (ret == CONTACTS_ERROR_NONE)
+               {
+                       ret = ctsvc_ipc_unmarshal_list(outdata,out_list);
+               }
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_db_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list )
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(out_list==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"list is NULL");
+       *out_list = NULL;
+       RETVM_IF(query==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"query is NULL");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_query(query,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int(offset,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int(limit,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_RECORDS_WITH_QUERY, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check outdata
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+               if (ret == CONTACTS_ERROR_NONE)
+               {
+                       ret = ctsvc_ipc_unmarshal_list(outdata,out_list);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_db_get_count( const char* view_uri, int *out_count )
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(view_uri==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"view_uri is NULL");
+       RETVM_IF(out_count==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"count pointer is NULL");
+       *out_count = 0;
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_string(view_uri,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_COUNT, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check outdata
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+               if (ret == CONTACTS_ERROR_NONE)
+               {
+                       ret = ctsvc_ipc_unmarshal_int(outdata,out_count);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_db_get_count_with_query( contacts_query_h query, int *out_count )
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(query==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"record is NULL");
+       RETVM_IF(out_count==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"count pointer is NULL");
+       *out_count = 0;
+
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_query(query,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_COUNT_WITH_QUERY, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check outdata
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+               if (ret == CONTACTS_ERROR_NONE)
+               {
+                       ret = ctsvc_ipc_unmarshal_int(outdata,out_count);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+// this function used in contacts_db_delete_records_async
+static int __ctsvc_db_check_permission_by_view_uri(const char *view_uri, bool check_read)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       bool result = false;
+
+       if (strcmp(view_uri, CTSVC_VIEW_URI_PHONELOG) == 0) {
+               if (check_read)
+                       ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_PHONELOG_READ, &result);
+               else
+                       ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_PHONELOG_WRITE, &result);
+       }
+       else if ((strcmp(view_uri, CTSVC_VIEW_URI_ADDRESSBOOK) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_PERSON) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_GROUP) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_CONTACT) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_MY_PROFILE) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_NAME) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_COMPANY) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_NOTE) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_NUMBER) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_EMAIL) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_URL) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_EVENT) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_NICKNAME) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_ADDRESS) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_MESSENGER) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_GROUP_RELATION) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_ACTIVITY) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_ACTIVITY_PHOTO) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_PROFILE) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_RELATIONSHIP) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_IMAGE) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_EXTENSION) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_SPEEDDIAL) == 0)
+                       || (strcmp(view_uri, CTSVC_VIEW_URI_SDN) == 0)
+                       ) {
+               if (check_read)
+                       ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_CONTACT_READ, &result);
+               else
+                       ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_CONTACT_WRITE, &result);
+       }
+       else {
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "ctsvc_ipc_client_check_permission fail (%d)", ret);
+       RETVM_IF(result == false, CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied (phonelog read)");
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_check_permission_by_type(int r_type, bool check_read)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       bool result = false;
+
+       switch((int)r_type) {
+       case CTSVC_RECORD_ADDRESSBOOK:
+       case CTSVC_RECORD_GROUP:
+       case CTSVC_RECORD_PERSON:
+       case CTSVC_RECORD_CONTACT:
+       case CTSVC_RECORD_MY_PROFILE:
+       case CTSVC_RECORD_SIMPLE_CONTACT:
+       case CTSVC_RECORD_NAME:
+       case CTSVC_RECORD_COMPANY:
+       case CTSVC_RECORD_NOTE:
+       case CTSVC_RECORD_NUMBER:
+       case CTSVC_RECORD_EMAIL:
+       case CTSVC_RECORD_URL:
+       case CTSVC_RECORD_EVENT:
+       case CTSVC_RECORD_NICKNAME:
+       case CTSVC_RECORD_ADDRESS:
+       case CTSVC_RECORD_MESSENGER:
+       case CTSVC_RECORD_GROUP_RELATION:
+       case CTSVC_RECORD_ACTIVITY:
+       case CTSVC_RECORD_ACTIVITY_PHOTO:
+       case CTSVC_RECORD_PROFILE:
+       case CTSVC_RECORD_RELATIONSHIP:
+       case CTSVC_RECORD_IMAGE:
+       case CTSVC_RECORD_EXTENSION:
+       case CTSVC_RECORD_SPEEDDIAL:
+       case CTSVC_RECORD_SDN:
+       case CTSVC_RECORD_UPDATED_INFO:
+       {
+               if (check_read)
+                       ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_CONTACT_READ, &result);
+               else
+                       ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_CONTACT_WRITE, &result);
+       }
+               break;
+       case CTSVC_RECORD_PHONELOG:
+       {
+               if (check_read)
+                       ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_PHONELOG_READ, &result);
+               else
+                       ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_PHONELOG_WRITE, &result);
+       }
+               break;
+       default:
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "ctsvc_ipc_client_check_permission fail (%d)", ret);
+       RETVM_IF(result == false, CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied (phonelog read)");
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_db_insert_records_async(const contacts_list_h list, contacts_db_insert_result_cb callback, void *user_data)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       ctsvc_ipc_async_userdata_s *async_data = NULL;
+       int r_type;
+
+       RETVM_IF(list==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"list is NULL");
+
+       r_type = ((ctsvc_list_s*)list)->l_type;
+       ret = __ctsvc_db_check_permission_by_type(r_type, false);
+       RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "__ctsvc_db_check_permission_by_type fail (%d)", ret);
+
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL) {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_list(list,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       async_data = (ctsvc_ipc_async_userdata_s*)malloc(sizeof(ctsvc_ipc_async_userdata_s));
+       if (async_data == NULL) {
+               CTS_ERR("malloc fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       async_data->callback = callback;
+       async_data->user_data = user_data;
+
+       if (ctsvc_ipc_call_async(CTSVC_IPC_DB_MODULE,CTSVC_IPC_SERVER_DB_INSERT_RECORDS,
+                               indata,__ctsvc_ipc_client_insert_records_cb,async_data) != 0) {
+               CONTACTS_FREE(async_data);
+               CTS_ERR("ctsvc_ipc_call_async failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+       pims_ipc_data_destroy(indata);
+
+       return ret;
+}
+
+API int contacts_db_update_records_async(const contacts_list_h list, contacts_db_result_cb callback, void *user_data)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       ctsvc_ipc_async_userdata_s *async_data = NULL;
+       int r_type;
+
+       RETVM_IF(list==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"record is NULL");
+
+       r_type = ((ctsvc_list_s*)list)->l_type;
+       ret = __ctsvc_db_check_permission_by_type(r_type, false);
+       RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "__ctsvc_db_check_permission_by_type fail (%d)", ret);
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL) {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_list(list,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       async_data = (ctsvc_ipc_async_userdata_s*)malloc(sizeof(ctsvc_ipc_async_userdata_s));
+       if (async_data == NULL) {
+               CTS_ERR("malloc fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       async_data->callback = callback;
+       async_data->user_data = user_data;
+
+       if (ctsvc_ipc_call_async(CTSVC_IPC_DB_MODULE,CTSVC_IPC_SERVER_DB_UPDATE_RECORDS,
+                               indata,__ctsvc_ipc_client_update_records_cb,async_data) != 0) {
+               CONTACTS_FREE(async_data);
+               CTS_ERR("ctsvc_ipc_call_async failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+       pims_ipc_data_destroy(indata);
+
+       return ret;
+}
+
+API int contacts_db_delete_records_async(const char* view_uri, int ids[], int count, contacts_db_result_cb callback, void *user_data)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       int i = 0;
+       ctsvc_ipc_async_userdata_s *async_data = NULL;
+
+       RETVM_IF(view_uri==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"view_uri is NULL");
+       RETVM_IF(NULL == ids, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(0 == count, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       ret = __ctsvc_db_check_permission_by_view_uri(view_uri, false);
+       RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "__ctsvc_db_check_permission_by_view_uri fail (%d)", ret);
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL) {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_string(view_uri,indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int(count,indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       for (i=0;i<count;i++) {
+               ret = ctsvc_ipc_marshal_int(ids[i],indata);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("marshal fail");
+                       pims_ipc_data_destroy(indata);
+                       return ret;
+               }
+       }
+
+       async_data = (ctsvc_ipc_async_userdata_s*)malloc(sizeof(ctsvc_ipc_async_userdata_s));
+       if (async_data == NULL) {
+               CTS_ERR("malloc fail!");
+               pims_ipc_data_destroy(indata);
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+       async_data->callback = callback;
+       async_data->user_data = user_data;
+       if (ctsvc_ipc_call_async(CTSVC_IPC_DB_MODULE,CTSVC_IPC_SERVER_DB_DELETE_RECORDS,
+                               indata,__ctsvc_ipc_client_delete_records_cb,async_data) != 0) {
+               CONTACTS_FREE(async_data);
+               CTS_ERR("ctsvc_ipc_call_async failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       return ret;
+}
+
+void __ctsvc_ipc_client_replace_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata)
+{
+       ctsvc_ipc_async_userdata_s *async_data = (ctsvc_ipc_async_userdata_s *)userdata;
+       int ret = CONTACTS_ERROR_NONE;
+
+       if (data_out) {
+               ctsvc_ipc_unmarshal_int(data_out, &ret);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       ctsvc_ipc_unmarshal_int(data_out, &transaction_ver);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+       }
+
+       if (async_data->callback) {
+               contacts_db_result_cb callback = async_data->callback;
+               callback(ret, async_data->user_data);
+       }
+
+       ctsvc_inotify_call_blocked_callback();
+
+       free(async_data);
+
+       return ;
+}
+
+API int contacts_db_replace_records_async( contacts_list_h list, int ids[], int count,
+               contacts_db_result_cb callback, void *user_data )
+{
+       int i;
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       ctsvc_ipc_async_userdata_s *async_data = NULL;
+       bool result = false;
+
+       RETVM_IF(NULL == list,CONTACTS_ERROR_INVALID_PARAMETER, "list is NULL");
+       RETVM_IF(NULL == ids, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(count <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_CONTACT_WRITE, &result);
+       RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "ctsvc_ipc_client_check_permission fail (%d)", ret);
+       RETVM_IF(result == false, CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied (contact read)");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL) {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_list(list, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int(count, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       for (i=0;i<count;i++) {
+               ret = ctsvc_ipc_marshal_int(ids[i],indata);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("marshal fail");
+                       pims_ipc_data_destroy(indata);
+                       return ret;
+               }
+       }
+
+       async_data = (ctsvc_ipc_async_userdata_s*)malloc(sizeof(ctsvc_ipc_async_userdata_s));
+       async_data->callback = callback;
+       async_data->user_data = user_data;
+
+       if (ctsvc_ipc_call_async(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_REPLACE_RECORDS,
+                               indata, __ctsvc_ipc_client_replace_records_cb, async_data) != 0) {
+               CONTACTS_FREE(async_data);
+               CTS_ERR("ctsvc_ipc_call_async failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+       pims_ipc_data_destroy(indata);
+
+       return ret;
+}
+
+API int contacts_db_insert_records( contacts_list_h list, int **ids, int *count)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       if (ids)
+               *ids = NULL;
+       if (count)
+               *count = 0;
+
+       RETVM_IF(list==NULL,CONTACTS_ERROR_INVALID_PARAMETER, "list is NULL");
+
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL) {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_list(list,indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_INSERT_RECORDS,
+                               indata, &outdata) != 0) {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata) {
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+
+                       if (ids && count) {
+                               int i = 0;
+                               int *id = NULL;
+                               int c;
+                               c = *(int*)pims_ipc_data_get(outdata, &size);
+                               id = calloc(c, sizeof(int));
+                               for(i=0;i<c;i++)
+                                       id[i] = *(int*) pims_ipc_data_get(outdata, &size);
+                               *ids = id;
+                               *count = c;
+                       }
+               }
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_db_update_records( contacts_list_h list)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER, "list is NULL");
+
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL) {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_list(list,indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_UPDATE_RECORDS,
+                               indata, &outdata) != 0) {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata) {
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_db_delete_records(const char* view_uri, int ids[], int count)
+{
+       int i;
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(view_uri == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "view_uri is NULL");
+
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL) {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_string(view_uri,indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int(count,indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       for (i=0;i<count;i++) {
+               ret = ctsvc_ipc_marshal_int(ids[i],indata);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("marshal fail");
+                       pims_ipc_data_destroy(indata);
+                       return ret;
+               }
+       }
+
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_DELETE_RECORDS,
+                               indata, &outdata) != 0) {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata) {
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_db_replace_records( contacts_list_h list, int ids[], int count )
+{
+       int i;
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(NULL == list,CONTACTS_ERROR_INVALID_PARAMETER, "list is NULL");
+       RETVM_IF(NULL == ids, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(0 == count, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL) {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_list(list, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int(count, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       for (i=0;i<count;i++) {
+               ret = ctsvc_ipc_marshal_int(ids[i], indata);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("marshal fail");
+                       pims_ipc_data_destroy(indata);
+                       return ret;
+               }
+       }
+
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_REPLACE_RECORDS,
+                               indata, &outdata) != 0) {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata) {
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_db_get_changes_by_version(const char* view_uri, int addressbook_id, int contacts_db_version, contacts_list_h* record_list, int* current_contacts_db_version )
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(record_list==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"record_list is NULL");
+       *record_list = NULL;
+       RETVM_IF(view_uri==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"view_uri is NULL");
+       RETVM_IF(current_contacts_db_version==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"current_contacts_db_version is NULL");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_string(view_uri,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int(addressbook_id,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int(contacts_db_version,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_CHANGES_BY_VERSION, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check outdata
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+               if (ret == CONTACTS_ERROR_NONE)
+               {
+                       ret = ctsvc_ipc_unmarshal_list(outdata,record_list);
+
+                       if (ret == CONTACTS_ERROR_NONE)
+                       {
+                               ret = ctsvc_ipc_unmarshal_int(outdata,current_contacts_db_version);
+                       }
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_db_get_current_version(int* contacts_db_version)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(contacts_db_version==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"contacts_db_version is null");
+       *contacts_db_version = 0;
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_CURRENT_VERSION, NULL, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               return CONTACTS_ERROR_IPC;
+       }
+
+       if (outdata)
+       {
+               // check outdata
+               ctsvc_ipc_unmarshal_int(outdata, &ret);
+               if (ret == CONTACTS_ERROR_NONE)
+               {
+                       ret = ctsvc_ipc_unmarshal_int(outdata,contacts_db_version);
+               }
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_db_search_records(const char* view_uri, const char *keyword,
+               int offset, int limit, contacts_list_h* out_list)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(out_list == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "list is NULL");
+       *out_list = NULL;
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail !");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_string(view_uri,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_string(keyword,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int(offset,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int(limit,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_SEARCH_RECORDS, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check outdata
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+               if (ret == CONTACTS_ERROR_NONE)
+               {
+                       ret = ctsvc_ipc_unmarshal_list(outdata,out_list);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_db_search_records_with_range(const char* view_uri, const char *keyword,
+               int offset, int limit, int range, contacts_list_h* out_list)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(out_list == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "list is NULL");
+       *out_list = NULL;
+       RETVM_IF(range == 0, CONTACTS_ERROR_INVALID_PARAMETER, "range is 0");
+
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL) {
+               CTS_ERR("ipc data created fail !");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       ret = ctsvc_ipc_marshal_string(view_uri, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               goto DATA_FREE;
+       }
+       ret = ctsvc_ipc_marshal_string(keyword, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               goto DATA_FREE;
+       }
+       ret = ctsvc_ipc_marshal_int(offset, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               goto DATA_FREE;
+       }
+       ret = ctsvc_ipc_marshal_int(limit, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               goto DATA_FREE;
+       }
+       ret = ctsvc_ipc_marshal_int(range, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               goto DATA_FREE;
+       }
+
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_SEARCH_RECORDS_WITH_RANGE, indata, &outdata) != 0) {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata) {
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+               if (ret == CONTACTS_ERROR_NONE)
+                       ret = ctsvc_ipc_unmarshal_list(outdata,out_list);
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+
+DATA_FREE:
+       pims_ipc_data_destroy(indata);
+       return ret;
+}
+
+API int contacts_db_search_records_with_query(contacts_query_h query, const char *keyword,
+               int offset, int limit, contacts_list_h* out_list)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(out_list==NULL, CONTACTS_ERROR_INVALID_PARAMETER, "list is NULL");
+       *out_list = NULL;
+       RETVM_IF(query==NULL, CONTACTS_ERROR_INVALID_PARAMETER, "query is NULL");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail !");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_query(query,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_string(keyword,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int(offset,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int(limit,indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_SEARCH_RECORDS_WITH_QUERY, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check outdata
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+               if (ret == CONTACTS_ERROR_NONE)
+               {
+                       ret = ctsvc_ipc_unmarshal_list(outdata,out_list);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_db_get_last_change_version(int* last_version)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       bool result = false;
+
+       RETVM_IF(NULL == last_version, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       *last_version = 0;
+
+       ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_CONTACT_READ, &result);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_ipc_client_check_permission fail (%d)", ret);
+       if (result == false) {
+               ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_PHONELOG_READ, &result);
+               RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_ipc_client_check_permission fail (%d)", ret);
+               RETVM_IF(result == false, CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied");
+       }
+
+       *last_version = ctsvc_client_ipc_get_change_version();
+       return ret;
+}
+
+typedef struct
+{
+       contacts_db_status_changed_cb cb;
+       void *user_data;
+}status_callback_info_s;
+
+static GSList *__status_change_subscribe_list = NULL;
+
+static void __ctsvc_db_status_subscriber_callback(pims_ipc_h ipc, pims_ipc_data_h data, void *user_data)
+{
+       int status = -1;
+       GSList *l;
+
+       if (data)
+               ctsvc_ipc_unmarshal_int(data, &status);
+
+       for (l = __status_change_subscribe_list;l;l=l->next) {
+               status_callback_info_s *cb_info = l->data;
+               if (cb_info->cb)
+                       cb_info->cb(status, cb_info->user_data);
+       }
+}
+
+API int contacts_db_get_status(contacts_db_status_e *status)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(status == NULL, CONTACTS_ERROR_INVALID_PARAMETER,"The out param is NULL");
+       *status = 0;
+
+       if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_STATUS, NULL, &outdata) != 0) {
+               CTS_ERR("ctsvc_ipc_call failed");
+               return CONTACTS_ERROR_IPC;
+       }
+
+       if (outdata) {
+               unsigned int size = 0;
+               ctsvc_ipc_unmarshal_int(outdata, &ret);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       ctsvc_ipc_unmarshal_int(outdata, (int *)status);
+               }
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_db_add_status_changed_cb(
+               contacts_db_status_changed_cb cb, void* user_data)
+{
+       status_callback_info_s *cb_info = NULL;
+       RETVM_IF(NULL == cb, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : callback is null");
+
+       ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+
+       if (pims_ipc_subscribe(ctsvc_ipc_get_handle_for_change_subsciption(),
+                               CTSVC_IPC_SUBSCRIBE_MODULE, CTSVC_IPC_SERVER_DB_STATUS_CHANGED,
+                               __ctsvc_db_status_subscriber_callback, NULL) != 0) {
+               CTS_ERR("pims_ipc_subscribe error\n");
+               ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       cb_info = calloc(1, sizeof(status_callback_info_s));
+       RETVM_IF(NULL == cb_info, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+       cb_info->user_data = user_data;
+       cb_info->cb = cb;
+       __status_change_subscribe_list = g_slist_append(__status_change_subscribe_list, cb_info);
+
+       ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_db_remove_status_changed_cb(
+               contacts_db_status_changed_cb cb, void* user_data)
+{
+       GSList *l;
+
+       RETVM_IF(NULL == cb, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : callback is null");
+
+       ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+       for(l = __status_change_subscribe_list;l;l=l->next) {
+               status_callback_info_s *cb_info = l->data;
+               if (cb == cb_info->cb && user_data == cb_info->user_data) {
+                       __status_change_subscribe_list = g_slist_remove(__status_change_subscribe_list, cb_info);
+                       break;
+               }
+       }
+
+       if (g_slist_length(__status_change_subscribe_list) == 0) {
+               pims_ipc_unsubscribe(ctsvc_ipc_get_handle_for_change_subsciption(),
+                               CTSVC_IPC_SUBSCRIBE_MODULE, CTSVC_IPC_SERVER_DB_STATUS_CHANGED);
+               g_slist_free(__status_change_subscribe_list);
+               __status_change_subscribe_list = NULL;
+       }
+
+       ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/client/ctsvc_client_group.c b/client/ctsvc_client_group.c
new file mode 100644 (file)
index 0000000..00ea286
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <glib.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_ipc_define.h"
+#include "ctsvc_client_ipc.h"
+#include <pims-ipc-data.h>
+#include "ctsvc_ipc_marshal.h"
+
+API int contacts_group_add_contact(int group_id, int contact_id)
+{
+       int ret = CONTACTS_ERROR_NONE;
+
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(group_id <= 0 || contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,"id should be greater than 0");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int( group_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int( contact_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_GROUP_MODULE, CTSVC_IPC_SERVER_GROUP_ADD_CONTACT, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check result
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata, &size);
+
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_group_remove_contact(int group_id, int contact_id)
+{
+       int ret = CONTACTS_ERROR_NONE;
+
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(group_id <= 0 || contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,"id should be greater than 0");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int( group_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int( contact_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_GROUP_MODULE, CTSVC_IPC_SERVER_GROUP_REMOVE_CONTACT, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check result
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata, &size);
+
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_group_set_group_order(int group_id, int previous_group_id, int next_group_id)
+{
+       int ret = CONTACTS_ERROR_NONE;
+
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(group_id <= 0 || previous_group_id < 0 || next_group_id < 0, CONTACTS_ERROR_INVALID_PARAMETER,"id should be greater than 0");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int( group_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int( previous_group_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int( next_group_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_GROUP_MODULE, CTSVC_IPC_SERVER_GROUP_SET_GROUP_ORDER, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check result
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata, &size);
+
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+
+}
+
diff --git a/client/ctsvc_client_ipc.c b/client/ctsvc_client_ipc.c
new file mode 100644 (file)
index 0000000..6fc233b
--- /dev/null
@@ -0,0 +1,437 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <glib.h>
+#include <stdlib.h>
+#include <pims-ipc-data.h>
+#include <security-server.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#include "ctsvc_client_ipc.h"
+
+#include "ctsvc_internal.h"
+#include "ctsvc_list.h"
+#include "ctsvc_record.h"
+#include "ctsvc_query.h"
+#include "ctsvc_inotify.h"
+
+#include "ctsvc_ipc_define.h"
+#include "ctsvc_ipc_marshal.h"
+#include "ctsvc_view.h"
+#include "ctsvc_mutex.h"
+#include "ctsvc_client_service.h"
+
+struct ctsvc_ipc_s {
+       pims_ipc_h ipc;
+       int change_version;
+};
+
+static GHashTable *_ctsvc_ipc_table = NULL;
+static bool _ctsvc_ipc_disconnected = false;
+
+static int __ctsvc_ipc_get_cookie_for_access_control(pims_ipc_data_h *indata)
+{
+       int ret;
+       size_t cookie_size = 0;
+       pims_ipc_data_h data;
+       char *buf;
+
+       // Access control : get cookie from security-server
+       cookie_size = security_server_get_cookie_size();
+       if (cookie_size <= 0) {
+               CTS_ERR("security_server_get_cookie_size fail(%d)", cookie_size);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       char cookie[cookie_size];
+       cookie[0] = '\0';
+       ret = security_server_request_cookie(cookie, cookie_size);
+       if(ret < 0) {
+               CTS_ERR("security_server_request_cookie fail (%d)", ret);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       // Access control : put cookie to indata
+       data = pims_ipc_data_create(0);
+       if (data == NULL) {
+               CTS_ERR("ipc data created fail!");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       ret = ctsvc_ipc_marshal_unsigned_int(cookie_size, data);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_ipc_marshal_int fail");
+               pims_ipc_data_destroy(data);
+               return ret;
+       }
+
+       buf = g_base64_encode((const guchar *)cookie, cookie_size);
+       if (buf) {
+               ret = ctsvc_ipc_marshal_string(buf, data);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_marshal_string fail");
+                       pims_ipc_data_destroy(data);
+                       return ret;
+               }
+               free(buf);
+       }
+       else {
+               CTS_ERR("g_base64_encode fail");
+               pims_ipc_data_destroy(data);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       *indata = data;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+#define CTS_STR_SHORT_LEN 1024 //short sql string length
+
+static inline void _ctsvc_ipc_get_pid_str(char *buf, int buf_size)
+{
+       pid_t pid = getpid();
+       snprintf(buf, buf_size, "%d", pid);
+}
+
+static inline void _ctsvc_ipc_get_tid_str(char *buf, int buf_size)
+{
+       pid_t tid = syscall(SYS_gettid);
+       snprintf(buf, buf_size, "%d", tid);
+}
+
+static void _ctsvc_ipc_data_free(gpointer p)
+{
+       struct ctsvc_ipc_s *ipc_data = p;
+       if (NULL == ipc_data)
+               return;
+
+       if (ipc_data->ipc)
+               pims_ipc_destroy(ipc_data->ipc);
+
+       free(ipc_data);
+}
+
+static int _ctsvc_ipc_server_connect(pims_ipc_h *p_ipc)
+{
+       int ret;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       pims_ipc_h ipc = pims_ipc_create(CTSVC_IPC_SOCKET_PATH);
+       if (NULL == ipc) {
+               if (errno == EACCES) {
+                       CTS_ERR("pims_ipc_create() Failed(%d)", CONTACTS_ERROR_PERMISSION_DENIED);
+                       return CONTACTS_ERROR_PERMISSION_DENIED;
+               }
+               else {
+                       CTS_ERR("pims_ipc_create() Failed(%d)", CONTACTS_ERROR_IPC_NOT_AVALIABLE);
+                       return CONTACTS_ERROR_IPC_NOT_AVALIABLE;
+               }
+       }
+       ret = __ctsvc_ipc_get_cookie_for_access_control(&indata);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_ipc_get_cookie_for_access_control fail (%d)", ret);
+               goto DATA_FREE;
+       }
+
+       // ipc call
+       if (pims_ipc_call(ipc, CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_CONNECT, indata, &outdata) != 0) {
+               CTS_ERR("pims_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               ret = CONTACTS_ERROR_IPC;
+               goto DATA_FREE;
+       }
+       pims_ipc_data_destroy(indata);
+
+       if (outdata) {
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+               pims_ipc_data_destroy(outdata);
+
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_server_connect return(%d)", ret);
+                       goto DATA_FREE;
+               }
+       }
+       *p_ipc = ipc;
+       return CONTACTS_ERROR_NONE;
+DATA_FREE:
+       pims_ipc_destroy(ipc);
+       return ret;
+}
+
+static struct ctsvc_ipc_s* _ctsvc_get_ipc_data()
+{
+       struct ctsvc_ipc_s *ipc_data = NULL;
+       char ipc_key[CTS_STR_SHORT_LEN] = {0};
+       RETVM_IF(NULL == _ctsvc_ipc_table, NULL, "contacts not connected");
+
+       _ctsvc_ipc_get_tid_str(ipc_key, sizeof(ipc_key));
+       ipc_data = g_hash_table_lookup(_ctsvc_ipc_table, ipc_key);
+       if (ipc_data) {
+               return ipc_data;
+       }
+
+       _ctsvc_ipc_get_pid_str(ipc_key, sizeof(ipc_key));
+       ipc_data = g_hash_table_lookup(_ctsvc_ipc_table, ipc_key);
+       if (ipc_data) {
+               return ipc_data;
+       }
+
+
+       return NULL;
+}
+
+pims_ipc_h ctsvc_get_ipc_handle()
+{
+       struct ctsvc_ipc_s *ipc_data = _ctsvc_get_ipc_data();
+       if (ipc_data)
+               return ipc_data->ipc;
+
+       return NULL;
+}
+
+bool ctsvc_ipc_is_busy()
+{
+       bool ret = false;
+
+       pims_ipc_h ipc = ctsvc_get_ipc_handle();
+       if (NULL == ipc) {
+               CTS_ERR("ctsvc_get_ipc_handle() return NULL");
+               return false;
+       }
+
+       ret = pims_ipc_is_call_in_progress(ipc);
+       if (ret)
+               CTS_ERR("global ipc channel is busy.");
+
+       return ret;
+}
+
+int ctsvc_ipc_connect(void)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       struct ctsvc_ipc_s *ipc_data = NULL;
+       char ipc_key[CTS_STR_SHORT_LEN] = {0};
+
+       RETV_IF(_ctsvc_ipc_disconnected, CONTACTS_ERROR_IPC_NOT_AVALIABLE);
+
+       _ctsvc_ipc_get_tid_str(ipc_key, sizeof(ipc_key));
+
+       if (NULL == _ctsvc_ipc_table)
+               _ctsvc_ipc_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, _ctsvc_ipc_data_free);
+       else
+               ipc_data = g_hash_table_lookup(_ctsvc_ipc_table, ipc_key);
+
+       // ipc create
+       if (ipc_data == NULL) {
+               ipc_data = calloc(1, sizeof(struct ctsvc_ipc_s));
+               ret = _ctsvc_ipc_server_connect(&(ipc_data->ipc));
+               if (CONTACTS_ERROR_NONE != ret) {
+                       _ctsvc_ipc_data_free(ipc_data);
+                       return ret;
+               }
+               g_hash_table_insert(_ctsvc_ipc_table, strdup(ipc_key), ipc_data);
+       }
+       else
+               CTS_DBG("[GLOBAL_IPC_CHANNEL] contacts already connected");
+
+       return CONTACTS_ERROR_NONE;
+}
+
+
+int ctsvc_ipc_disconnect(void)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h outdata = NULL;
+
+       RETV_IF(_ctsvc_ipc_disconnected, CONTACTS_ERROR_IPC_NOT_AVALIABLE);
+
+       struct ctsvc_ipc_s *ipc_data = NULL;
+       char ipc_key[CTS_STR_SHORT_LEN] = {0};
+       _ctsvc_ipc_get_tid_str(ipc_key, sizeof(ipc_key));
+
+       RETVM_IF(NULL == _ctsvc_ipc_table, CONTACTS_ERROR_IPC, "contacts not connected");
+       ipc_data = g_hash_table_lookup(_ctsvc_ipc_table, ipc_key);
+       RETVM_IF(ipc_data == NULL, CONTACTS_ERROR_IPC, "contacts not connected");
+
+       if (pims_ipc_call(ipc_data->ipc, CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_DISCONNECT, NULL, &outdata) != 0) {
+               CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc_call failed");
+               return CONTACTS_ERROR_IPC;
+       }
+
+       if (outdata) {
+               ctsvc_ipc_unmarshal_int(outdata, &ret);
+               pims_ipc_data_destroy(outdata);
+
+               if (ret != CONTACTS_ERROR_NONE)
+                       CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc didn't destroyed!!!(%d)", ret);
+
+               g_hash_table_remove(_ctsvc_ipc_table, ipc_key);
+       }
+       else {
+               CTS_ERR("pims_ipc_call out data is NULL");
+               return CONTACTS_ERROR_IPC;
+       }
+       return ret;
+}
+
+static void __ctsvc_ipc_lock()
+{
+       if (0 == ctsvc_client_get_thread_connection_count())
+               ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_CALL);
+}
+
+static void __ctsvc_ipc_unlock(void)
+{
+       if (0 == ctsvc_client_get_thread_connection_count())
+               ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_CALL);
+}
+
+int ctsvc_ipc_call(char *module, char *function, pims_ipc_h data_in, pims_ipc_data_h *data_out)
+{
+       RETV_IF(_ctsvc_ipc_disconnected, CONTACTS_ERROR_IPC_NOT_AVALIABLE);
+       pims_ipc_h ipc_handle = ctsvc_get_ipc_handle();
+
+       __ctsvc_ipc_lock();
+
+       int ret = pims_ipc_call(ipc_handle, module, function, data_in, data_out);
+
+       __ctsvc_ipc_unlock();
+
+       return ret;
+}
+
+int ctsvc_ipc_call_async(char *module, char *function, pims_ipc_h data_in, pims_ipc_call_async_cb callback, void *userdata)
+{
+       RETV_IF(_ctsvc_ipc_disconnected, CONTACTS_ERROR_IPC_NOT_AVALIABLE);
+       pims_ipc_h ipc_handle = ctsvc_get_ipc_handle();
+
+       __ctsvc_ipc_lock();
+
+       int ret = pims_ipc_call_async(ipc_handle, module, function, data_in, callback, userdata);
+
+       __ctsvc_ipc_unlock();
+
+       return ret;
+}
+
+void ctsvc_client_ipc_set_change_version(int version)
+{
+       struct ctsvc_ipc_s *ipc_data = _ctsvc_get_ipc_data();
+       RETM_IF(NULL == ipc_data, "_ctsvc_get_ipc_data() return NULL");
+
+       ipc_data->change_version = version;
+       CTS_DBG("change_version = %d", version);
+}
+
+int ctsvc_client_ipc_get_change_version(void)
+{
+       struct ctsvc_ipc_s *ipc_data = _ctsvc_get_ipc_data();
+       RETVM_IF(NULL == ipc_data, 0, "_ctsvc_get_ipc_data() return NULL");
+       return ipc_data->change_version;
+}
+
+int ctsvc_ipc_client_check_permission(int permission, bool *result)
+{
+       RETV_IF(_ctsvc_ipc_disconnected, CONTACTS_ERROR_IPC_NOT_AVALIABLE);
+
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+       int ret;
+
+       if (result)
+               *result = false;
+
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL) {
+               CTS_ERR("ipc data created fail !");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       ret = ctsvc_ipc_marshal_int(permission, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       if (ctsvc_ipc_call(CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_CHECK_PERMISSION, indata, &outdata) != 0) {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata) {
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+               if (ret == CONTACTS_ERROR_NONE) {
+                       if (result)
+                               *result = *(bool*) pims_ipc_data_get(outdata, &size);
+               }
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+static int disconnected_cb_count = 0;
+
+int ctsvc_ipc_set_disconnected_cb(void (*cb)(void *), void *user_data)
+{
+       if (0 == disconnected_cb_count++)
+               return pims_ipc_set_server_disconnected_cb(cb, user_data);
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_unset_disconnected_cb()
+{
+       if (1 == disconnected_cb_count--)
+               return pims_ipc_unset_server_disconnected_cb();
+       return CONTACTS_ERROR_NONE;
+}
+
+void ctsvc_ipc_set_disconnected(bool is_disconnected)
+{
+       _ctsvc_ipc_disconnected = is_disconnected;
+}
+
+static void _ctsvc_ipc_recovery_foreach_cb(gpointer key, gpointer value, gpointer user_data)
+{
+       struct ctsvc_ipc_s *ipc_data = value;
+       int ret = _ctsvc_ipc_server_connect(&(ipc_data->ipc));
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "_ctsvc_ipc_server_connect() Fail(%d)", ret);
+}
+
+void ctsvc_ipc_recovery()
+{
+       if (false == _ctsvc_ipc_disconnected)
+               return;
+
+       g_hash_table_foreach(_ctsvc_ipc_table, _ctsvc_ipc_recovery_foreach_cb, NULL);
+}
+
+
diff --git a/client/ctsvc_client_ipc.h b/client/ctsvc_client_ipc.h
new file mode 100644 (file)
index 0000000..7243858
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CTSVC_CLIENT_IPC_H__
+#define __TIZEN_SOCIAL_CTSVC_CLIENT_IPC_H__
+
+#include <pims-ipc.h>
+
+pims_ipc_h ctsvc_get_ipc_handle();
+
+int ctsvc_ipc_connect(void);
+int ctsvc_ipc_disconnect(void);
+
+void ctsvc_ipc_set_disconnected(bool is_disconnected);
+void ctsvc_ipc_recovery();
+
+bool ctsvc_ipc_is_busy();
+
+pims_ipc_h ctsvc_ipc_get_handle_for_change_subsciption();
+
+int ctsvc_ipc_create_for_change_subscription();
+int ctsvc_ipc_destroy_for_change_subscription();
+int ctsvc_ipc_recover_for_change_subscription();
+
+int ctsvc_ipc_call(char *module, char *function, pims_ipc_h data_in, pims_ipc_data_h *data_out);
+int ctsvc_ipc_call_async(char *module, char *function, pims_ipc_h data_in, pims_ipc_call_async_cb callback, void *userdata);
+
+void ctsvc_client_ipc_set_change_version(int version);
+int ctsvc_client_ipc_get_change_version(void);
+
+int ctsvc_ipc_client_check_permission(int permission, bool *result);
+
+int ctsvc_ipc_set_disconnected_cb(void (*cb)(void *), void *user_data);
+int ctsvc_ipc_unset_disconnected_cb();
+
+#endif /*  __TIZEN_SOCIAL_CTSVC_CLIENT_IPC_H__ */
+
diff --git a/client/ctsvc_client_noti.c b/client/ctsvc_client_noti.c
new file mode 100644 (file)
index 0000000..43720ae
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <pims-ipc.h>
+#include <pims-ipc-svc.h>
+#include <pims-ipc-data.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_ipc_define.h"
+#include "ctsvc_mutex.h"
+#include "ctsvc_client_ipc.h"
+
+typedef struct
+{
+       contacts_db_change_cb_with_info cb;
+       void *user_data;
+}db_callback_info_s;
+
+typedef struct
+{
+       char *view_uri;
+       GSList *callbacks;
+}subscribe_info_s;
+
+static int __ipc_pubsub_ref = 0;
+static pims_ipc_h __ipc = NULL;
+static GSList *__db_change_subscribe_list = NULL;
+
+static void __ctsvc_db_subscriber_callback(pims_ipc_h ipc, pims_ipc_data_h data, void *user_data)
+{
+       unsigned int size = 0;
+       char *str = NULL;
+       subscribe_info_s *info = user_data;
+
+       if (data)
+               str = (char*)pims_ipc_data_get(data, &size);
+
+       if (!str) {
+               CTS_ERR("There is no changed data");
+               return;
+       }
+
+       if (info) {
+               GSList *l;
+               for (l = info->callbacks;l;l=l->next) {
+                       db_callback_info_s *cb_info = l->data;
+                       if (cb_info->cb) {
+                               cb_info->cb(info->view_uri, str, cb_info->user_data);
+                       }
+               }
+       }
+}
+
+// This API should be called in CTS_MUTEX_PIMS_IPC_PUBSUB mutex
+pims_ipc_h ctsvc_ipc_get_handle_for_change_subsciption()
+{
+       return __ipc;
+}
+
+
+int ctsvc_ipc_create_for_change_subscription()
+{
+       ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+
+       if (0 < __ipc_pubsub_ref) {
+               __ipc_pubsub_ref++;
+               ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+               return CONTACTS_ERROR_NONE;
+       }
+
+       if (!__ipc) {
+               __ipc = pims_ipc_create_for_subscribe(CTSVC_IPC_SOCKET_PATH_FOR_CHANGE_SUBSCRIPTION);
+               if (!__ipc) {
+                       CTS_ERR("pims_ipc_create_for_subscribe error\n");
+                       ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+                       return CONTACTS_ERROR_IPC;
+               }
+       }
+       __ipc_pubsub_ref++;
+       ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_recover_for_change_subscription()
+{
+       ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+       if (__ipc_pubsub_ref <= 0)
+               return CONTACTS_ERROR_NONE;
+       __ipc = pims_ipc_create_for_subscribe(CTSVC_IPC_SOCKET_PATH_FOR_CHANGE_SUBSCRIPTION);
+       if (!__ipc) {
+               CTS_ERR("pims_ipc_create_for_subscribe error\n");
+               ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+               return CONTACTS_ERROR_IPC;
+       }
+       ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_destroy_for_change_subscription()
+{
+       ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+
+       if (1 == __ipc_pubsub_ref) {
+               pims_ipc_destroy_for_subscribe(__ipc);
+               __ipc = NULL;
+       }
+       else if (1 < __ipc_pubsub_ref) {
+               CTS_DBG("ctsvc pubsub ipc ref count : %d", __ipc_pubsub_ref);
+       }
+       else {
+               CTS_DBG("System : please call connection APIs, connection count is (%d)", __ipc_pubsub_ref);
+               ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       __ipc_pubsub_ref--;
+
+       ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_db_add_changed_cb_with_info(const char* view_uri,
+               contacts_db_change_cb_with_info cb, void* user_data)
+{
+       GSList *it = NULL;
+       subscribe_info_s *info = NULL;
+       db_callback_info_s *cb_info;
+       bool result = false;
+       int ret;
+
+       RETVM_IF(view_uri == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "view_uri is NULL");
+       RETVM_IF(cb == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "cb is NULL");
+
+       if (strncmp(view_uri, CTSVC_VIEW_URI_PHONELOG, strlen(CTSVC_VIEW_URI_PHONELOG)) == 0) {
+               ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_PHONELOG_READ, &result);
+               RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "ctsvc_ipc_client_check_permission fail (%d)", ret);
+               RETVM_IF(result == false, CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied (phonelog read)");
+       }
+       else if (strncmp(view_uri, CTSVC_VIEW_URI_PERSON, strlen(CTSVC_VIEW_URI_PERSON)) == 0) {
+               ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_CONTACT_READ, &result);
+               RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "ctsvc_ipc_client_check_permission fail (%d)", ret);
+               RETVM_IF(result == false, CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied (contact read)");
+       }
+       else {
+               CTS_ERR("We support this API for only %s and %s", CTSVC_VIEW_URI_PERSON, CTSVC_VIEW_URI_PHONELOG);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+
+       for (it=__db_change_subscribe_list;it;it=it->next) {
+               if (!it->data) continue;
+
+               info = it->data;
+               if (strcmp(info->view_uri, view_uri) == 0)
+                       break;
+               else
+                       info = NULL;
+       }
+
+       if (!info) {
+               info = calloc(1, sizeof(subscribe_info_s));
+               if (NULL == info) {
+                       CTS_ERR("calloc() Failed");
+                       ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+               }
+
+               if (pims_ipc_subscribe(__ipc, CTSVC_IPC_SUBSCRIBE_MODULE, (char*)view_uri,
+                                       __ctsvc_db_subscriber_callback, (void*)info) != 0) {
+                       CTS_ERR("pims_ipc_subscribe error\n");
+                       free(info);
+                       ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+                       return CONTACTS_ERROR_IPC;
+               }
+               info->view_uri = strdup(view_uri);
+               __db_change_subscribe_list = g_slist_append(__db_change_subscribe_list, info);
+       }
+       else {
+               GSList *l;
+               for (l = info->callbacks;l;l=l->next) {
+                       db_callback_info_s *cb_info = l->data;
+                       if (cb_info->cb == cb && cb_info->user_data == user_data) {
+                               CTS_ERR("The same callback(%s) is already exist", view_uri);
+                               ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+                               return CONTACTS_ERROR_INVALID_PARAMETER;
+                       }
+               }
+       }
+
+       cb_info = calloc(1, sizeof(db_callback_info_s));
+       cb_info->user_data = user_data;
+       cb_info->cb = cb;
+       info->callbacks = g_slist_append(info->callbacks, cb_info);
+
+       ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_db_remove_changed_cb_with_info(const char* view_uri,
+               contacts_db_change_cb_with_info cb, void* user_data)
+{
+       GSList *it = NULL;
+       subscribe_info_s *info = NULL;
+
+       RETVM_IF(view_uri == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "view_uri is NULL");
+       RETVM_IF(cb == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "cb is NULL");
+
+       if (strcmp(view_uri, CTSVC_VIEW_URI_PHONELOG) != 0 &&
+                       strcmp(view_uri, CTSVC_VIEW_URI_PERSON) != 0) {
+               CTS_ERR("We support this API for only %s and %s", CTSVC_VIEW_URI_PERSON, CTSVC_VIEW_URI_PHONELOG);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+
+       for (it=__db_change_subscribe_list;it;it=it->next) {
+               if (!it->data) continue;
+
+               info = it->data;
+               if (strcmp(info->view_uri, view_uri) == 0)
+                       break;
+               else
+                       info = NULL;
+       }
+
+       if (info) {
+               GSList *l;
+               for(l = info->callbacks;l;l=l->next) {
+                       db_callback_info_s *cb_info = l->data;
+                       if (cb == cb_info->cb && user_data == cb_info->user_data) {
+                               info->callbacks = g_slist_remove(info->callbacks, cb_info);
+                               free(cb_info);
+                               break;
+                       }
+               }
+               if (g_slist_length(info->callbacks) == 0) {
+                       pims_ipc_unsubscribe(__ipc, CTSVC_IPC_SUBSCRIBE_MODULE, info->view_uri);
+                       __db_change_subscribe_list = g_slist_remove(__db_change_subscribe_list, info);
+                       free(info->view_uri);
+                       free(info);
+               }
+       }
+
+       ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+       return CONTACTS_ERROR_NONE;
+}
diff --git a/client/ctsvc_client_person.c b/client/ctsvc_client_person.c
new file mode 100644 (file)
index 0000000..d235a61
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <glib.h>
+#include <pims-ipc-data.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_ipc_define.h"
+#include "ctsvc_client_ipc.h"
+#include "ctsvc_ipc_marshal.h"
+
+API int contacts_person_link_person(int base_person_id, int person_id)
+{
+
+       int ret = CONTACTS_ERROR_NONE;
+
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(base_person_id <= 0 || person_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,"id should be greater than 0");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       bool success = false;
+       do {
+               if( ctsvc_ipc_marshal_int( base_person_id, indata) != CONTACTS_ERROR_NONE ) break;
+               if( ctsvc_ipc_marshal_int( person_id, indata) != CONTACTS_ERROR_NONE ) break;
+
+               success = true;
+       } while(0);
+
+       if( success == false ) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+/*
+       ret = ctsvc_ipc_marshal_int( base_person_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int( person_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               return ret;
+       }
+*/
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_LINK_PERSON, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check result
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata, &size);
+
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_person_unlink_contact(int person_id, int contact_id, int* unlinked_person_id)
+{
+       int ret = CONTACTS_ERROR_NONE;
+
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(person_id <= 0 || contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,"id should be greater than 0");
+
+       if (unlinked_person_id)
+               *unlinked_person_id = 0;
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int( person_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int( contact_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_UNLINK_CONTACT, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check result
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata, &size);
+
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+
+                       if (unlinked_person_id)
+                               *unlinked_person_id = *(int*)pims_ipc_data_get(outdata,&size);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_person_reset_usage(int person_id, contacts_usage_type_e type)
+{
+       int ret = CONTACTS_ERROR_NONE;
+
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(person_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,"contact_id should be greater than 0");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int( person_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int( (int)type, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_RESET_USAGE, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check result
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata, &size);
+
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_person_set_favorite_order(int person_id, int previous_person_id, int next_person_id)
+{
+       int ret = CONTACTS_ERROR_NONE;
+
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(person_id <= 0 || previous_person_id < 0 || next_person_id < 0, CONTACTS_ERROR_INVALID_PARAMETER,"id should be greater than 0");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int( person_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int( previous_person_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int( next_person_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_SET_FAVORITE_ORDER, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check result
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata, &size);
+
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+
+}
+
+API int contacts_person_set_default_property(contacts_person_property_e property,
+               int person_id, int id)
+{
+       int ret = CONTACTS_ERROR_NONE;
+
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(person_id <= 0 || id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,"id should be greater than 0");
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int( person_id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_unsigned_int( property, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+       ret = ctsvc_ipc_marshal_int( id, indata);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_SET_DEFAULT_PROPERTY, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check result
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata, &size);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_person_get_default_property(contacts_person_property_e property,
+               int person_id, int *id)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(person_id <= 0 || id == NULL, CONTACTS_ERROR_INVALID_PARAMETER,"id should be greater than 0");
+       *id = 0;
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL) {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int(person_id, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_unsigned_int(property, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_GET_DEFAULT_PROPERTY,
+                               indata, &outdata) != 0) {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata) {
+               // check result
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata, &size);
+               if (ret == CONTACTS_ERROR_NONE) {
+                       if (id)
+                               *id = *(int*)pims_ipc_data_get(outdata,&size);
+               }
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
diff --git a/client/ctsvc_client_phonelog.c b/client/ctsvc_client_phonelog.c
new file mode 100644 (file)
index 0000000..3d64dd3
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <glib.h>
+#include <pims-ipc-data.h>
+
+#include "contacts.h"
+#include "contacts_phone_log_internal.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_ipc_define.h"
+#include "ctsvc_client_ipc.h"
+#include "ctsvc_ipc_marshal.h"
+
+API int contacts_phone_log_reset_statistics(void)
+{
+#ifndef ENABLE_LOG_FEATURE
+       return CONTACTS_ERROR_NOT_SUPPORTED;
+#endif // ENABLE_LOG_FEATURE
+
+       int ret = CONTACTS_ERROR_NONE;
+
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       // make indata
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL)
+       {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       // ipc call
+       if (ctsvc_ipc_call(CTSVC_IPC_PHONELOG_MODULE, CTSVC_IPC_SERVER_PHONELOG_RESET_STATISTICS, indata, &outdata) != 0)
+       {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata)
+       {
+               // check result
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata, &size);
+
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+
+}
+
+API int contacts_phone_log_delete(contacts_phone_log_delete_e op, ...)
+{
+#ifndef ENABLE_LOG_FEATURE
+       return CONTACTS_ERROR_NOT_SUPPORTED;
+#endif // ENABLE_LOG_FEATURE
+
+       int ret = CONTACTS_ERROR_NONE;
+
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+       char *number = NULL;
+       int extra_data1;
+
+       va_list args;
+
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL) {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int( op, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_ipc_marshal_int fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       switch(op) {
+       case CONTACTS_PHONE_LOG_DELETE_BY_ADDRESS:
+               va_start(args, op);
+               number = va_arg(args, char *);
+               va_end(args);
+               if (NULL == number) {
+                       pims_ipc_data_destroy(indata);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               ret = ctsvc_ipc_marshal_string(number, indata);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_marshal_string fail");
+                       pims_ipc_data_destroy(indata);
+                       return ret;
+               }
+               break;
+       case CONTACTS_PHONE_LOG_DELETE_BY_MESSAGE_EXTRA_DATA1:
+       case CONTACTS_PHONE_LOG_DELETE_BY_EMAIL_EXTRA_DATA1:
+               va_start(args, op);
+               extra_data1 = va_arg(args, int);
+               va_end(args);
+               ret = ctsvc_ipc_marshal_int(extra_data1, indata);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_marshal_int fail");
+                       pims_ipc_data_destroy(indata);
+                       return ret;
+               }
+               break;
+       default:
+               CTS_ERR("Invalid parameter : operation is not proper (%d)", ret);
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (ctsvc_ipc_call(CTSVC_IPC_PHONELOG_MODULE,
+                       CTSVC_IPC_SERVER_PHONELOG_DELETE, indata, &outdata) != 0) {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       if (outdata) {
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata, &size);
+
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int transaction_ver = 0;
+                       transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+                       ctsvc_client_ipc_set_change_version(transaction_ver);
+               }
+
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
diff --git a/client/ctsvc_client_service.c b/client/ctsvc_client_service.c
new file mode 100644 (file)
index 0000000..9487937
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <pims-ipc-data.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_socket.h"
+#include "ctsvc_mutex.h"
+#include "ctsvc_inotify.h"
+#include "ctsvc_client_ipc.h"
+
+static int _ctsvc_connection = 0;
+
+static __thread int _ctsvc_connection_on_thread = 0;
+
+int ctsvc_client_get_thread_connection_count()
+{
+       return _ctsvc_connection_on_thread;
+}
+
+API int contacts_connect_with_flags(unsigned int flags)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+
+       // If new flag is defined, errer check should be updated
+       RETVM_IF(flags & 0x11111110, CONTACTS_ERROR_INVALID_PARAMETER, "flags is invalid");
+
+       ret = contacts_connect();
+       if (ret == CONTACTS_ERROR_PERMISSION_DENIED)
+               return ret;
+       else if (ret == CONTACTS_ERROR_NONE)
+               return ret;
+
+       if (flags & CONTACTS_CONNECT_FLAG_RETRY) {
+               int i;
+               int waiting_time = 500;
+               for (i=0;i<9;i++) {
+                       usleep(waiting_time * 1000);
+                       CTS_DBG("retry cnt=%d, ret=%x, %d",(i+1), ret, waiting_time);
+                       ret = contacts_connect();
+                       if (ret == CONTACTS_ERROR_NONE)
+                               break;
+                       if (6 < i)
+                               waiting_time += 30000;
+                       else
+                               waiting_time *= 2;
+               }
+       }
+
+       return ret;
+}
+
+static void _ctsvc_ipc_disconnected_cb(void *user_data)
+{
+       ctsvc_ipc_set_disconnected(true);
+}
+
+static void _ctsvc_ipc_initialized_cb(void *user_data)
+{
+       ctsvc_ipc_recovery();
+       ctsvc_ipc_recover_for_change_subscription();
+       ctsvc_ipc_set_disconnected(false);
+}
+
+
+API int contacts_connect(void)
+{
+       CTS_FN_CALL;
+       int ret;
+
+       ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
+       if (0 == _ctsvc_connection) {
+               ret = ctsvc_ipc_connect();
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_connect() Failed(%d)", ret);
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return ret;
+               }
+
+               ret = ctsvc_socket_init();
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_socket_init() Failed(%d)", ret);
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return ret;
+               }
+
+               ret = ctsvc_inotify_init();
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_inotify_init() Failed(%d)", ret);
+                       ctsvc_socket_final();
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return ret;
+               }
+               ctsvc_inotify_subscribe_ipc_ready(_ctsvc_ipc_initialized_cb, NULL);
+
+               ctsvc_view_uri_init();
+               ctsvc_ipc_create_for_change_subscription();
+               ctsvc_ipc_set_disconnected_cb(_ctsvc_ipc_disconnected_cb, NULL);
+       }
+       else
+               CTS_DBG("System : Contacts service has been already connected(%d)", _ctsvc_connection + 1);
+
+       _ctsvc_connection++;
+       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_disconnect(void)
+{
+       int ret;
+
+       CTS_FN_CALL;
+
+       ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
+       if (1 == _ctsvc_connection) {
+               ctsvc_ipc_destroy_for_change_subscription();
+
+               ret = ctsvc_ipc_disconnect();
+               if (ret != CONTACTS_ERROR_NONE) {
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       CTS_ERR("ctsvc_ipc_disconnect() Failed(%d)", ret);
+                       return ret;
+               }
+
+               ctsvc_view_uri_deinit();
+               ctsvc_inotify_unsubscribe_ipc_ready();
+               ctsvc_inotify_close();
+               ctsvc_socket_final();
+               ctsvc_ipc_unset_disconnected_cb();
+       }
+       else if (1 < _ctsvc_connection)
+               CTS_DBG("System : connection count is %d", _ctsvc_connection);
+       else {
+               CTS_DBG("System : please call contacts_connect(), connection count is (%d)", _ctsvc_connection);
+               ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       _ctsvc_connection--;
+       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_connect_on_thread(void)
+{
+       int ret;
+
+       ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
+
+       if (0 == _ctsvc_connection_on_thread) {
+               ret = ctsvc_ipc_connect();
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_connect() Failed(%d)", ret);
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return ret;
+               }
+
+               ret = ctsvc_socket_init();
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_socket_init() Failed(%d)", ret);
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return ret;
+               }
+
+               ret = ctsvc_inotify_init();
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_inotify_init() Failed(%d)", ret);
+                       ctsvc_socket_final();
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return ret;
+               }
+               ctsvc_inotify_subscribe_ipc_ready(_ctsvc_ipc_initialized_cb, NULL);
+
+               ctsvc_view_uri_init();
+               ctsvc_ipc_create_for_change_subscription();
+               ctsvc_ipc_set_disconnected_cb(_ctsvc_ipc_disconnected_cb, NULL);
+       }
+       else if (0 < _ctsvc_connection_on_thread)
+               CTS_DBG("System : Contacts service has been already connected");
+
+       _ctsvc_connection_on_thread++;
+
+       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_disconnect_on_thread(void)
+{
+       int ret;
+
+       ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
+
+       if (1 == _ctsvc_connection_on_thread) {
+               ctsvc_ipc_destroy_for_change_subscription();
+
+               ret = ctsvc_ipc_disconnect();
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_disconnect() Failed(%d)", ret);
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return ret;
+               }
+
+               ctsvc_view_uri_deinit();
+               ctsvc_inotify_unsubscribe_ipc_ready();
+               ctsvc_inotify_close();
+               ctsvc_socket_final();
+               ctsvc_ipc_unset_disconnected_cb();
+               CTS_DBG("System : connection_on_thread was destroyed successfully");
+       }
+       else if (1 < _ctsvc_connection_on_thread) {
+               CTS_DBG("System : connection count is %d", _ctsvc_connection_on_thread);
+       }
+       else {
+               CTS_DBG("System : please call contacts_connect_on_thread(), connection count is (%d)", _ctsvc_connection_on_thread);
+               ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       _ctsvc_connection_on_thread--;
+
+       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/client/ctsvc_client_service.h b/client/ctsvc_client_service.h
new file mode 100644 (file)
index 0000000..4d3e4ef
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CTSVC_CLIENT_SERVICE_H__
+#define __TIZEN_SOCIAL_CTSVC_CLIENT_SERVICE_H__
+
+int ctsvc_client_get_thread_connection_count();
+
+#endif /*  __TIZEN_SOCIAL_CTSVC_CLIENT_SERVICE_H__ */
+
diff --git a/client/ctsvc_client_setting.c b/client/ctsvc_client_setting.c
new file mode 100755 (executable)
index 0000000..e524538
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <glib.h>
+#include <pims-ipc-data.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_notify.h"
+#include "ctsvc_ipc_define.h"
+#include "ctsvc_ipc_marshal.h"
+#include "ctsvc_client_ipc.h"
+#include "ctsvc_mutex.h"
+
+API int contacts_setting_get_name_display_order(contacts_name_display_order_e *name_display_order)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(name_display_order == NULL, CONTACTS_ERROR_INVALID_PARAMETER,"The out param is NULL");
+       *name_display_order = 0;
+
+       if (ctsvc_ipc_call(CTSVC_IPC_SETTING_MODULE, CTSVC_IPC_SERVER_SETTING_GET_NAME_DISPLAY_ORDER, NULL, &outdata) != 0) {
+               CTS_ERR("ctsvc_ipc_call failed");
+               return CONTACTS_ERROR_IPC;
+       }
+
+       if (outdata) {
+               ctsvc_ipc_unmarshal_int(outdata, &ret);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       ctsvc_ipc_unmarshal_int(outdata, (int *)name_display_order);
+               }
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_setting_get_name_sorting_order(contacts_name_sorting_order_e *name_sorting_order)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(name_sorting_order == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "The out param is NULL");
+       *name_sorting_order = 0;
+
+       if (ctsvc_ipc_call(CTSVC_IPC_SETTING_MODULE, CTSVC_IPC_SERVER_SETTING_GET_NAME_SORTING_ORDER, NULL, &outdata) != 0) {
+               CTS_ERR("ctsvc_ipc_call failed");
+               return CONTACTS_ERROR_IPC;
+       }
+
+       if (outdata) {
+               ctsvc_ipc_unmarshal_int(outdata, &ret);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       ctsvc_ipc_unmarshal_int(outdata, (int *)name_sorting_order);
+               }
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_setting_set_name_display_order(contacts_name_display_order_e name_display_order)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(name_display_order != CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST
+                       && name_display_order != CONTACTS_NAME_DISPLAY_ORDER_LASTFIRST,
+                       CONTACTS_ERROR_INVALID_PARAMETER, "name display order is invalid : %d", name_display_order);
+
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL) {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int(name_display_order, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       if (ctsvc_ipc_call(CTSVC_IPC_SETTING_MODULE, CTSVC_IPC_SERVER_SETTING_SET_NAME_DISPLAY_ORDER, indata, &outdata) != 0) {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+       pims_ipc_data_destroy(indata);
+
+       if (outdata) {
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata, &size);
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+API int contacts_setting_set_name_sorting_order(contacts_name_sorting_order_e name_sorint_order)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       pims_ipc_data_h indata = NULL;
+       pims_ipc_data_h outdata = NULL;
+
+       RETVM_IF(name_sorint_order != CONTACTS_NAME_SORTING_ORDER_FIRSTLAST
+                       && name_sorint_order != CONTACTS_NAME_SORTING_ORDER_LASTFIRST,
+                       CONTACTS_ERROR_INVALID_PARAMETER, "name sorting order is invalid : %d", name_sorint_order);
+
+       indata = pims_ipc_data_create(0);
+       if (indata == NULL) {
+               CTS_ERR("ipc data created fail!");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               return ret;
+       }
+
+       ret = ctsvc_ipc_marshal_int(name_sorint_order, indata);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("marshal fail");
+               pims_ipc_data_destroy(indata);
+               return ret;
+       }
+
+       if (ctsvc_ipc_call(CTSVC_IPC_SETTING_MODULE, CTSVC_IPC_SERVER_SETTING_SET_NAME_SORTING_ORDER, indata, &outdata) != 0) {
+               CTS_ERR("ctsvc_ipc_call failed");
+               pims_ipc_data_destroy(indata);
+               return CONTACTS_ERROR_IPC;
+       }
+       pims_ipc_data_destroy(indata);
+
+       if (outdata) {
+               unsigned int size = 0;
+               ret = *(int*) pims_ipc_data_get(outdata, &size);
+               pims_ipc_data_destroy(outdata);
+       }
+
+       return ret;
+}
+
+typedef struct
+{
+       contacts_setting_name_display_order_changed_cb cb;
+       void *user_data;
+}ctsvc_name_display_order_changed_cb_info_s;
+
+static GSList *__setting_name_display_order_subscribe_list = NULL;
+
+static void __ctsvc_setting_name_display_order_subscriber_callback(pims_ipc_h ipc, pims_ipc_data_h data, void *user_data)
+{
+       int value = -1;
+       if (data)
+               ctsvc_ipc_unmarshal_int(data, &value);
+
+       if (__setting_name_display_order_subscribe_list) {
+               GSList *l;
+               for (l = __setting_name_display_order_subscribe_list;l;l=l->next) {
+                       ctsvc_name_display_order_changed_cb_info_s *cb_info = l->data;
+                       if (cb_info->cb)
+                               cb_info->cb((contacts_name_display_order_e)value, cb_info->user_data);
+               }
+       }
+}
+
+API int contacts_setting_add_name_display_order_changed_cb(
+       contacts_setting_name_display_order_changed_cb cb, void* user_data)
+{
+       GSList *l;
+       int ret;
+       bool result = false;
+       ctsvc_name_display_order_changed_cb_info_s *cb_info;
+
+       RETVM_IF(cb == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : callback is NULL");
+
+       ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_CONTACT_READ, &result);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_ipc_client_check_permission fail (%d)", ret);
+       RETVM_IF(result == false, CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied (contact read)");
+
+       ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+
+       if (!__setting_name_display_order_subscribe_list) {
+               if (pims_ipc_subscribe(ctsvc_ipc_get_handle_for_change_subsciption(),
+                                       CTSVC_IPC_SUBSCRIBE_MODULE, CTSVC_SETTING_DISPLAY_ORDER_CHANGED,
+                                       __ctsvc_setting_name_display_order_subscriber_callback, NULL) != 0) {
+                       CTS_ERR("pims_ipc_subscribe error\n");
+                       ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+                       return CONTACTS_ERROR_IPC;
+               }
+       }
+
+       for (l = __setting_name_display_order_subscribe_list;l;l=l->next) {
+               ctsvc_name_display_order_changed_cb_info_s *cb_info = l->data;
+               if (cb_info->cb == cb && cb_info->user_data == user_data) {
+                       CTS_ERR("The same callback(%s) is already exist");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+
+       cb_info = calloc(1, sizeof(ctsvc_name_display_order_changed_cb_info_s));
+       cb_info->user_data = user_data;
+       cb_info->cb = cb;
+       __setting_name_display_order_subscribe_list = g_slist_append(__setting_name_display_order_subscribe_list, cb_info);
+
+       ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_setting_remove_name_display_order_changed_cb(
+       contacts_setting_name_display_order_changed_cb cb, void* user_data)
+{
+       RETVM_IF(cb == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : callback is NULL");
+
+       ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+
+       if (__setting_name_display_order_subscribe_list) {
+               GSList *l;
+               for(l = __setting_name_display_order_subscribe_list;l;l=l->next) {
+                       ctsvc_name_display_order_changed_cb_info_s *cb_info = l->data;
+                       if (cb == cb_info->cb && user_data == cb_info->user_data) {
+                               __setting_name_display_order_subscribe_list = g_slist_remove(__setting_name_display_order_subscribe_list, cb_info);
+                               free(cb_info);
+                               break;
+                       }
+               }
+               if (g_slist_length(__setting_name_display_order_subscribe_list) == 0) {
+                       pims_ipc_unsubscribe(ctsvc_ipc_get_handle_for_change_subsciption(),
+                                       CTSVC_IPC_SUBSCRIBE_MODULE, CTSVC_SETTING_DISPLAY_ORDER_CHANGED);
+                       g_slist_free(__setting_name_display_order_subscribe_list);
+                       __setting_name_display_order_subscribe_list = NULL;
+               }
+       }
+
+       ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+       return CONTACTS_ERROR_NONE;
+}
+
+typedef struct
+{
+       contacts_setting_name_sorting_order_changed_cb cb;
+       void *user_data;
+}ctsvc_name_sorting_order_changed_cb_info_s;
+
+static GSList *__setting_name_sorting_order_subscribe_list = NULL;
+
+static void __ctsvc_setting_name_sorting_order_subscriber_callback(pims_ipc_h ipc, pims_ipc_data_h data, void *user_data)
+{
+       int value = -1;
+       if (data)
+               ctsvc_ipc_unmarshal_int(data, &value);
+
+       if (__setting_name_sorting_order_subscribe_list) {
+               GSList *l;
+               for (l = __setting_name_sorting_order_subscribe_list;l;l=l->next) {
+                       ctsvc_name_sorting_order_changed_cb_info_s *cb_info = l->data;
+                       if (cb_info->cb)
+                               cb_info->cb((contacts_name_sorting_order_e)value, cb_info->user_data);
+               }
+       }
+}
+
+API int contacts_setting_add_name_sorting_order_changed_cb(
+       contacts_setting_name_sorting_order_changed_cb cb, void* user_data)
+{
+       GSList *l;
+       int ret;
+       bool result = false;
+       ctsvc_name_sorting_order_changed_cb_info_s *cb_info;
+
+       RETVM_IF(cb == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : callback is NULL");
+
+       ret = ctsvc_ipc_client_check_permission(CTSVC_PERMISSION_CONTACT_READ, &result);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_ipc_client_check_permission fail (%d)", ret);
+       RETVM_IF(result == false, CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied (contact read)");
+
+       ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+
+       if (!__setting_name_sorting_order_subscribe_list) {
+               if (pims_ipc_subscribe(ctsvc_ipc_get_handle_for_change_subsciption(),
+                                       CTSVC_IPC_SUBSCRIBE_MODULE, CTSVC_SETTING_SORTING_ORDER_CHANGED,
+                                       __ctsvc_setting_name_sorting_order_subscriber_callback, NULL) != 0) {
+                       CTS_ERR("pims_ipc_subscribe error\n");
+                       ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+                       return CONTACTS_ERROR_IPC;
+               }
+       }
+
+       for (l = __setting_name_sorting_order_subscribe_list;l;l=l->next) {
+               ctsvc_name_sorting_order_changed_cb_info_s *cb_info = l->data;
+               if (cb_info->cb == cb && cb_info->user_data == user_data) {
+                       CTS_ERR("The same callback(%s) is already exist");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+
+       cb_info = calloc(1, sizeof(ctsvc_name_sorting_order_changed_cb_info_s));
+       cb_info->user_data = user_data;
+       cb_info->cb = cb;
+       __setting_name_sorting_order_subscribe_list = g_slist_append(__setting_name_sorting_order_subscribe_list, cb_info);
+
+       ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_setting_remove_name_sorting_order_changed_cb(
+       contacts_setting_name_sorting_order_changed_cb cb, void* user_data)
+{
+       RETVM_IF(cb == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : callback is NULL");
+
+       ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+
+       if (__setting_name_sorting_order_subscribe_list) {
+               GSList *l;
+               for(l = __setting_name_sorting_order_subscribe_list;l;l=l->next) {
+                       ctsvc_name_sorting_order_changed_cb_info_s *cb_info = l->data;
+                       if (cb == cb_info->cb && user_data == cb_info->user_data) {
+                               __setting_name_sorting_order_subscribe_list = g_slist_remove(__setting_name_sorting_order_subscribe_list, cb_info);
+                               free(cb_info);
+                               break;
+                       }
+               }
+               if (g_slist_length(__setting_name_sorting_order_subscribe_list) == 0) {
+                       pims_ipc_unsubscribe(ctsvc_ipc_get_handle_for_change_subsciption(),
+                                       CTSVC_IPC_SUBSCRIBE_MODULE, CTSVC_SETTING_SORTING_ORDER_CHANGED);
+                       g_slist_free(__setting_name_sorting_order_subscribe_list);
+                       __setting_name_sorting_order_subscribe_list = NULL;
+               }
+       }
+
+       ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/common/ctsvc_db_notification.c b/common/ctsvc_db_notification.c
new file mode 100644 (file)
index 0000000..a710943
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <glib.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_inotify.h"
+
+API int contacts_db_add_changed_cb( const char* view_uri, contacts_db_changed_cb cb,
+               void* user_data )
+{
+       int ret;
+
+       RETVM_IF(NULL == view_uri, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : view_uri is null");
+       RETVM_IF(NULL == cb, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : callback is null");
+
+       ret = ctsvc_inotify_subscribe(view_uri, cb, user_data);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret,
+                       "ctsvc_inotify_subscribe(%s) Failed(%d)", view_uri, ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_db_remove_changed_cb( const char* view_uri, contacts_db_changed_cb cb,
+               void* user_data )
+{
+       int ret;
+
+       RETVM_IF(NULL == view_uri, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : view_uri is null");
+       RETVM_IF(NULL == cb, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : callback is null");
+
+       ret = ctsvc_inotify_unsubscribe(view_uri, cb, user_data);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret,
+                       "ctsvc_inotify_unsubscribe(%s) Failed(%d)", view_uri, ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/common/ctsvc_filter.c b/common/ctsvc_filter.c
new file mode 100644 (file)
index 0000000..17c60da
--- /dev/null
@@ -0,0 +1,348 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_filter.h"
+
+static inline bool __ctsvc_filters_property_check(const property_info_s *properties,
+               int count, unsigned int property_id, int *type)
+{
+       int i;
+       for (i=0;i<count;i++) {
+               property_info_s *p = (property_info_s*)&(properties[i]);
+               if (property_id == p->property_id) {
+                       if (p->property_type == CTSVC_SEARCH_PROPERTY_ALL || p->property_type == CTSVC_SEARCH_PROPERTY_FILTER) {
+                               *type = (property_id & CTSVC_VIEW_DATA_TYPE_MASK);
+                               return true;
+                       }
+                       else
+                               return false;
+               }
+       }
+       return false;
+}
+
+API int contacts_filter_create( const char* view_uri, contacts_filter_h* out_filter )
+{
+       ctsvc_composite_filter_s *com_filter;
+
+       RETV_IF(NULL == out_filter, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_filter = NULL;
+
+       RETV_IF(NULL == view_uri, CONTACTS_ERROR_INVALID_PARAMETER);
+       com_filter = (ctsvc_composite_filter_s *)calloc(1, sizeof(ctsvc_composite_filter_s));
+       RETV_IF(NULL == com_filter, CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       com_filter->filter_type = CTSVC_FILTER_COMPOSITE;
+       com_filter->view_uri = strdup(view_uri);
+       com_filter->properties = (property_info_s *)ctsvc_view_get_all_property_infos(view_uri, &com_filter->property_count);
+       *out_filter = (contacts_filter_h)com_filter;
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_filter_add_operator( contacts_filter_h filter, contacts_filter_operator_e op )
+{
+       ctsvc_composite_filter_s *com_filter;
+
+       RETV_IF(NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       com_filter = (ctsvc_composite_filter_s*)filter;
+
+       RETVM_IF(g_slist_length(com_filter->filter_ops) != (g_slist_length(com_filter->filters)-1),
+                               CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : Please check the operator of filter");
+       com_filter->filter_ops = g_slist_append(com_filter->filter_ops, (void*)op );
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_filter_add_filter(contacts_filter_h filter1, contacts_filter_h filter2)
+{
+       int ret;
+       ctsvc_composite_filter_s *s_filter1;
+       ctsvc_composite_filter_s *s_filter2;
+       contacts_filter_h new_filter;
+
+       RETV_IF(NULL == filter1 || NULL == filter2, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_filter1 = (ctsvc_composite_filter_s *)filter1;
+       s_filter2 = (ctsvc_composite_filter_s *)filter2;
+
+       RETVM_IF(g_slist_length(s_filter1->filter_ops) != (g_slist_length(s_filter1->filters)),
+                               CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : Please check the operator of filter");
+       RETVM_IF (0 != strcmp(s_filter1->view_uri, s_filter2->view_uri), CONTACTS_ERROR_INVALID_PARAMETER,
+                               "The filter view_uri is different (filter1:%s, filter2:%s)", s_filter1->view_uri, s_filter2->view_uri);
+       ret = ctsvc_filter_clone(filter2, &new_filter);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_filter_clone is failed (%d)", ret);
+       s_filter1->filters = g_slist_append(s_filter1->filters, new_filter);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_attribute_filter_create(ctsvc_composite_filter_s *com_filter, unsigned int property_id,
+               int match, int filter_type, ctsvc_attribute_filter_s **out_filter)
+{
+       ctsvc_attribute_filter_s *filter;
+       int type;
+       bool find = false;
+
+       RETVM_IF(g_slist_length(com_filter->filter_ops) != g_slist_length(com_filter->filters),
+                               CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter :Please check the operator of filter");
+
+       find = __ctsvc_filters_property_check(com_filter->properties, com_filter->property_count, property_id, &type);
+       RETVM_IF(false == find, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : property_id(%d) is not supported on view_uri(%s)", property_id, com_filter->view_uri);
+
+       if (type == CTSVC_VIEW_DATA_TYPE_INT && CTSVC_FILTER_INT != filter_type) {
+               CTS_ERR("Invalid parameter : use contacts_filter_add_int() (%d)", filter_type);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (type == CTSVC_VIEW_DATA_TYPE_STR && CTSVC_FILTER_STR != filter_type) {
+               CTS_ERR("Invalid parameter : use contacts_filter_add_str() (%d)", filter_type);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (type == CTSVC_VIEW_DATA_TYPE_BOOL && CTSVC_FILTER_BOOL != filter_type) {
+               CTS_ERR("Invalid parameter : use contacts_filter_add_bool() (%d)", filter_type);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (type == CTSVC_VIEW_DATA_TYPE_LLI && CTSVC_FILTER_LLI != filter_type) {
+               CTS_ERR("Invalid parameter : use contacts_filter_add_lli() (%d)", filter_type);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (type == CTSVC_VIEW_DATA_TYPE_DOUBLE && CTSVC_FILTER_DOUBLE != filter_type) {
+               CTS_ERR("Invalid parameter : use contacts_filter_add_double() (%d)", filter_type);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       filter = (ctsvc_attribute_filter_s *)calloc(1, sizeof(ctsvc_attribute_filter_s));
+       RETVM_IF(NULL == filter, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+       filter->filter_type = filter_type;
+       filter->property_id = property_id;
+       filter->match = match;
+
+       com_filter->filters = g_slist_append(com_filter->filters, filter);
+       *out_filter = filter;
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_filter_add_str( contacts_filter_h filter, unsigned int property_id,
+               contacts_match_str_flag_e match, const char* match_value )
+{
+       ctsvc_composite_filter_s *com_filter;
+       ctsvc_attribute_filter_s *str_filter;
+       int ret;
+
+       RETV_IF(NULL == filter || NULL == match_value, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       com_filter = (ctsvc_composite_filter_s*)filter;
+       ret = __ctsvc_attribute_filter_create(com_filter, property_id, match, CTSVC_FILTER_STR, &str_filter);
+       RETVM_IF(CONTACTS_ERROR_NONE !=ret, ret,
+               "Invalid parameter : The parameter is not proper (view_uri:%s, property_id:0x%x, match:%d)",
+               com_filter->view_uri, property_id, match);
+
+       str_filter->value.s = SAFE_STRDUP(match_value);
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_filter_add_int( contacts_filter_h filter, unsigned int property_id,
+               contacts_match_int_flag_e match, int match_value )
+{
+       ctsvc_composite_filter_s *com_filter;
+       ctsvc_attribute_filter_s *int_filter;
+       int ret;
+
+       RETV_IF(NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETVM_IF(property_id == CTSVC_PROPERTY_PHONELOG_SIM_SLOT_NO &&
+                       (match >= CONTACTS_MATCH_GREATER_THAN && match <= CONTACTS_MATCH_LESS_THAN_OR_EQUAL),
+                       CONTACTS_ERROR_INVALID_PARAMETER, "Not support this condition");
+
+       com_filter = (ctsvc_composite_filter_s*)filter;
+       ret = __ctsvc_attribute_filter_create(com_filter, property_id, match, CTSVC_FILTER_INT, &int_filter);
+       RETVM_IF(CONTACTS_ERROR_NONE !=ret, ret,
+               "Invalid parameter : The parameter is not proper (view_uri:%s, property_id:0x%x, match:%d)",
+               com_filter->view_uri, property_id, match);
+
+       int_filter->value.i = match_value;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_filter_add_lli( contacts_filter_h filter, unsigned int property_id,
+               contacts_match_int_flag_e match, long long int match_value )
+{
+       ctsvc_composite_filter_s *com_filter;
+       ctsvc_attribute_filter_s *lli_filter;
+       int ret;
+
+       RETV_IF(NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       com_filter = (ctsvc_composite_filter_s*)filter;
+       ret = __ctsvc_attribute_filter_create(com_filter, property_id, match, CTSVC_FILTER_LLI, &lli_filter);
+       RETVM_IF(CONTACTS_ERROR_NONE !=ret, ret,
+               "Invalid parameter : The parameter is not proper (view_uri:, property_id:0x%x, match:%d)",
+               property_id, match);
+
+       lli_filter->value.l = match_value;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_filter_add_double( contacts_filter_h filter, unsigned int property_id,
+               contacts_match_int_flag_e match, double match_value )
+{
+       ctsvc_composite_filter_s *com_filter;
+       ctsvc_attribute_filter_s *double_filter;
+       int ret;
+
+       RETV_IF(NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       com_filter = (ctsvc_composite_filter_s*)filter;
+       ret = __ctsvc_attribute_filter_create(com_filter, property_id, match, CTSVC_FILTER_DOUBLE, &double_filter);
+       RETVM_IF(CONTACTS_ERROR_NONE !=ret, ret,
+               "Invalid parameter : The parameter is not proper (view_uri:, property_id:0x%x, match:%d)",
+               property_id, match);
+
+       double_filter->value.d = match_value;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_filter_add_bool( contacts_filter_h filter, unsigned int property_id, bool match_value )
+{
+       ctsvc_composite_filter_s *com_filter;
+       ctsvc_attribute_filter_s *bool_filter;
+       int ret;
+
+       RETV_IF(NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       com_filter = (ctsvc_composite_filter_s*)filter;
+       ret = __ctsvc_attribute_filter_create(com_filter, property_id, 0, CTSVC_FILTER_BOOL, &bool_filter);
+       RETVM_IF(CONTACTS_ERROR_NONE !=ret, ret,
+               "Invalid parameter : The parameter is not proper (view_uri:, property_id:%d)",
+               property_id);
+
+       bool_filter->value.b = match_value;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_composite_filter_destroy(ctsvc_composite_filter_s *com_filter)
+{
+       CTS_FN_CALL;
+       GSList *cursor;
+
+       RETV_IF(NULL == com_filter, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       for(cursor=com_filter->filters;cursor;cursor=cursor->next) {
+               ctsvc_filter_s *sub_filter = (ctsvc_filter_s *)cursor->data;
+
+               if (sub_filter->filter_type == CTSVC_FILTER_COMPOSITE)
+                       __ctsvc_composite_filter_destroy((ctsvc_composite_filter_s *)sub_filter);
+               else {
+                       ctsvc_attribute_filter_s *attr = (ctsvc_attribute_filter_s *)sub_filter;
+                       if (attr->filter_type == CTSVC_FILTER_STR)
+                               free(attr->value.s);
+                       free(attr);
+               }
+       }
+       g_slist_free(com_filter->filters);
+       g_slist_free(com_filter->filter_ops);
+
+       free(com_filter->view_uri);
+
+       free(com_filter);
+       return CONTACTS_ERROR_NONE;
+}
+
+
+API int contacts_filter_destroy( contacts_filter_h filter )
+{
+       RETV_IF(NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       return __ctsvc_composite_filter_destroy((ctsvc_composite_filter_s*)filter);
+}
+
+static int __ctsvc_attribute_filter_clone(ctsvc_attribute_filter_s *src, ctsvc_attribute_filter_s **dest)
+{
+       ctsvc_attribute_filter_s *out;
+       out = (ctsvc_attribute_filter_s *)calloc(1, sizeof(ctsvc_attribute_filter_s));
+       RETVM_IF(NULL == out, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+       out->filter_type = src->filter_type;
+       out->property_id = src->property_id;
+       out->match = src->match;
+       if (src->filter_type == CTSVC_FILTER_STR)
+               out->value.s = SAFE_STRDUP(src->value.s);
+       else if (src->filter_type == CTSVC_FILTER_INT)
+               out->value.i = src->value.i;
+       else if (src->filter_type == CTSVC_FILTER_BOOL)
+               out->value.b = src->value.b;
+       else if (src->filter_type == CTSVC_FILTER_LLI)
+               out->value.l = src->value.l;
+       else if (src->filter_type == CTSVC_FILTER_DOUBLE)
+               out->value.d = src->value.d;
+       else
+               CTS_ERR("Invalid parameter : unknown type (%d)", src->filter_type);
+
+       *dest = out;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_composite_filter_clone(ctsvc_composite_filter_s * filter,
+               ctsvc_composite_filter_s **out_filter)
+{
+       int ret;
+       GSList *cursor;
+       ctsvc_composite_filter_s *out;
+
+       RETV_IF(NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER);
+       ret = contacts_filter_create(filter->view_uri, (contacts_filter_h *)&out);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_filter_create() Fail(%d)", ret);
+
+       for(cursor=filter->filters;cursor;cursor=cursor->next) {
+               ctsvc_filter_s *src = (ctsvc_filter_s *)cursor->data;
+               ctsvc_filter_s *dest = NULL;
+
+               if (src->filter_type == CTSVC_FILTER_COMPOSITE)
+                       __ctsvc_composite_filter_clone((ctsvc_composite_filter_s *)src, (ctsvc_composite_filter_s **)&dest);
+               else
+                       __ctsvc_attribute_filter_clone((ctsvc_attribute_filter_s *)src, (ctsvc_attribute_filter_s **)&dest);
+
+               out->filters = g_slist_append(out->filters, dest);
+       }
+
+       out->filter_ops = g_slist_copy(filter->filter_ops);
+       *out_filter = out;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_filter_clone(contacts_filter_h filter, contacts_filter_h *out_filter)
+{
+       RETV_IF(NULL == filter || NULL == out_filter, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       return __ctsvc_composite_filter_clone((ctsvc_composite_filter_s *)filter, (ctsvc_composite_filter_s **)out_filter);
+}
old mode 100755 (executable)
new mode 100644 (file)
similarity index 63%
rename from src/cts-vcard-file.h
rename to common/ctsvc_filter.h
index a82d6be..31b22e4
@@ -1,32 +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_VCARD_FILE_H__
-#define __CTS_VCARD_FILE_H__
-
-#define CTS_VCARD_FILE_MAX_SIZE 1024*1024
-#define CTS_VCARD_PHOTO_MAX_SIZE 1024*100
-
-int cts_vcard_parse(const void *vcard_stream, CTSstruct **contact, int flags);
-int cts_vcard_make(const CTSstruct *contact, char **vcard_stream, int flags);
-
-#endif //__CTS_VCARD_FILE_H__
-
-
+/*\r
+ * Contacts Service\r
+ *\r
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: Dohyung Jin <dh.jin@samsung.com>\r
+ *                 Jongwon Lee <gogosing.lee@samsung.com>\r
+ *                 Donghee Ye <donghee.ye@samsung.com>\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
+\r
+#ifndef __TIZEN_SOCIAL_CTSVC_FILTER_H__\r
+#define __TIZEN_SOCIAL_CTSVC_FILTER_H__\r
+\r
+int ctsvc_filter_clone(contacts_filter_h filter, contacts_filter_h *out_filter);\r
+\r
+#endif /*  __TIZEN_SOCIAL_CTSVC_FILTER_H__ */\r
+\r
diff --git a/common/ctsvc_inotify.c b/common/ctsvc_inotify.c
new file mode 100755 (executable)
index 0000000..641a6a1
--- /dev/null
@@ -0,0 +1,477 @@
+/*
+ * 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 <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/inotify.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_notify.h"
+#include "ctsvc_view.h"
+
+#include <stdbool.h>
+
+#ifdef _CONTACTS_IPC_CLIENT
+#include "ctsvc_client_ipc.h"
+#endif
+
+typedef struct
+{
+       int wd;
+       char *view_uri;
+       contacts_db_changed_cb cb;
+       void *cb_data;
+       bool blocked;
+}noti_info;
+
+struct socket_init_noti_info {
+       int wd;
+       void (*cb)(void *);
+       void *cb_data;
+};
+
+static struct socket_init_noti_info *_ctsvc_socket_init_noti = NULL;
+static int socket_init_noti_count = 0;
+static int __ctsvc_inoti_ref = 0;
+static int __inoti_fd = -1;
+static guint __inoti_handler = 0;
+static GSList *__noti_list = NULL;
+
+void ctsvc_inotify_call_blocked_callback() {
+       noti_info *noti;
+       GSList *it = NULL;
+
+       for (it = __noti_list;it;it=it->next) {
+               noti = (noti_info *)it->data;
+
+               if (noti->cb && noti->blocked) {
+                       CTS_DBG("%s", noti->view_uri);
+                       noti->blocked = false;
+                       noti->cb(noti->view_uri, noti->cb_data);
+               }
+       }
+}
+
+static inline void __ctsvc_inotify_handle_callback(GSList *noti_list, int wd, uint32_t mask)
+{
+       noti_info *noti;
+       GSList *it = NULL;
+
+       for (it = noti_list;it;it=it->next) {
+               noti = (noti_info *)it->data;
+
+               if (noti->wd == wd) {
+
+#ifdef _CONTACTS_IPC_CLIENT
+                       if( ctsvc_ipc_is_busy() ){
+                               // hold the line
+                               noti->blocked = true;
+                               continue;
+                       }
+#endif
+                       if ((mask & IN_CLOSE_WRITE) && noti->cb) {
+                               CTS_DBG("%s", noti->view_uri);
+                               noti->cb(noti->view_uri, noti->cb_data);
+                       }
+               }
+       }
+}
+
+static gboolean __ctsvc_inotify_gio_cb(GIOChannel *src, GIOCondition cond, gpointer data)
+{
+       int fd, ret;
+       struct inotify_event ie;
+       char name[FILENAME_MAX] = {0};
+
+       fd = g_io_channel_unix_get_fd(src);
+
+       while (0 < (ret = read(fd, &ie, sizeof(ie)))) {
+               if (sizeof(ie) == ret) {
+
+                       if (_ctsvc_socket_init_noti && _ctsvc_socket_init_noti->wd == ie.wd) // socket initialized
+                               _ctsvc_socket_init_noti->cb(_ctsvc_socket_init_noti->cb_data);
+
+                       else if (__noti_list)
+                               __ctsvc_inotify_handle_callback(__noti_list, ie.wd, ie.mask);
+
+                       while (0 < ie.len) {
+                               ret = read(fd, name, (ie.len<sizeof(name))?ie.len:sizeof(name));
+                               if (-1 == ret) {
+                                       if (EINTR == errno)
+                                               continue;
+                                       else
+                                               break;
+                               }
+                               if (ie.len <= ret)
+                                       break;
+                               ie.len -= ret;
+                       }
+               }
+               else {
+                       while (ret < sizeof(ie)) {
+                               int read_size;
+                               read_size = read(fd, name, sizeof(ie)-ret);
+                               if (-1 == read_size) {
+                                       if (EINTR == errno)
+                                               continue;
+                                       else
+                                               break;
+                               }
+                               ret += read_size;
+                       }
+               }
+       }
+
+       return TRUE;
+}
+
+static inline int __ctsvc_inotify_attach_handler(int fd)
+{
+       guint ret;
+       GIOChannel *channel;
+
+       RETVM_IF(fd < 0, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter: fd is invalid");
+
+       channel = g_io_channel_unix_new(fd);
+       RETVM_IF(NULL == channel, CONTACTS_ERROR_SYSTEM, "System: g_io_channel_unix_new() Failed");
+
+       g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL);
+
+       ret = g_io_add_watch(channel, G_IO_IN, __ctsvc_inotify_gio_cb, NULL);
+       g_io_channel_unref(channel);
+
+       return ret;
+}
+
+int ctsvc_inotify_init(void)
+{
+       int ret;
+
+       if (0 < __ctsvc_inoti_ref) {
+               __ctsvc_inoti_ref++;
+               return CONTACTS_ERROR_NONE;
+       }
+       __inoti_fd = inotify_init();
+       RETVM_IF(-1 == __inoti_fd, CONTACTS_ERROR_SYSTEM,
+                       "System: inotify_init() Failed(%d)", errno);
+
+       ret = fcntl(__inoti_fd, F_SETFD, FD_CLOEXEC);
+       WARN_IF(ret < 0, "fcntl failed(%d)", ret);
+       ret = fcntl(__inoti_fd, F_SETFL, O_NONBLOCK);
+       WARN_IF(ret < 0, "fcntl failed(%d)", ret);
+
+       __inoti_handler = __ctsvc_inotify_attach_handler(__inoti_fd);
+       if (__inoti_handler <= 0) {
+               CTS_ERR("__ctsvc_inotify_attach_handler() Failed");
+               close(__inoti_fd);
+               __inoti_fd = -1;
+               __inoti_handler = 0;
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       __ctsvc_inoti_ref++;
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_inotify_get_wd(int fd, const char *notipath)
+{
+       return inotify_add_watch(fd, notipath, IN_ACCESS);
+}
+
+static inline int __ctsvc_inotify_watch(int fd, const char *notipath)
+{
+       int ret;
+
+       ret = inotify_add_watch(fd, notipath, IN_CLOSE_WRITE);
+       RETVM_IF(-1 == ret, CONTACTS_ERROR_SYSTEM,
+                       "System: inotify_add_watch() Failed(%d)", errno);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline const char* __ctsvc_noti_get_file_path(const char *view_uri)
+{
+       ctsvc_record_type_e match = ctsvc_view_get_record_type(view_uri);
+       switch((int)match) {
+       case CTSVC_RECORD_ADDRESSBOOK:
+               return CTSVC_NOTI_ADDRESSBOOK_CHANGED;
+       case CTSVC_RECORD_GROUP:
+               return CTSVC_NOTI_GROUP_CHANGED;
+       case CTSVC_RECORD_PERSON:
+               return CTSVC_NOTI_PERSON_CHANGED;
+       case CTSVC_RECORD_CONTACT:
+       case CTSVC_RECORD_SIMPLE_CONTACT:
+               return CTSVC_NOTI_CONTACT_CHANGED;
+       case CTSVC_RECORD_MY_PROFILE:
+               return CTSVC_NOTI_MY_PROFILE_CHANGED;
+       case CTSVC_RECORD_NAME:
+               return CTSVC_NOTI_NAME_CHANGED;
+       case CTSVC_RECORD_COMPANY:
+               return CTSVC_NOTI_COMPANY_CHANGED;
+       case CTSVC_RECORD_NOTE:
+               return CTSVC_NOTI_NOTE_CHANGED;
+       case CTSVC_RECORD_NUMBER:
+               return CTSVC_NOTI_NUMBER_CHANGED;
+       case CTSVC_RECORD_EMAIL:
+               return CTSVC_NOTI_EMAIL_CHANGED;
+       case CTSVC_RECORD_URL:
+               return CTSVC_NOTI_URL_CHANGED;
+       case CTSVC_RECORD_EVENT:
+               return CTSVC_NOTI_EVENT_CHANGED;
+       case CTSVC_RECORD_NICKNAME:
+               return CTSVC_NOTI_NICKNAME_CHANGED;
+       case CTSVC_RECORD_ADDRESS:
+               return CTSVC_NOTI_ADDRESS_CHANGED;
+       case CTSVC_RECORD_MESSENGER:
+               return CTSVC_NOTI_MESSENGER_CHANGED;
+       case CTSVC_RECORD_GROUP_RELATION:
+               return CTSVC_NOTI_GROUP_RELATION_CHANGED;
+       case CTSVC_RECORD_ACTIVITY:
+               return CTSVC_NOTI_ACTIVITY_CHANGED;
+       case CTSVC_RECORD_ACTIVITY_PHOTO:
+               return CTSVC_NOTI_ACTIVITY_PHOTO_CHANGED;
+       case CTSVC_RECORD_PROFILE:
+               return CTSVC_NOTI_PROFILE_CHANGED;
+       case CTSVC_RECORD_RELATIONSHIP:
+               return CTSVC_NOTI_RELATIONSHIP_CHANGED;
+       case CTSVC_RECORD_IMAGE:
+               return CTSVC_NOTI_IMAGE_CHANGED;
+       case CTSVC_RECORD_EXTENSION:
+               return CTSVC_NOTI_DATA_CHANGED;
+       case CTSVC_RECORD_PHONELOG:
+               return CTSVC_NOTI_PHONELOG_CHANGED;
+       case CTSVC_RECORD_SPEEDDIAL:
+               return CTSVC_NOTI_SPEEDDIAL_CHANGED;
+       case CTSVC_RECORD_SDN:
+               return CTSVC_NOTI_SDN_CHANGED;
+       case CTSVC_RECORD_RESULT:
+       default:
+               CTS_ERR("Invalid parameter : The type(%d) is not supported", view_uri);
+               return NULL;
+       }
+       return NULL;
+}
+
+int ctsvc_inotify_subscribe_ipc_ready(void (*cb)(void *), void *user_data)
+{
+       if (0 == socket_init_noti_count) {
+               int wd = __ctsvc_inotify_get_wd(__inoti_fd, CTSVC_NOTI_IPC_READY);
+               if (-1 == wd) {
+                       CTS_ERR("__ctsvc_inotify_get_wd() Failed(errno : %d)", errno);
+                       if (errno == EACCES)
+                               return CONTACTS_ERROR_PERMISSION_DENIED;
+                       return CONTACTS_ERROR_SYSTEM;
+               }
+               int ret = __ctsvc_inotify_watch(__inoti_fd, CTSVC_NOTI_IPC_READY);
+               RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_inotify_watch() Failed");
+
+               _ctsvc_socket_init_noti = calloc(1, sizeof(struct socket_init_noti_info));
+               _ctsvc_socket_init_noti->wd = wd;
+               _ctsvc_socket_init_noti->cb = cb;
+               _ctsvc_socket_init_noti->cb_data = user_data;
+       }
+       socket_init_noti_count++;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_inotify_unsubscribe_ipc_ready()
+{
+       RETV_IF(socket_init_noti_count <= 0, CONTACTS_ERROR_SYSTEM);
+       if (1 == socket_init_noti_count) {
+               int wd = _ctsvc_socket_init_noti->wd;
+               inotify_rm_watch(__inoti_fd, wd);
+
+               free(_ctsvc_socket_init_noti);
+               _ctsvc_socket_init_noti = NULL;
+       }
+       socket_init_noti_count--;
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_inotify_subscribe(const char *view_uri,
+                       contacts_db_changed_cb cb, void *data)
+{
+       int ret, wd;
+       noti_info *noti, *same_noti = NULL;
+       GSList *it;
+       const char *path;
+
+       RETV_IF(NULL==cb, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETVM_IF(__inoti_fd < 0, CONTACTS_ERROR_SYSTEM,
+                       "__inoti_fd(%d) is invalid", __inoti_fd);
+
+       path = __ctsvc_noti_get_file_path(view_uri);
+       RETVM_IF(NULL == path, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "__ctsvc_noti_get_file_path(%s) Failed", view_uri);
+
+       wd = __ctsvc_inotify_get_wd(__inoti_fd, path);
+       if (-1 == wd) {
+               CTS_ERR("__ctsvc_inotify_get_wd() Failed(errno : %d)", errno);
+               if (errno == EACCES)
+                       return CONTACTS_ERROR_PERMISSION_DENIED;
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       for (it=__noti_list;it;it=it->next) {
+               if (it->data) {
+                       same_noti = it->data;
+                       if (same_noti->wd == wd && same_noti->cb == cb &&
+                                       strcmp(same_noti->view_uri, view_uri) == 0 && same_noti->cb_data == data)
+                               break;
+                       else
+                               same_noti = NULL;
+               }
+       }
+
+       if (same_noti) {
+               __ctsvc_inotify_watch(__inoti_fd, path);
+               CTS_ERR("The same callback(%s) is already exist", view_uri);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = __ctsvc_inotify_watch(__inoti_fd, path);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_inotify_watch() Failed");
+
+       noti = calloc(1, sizeof(noti_info));
+       RETVM_IF(NULL == noti, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() Failed");
+
+       noti->wd = wd;
+       noti->view_uri = strdup(view_uri);
+       noti->cb_data = data;
+       noti->cb = cb;
+       noti->blocked = false;
+
+       __noti_list = g_slist_append(__noti_list, noti);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_del_noti(GSList **noti_list, int wd,
+               const char *view_uri, contacts_db_changed_cb cb, void *user_data)
+{
+       int del_cnt, remain_cnt;
+       GSList *it, *result;
+
+       del_cnt = 0;
+       remain_cnt = 0;
+
+       it = result = *noti_list;
+       while (it) {
+               noti_info *noti = it->data;
+               if (noti && wd == noti->wd) {
+                       if (cb == noti->cb && user_data == noti->cb_data
+                               && 0 == strcmp(noti->view_uri, view_uri)) {
+                               it = it->next;
+                               result = g_slist_remove(result , noti);
+                               free(noti->view_uri);
+                               free(noti);
+                               del_cnt++;
+                               continue;
+                       }
+                       else {
+                               remain_cnt++;
+                       }
+               }
+               it = it->next;
+       }
+       RETVM_IF(del_cnt == 0, CONTACTS_ERROR_NO_DATA, "No Data: nothing deleted");
+
+       *noti_list = result;
+
+       return remain_cnt;
+}
+
+int ctsvc_inotify_unsubscribe(const char *view_uri, contacts_db_changed_cb cb, void *user_data)
+{
+       int ret, wd;
+       const char *path;
+
+       RETV_IF(NULL==cb, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETVM_IF(__inoti_fd < 0, CONTACTS_ERROR_SYSTEM,
+                       "System : __inoti_fd(%d) is invalid", __inoti_fd);
+
+       path = __ctsvc_noti_get_file_path(view_uri);
+       RETVM_IF(NULL == path, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "__ctsvc_noti_get_file_path(%s) Failed", view_uri);
+
+       wd = __ctsvc_inotify_get_wd(__inoti_fd, path);
+       if (-1 == wd) {
+               CTS_ERR("__ctsvc_inotify_get_wd() Failed(errno : %d)", errno);
+               if (errno == EACCES)
+                       return CONTACTS_ERROR_PERMISSION_DENIED;
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       ret = __ctsvc_del_noti(&__noti_list, wd, view_uri, cb, user_data);
+       WARN_IF(ret < CONTACTS_ERROR_NONE, "__ctsvc_del_noti() Failed(%d)", ret);
+
+       if (0 == ret)
+               return inotify_rm_watch(__inoti_fd, wd);
+
+       return __ctsvc_inotify_watch(__inoti_fd, path);
+}
+
+static void __clear_nslot_list(gpointer data, gpointer user_data)
+{
+       noti_info *noti = (noti_info *)data;
+
+       free(noti->view_uri);
+       free(noti );
+}
+
+static inline gboolean __ctsvc_inotify_detach_handler(guint id)
+{
+       return g_source_remove(id);
+}
+
+void ctsvc_inotify_close(void)
+{
+       if (1 < __ctsvc_inoti_ref) {
+               CTS_DBG("inotify ref count : %d", __ctsvc_inoti_ref);
+               __ctsvc_inoti_ref--;
+               return;
+       }
+       else if (__ctsvc_inoti_ref < 1) {
+               CTS_DBG("Please call connection API. inotify ref count : %d", __ctsvc_inoti_ref);
+               return;
+       }
+
+       __ctsvc_inoti_ref--;
+
+       if (__inoti_handler) {
+               __ctsvc_inotify_detach_handler(__inoti_handler);
+               __inoti_handler = 0;
+       }
+
+       if (__noti_list) {
+               g_slist_foreach(__noti_list, __clear_nslot_list, NULL);
+               g_slist_free(__noti_list);
+               __noti_list = NULL;
+       }
+
+       if (0 <= __inoti_fd) {
+               close(__inoti_fd);
+               __inoti_fd = -1;
+       }
+}
diff --git a/common/ctsvc_inotify.h b/common/ctsvc_inotify.h
new file mode 100755 (executable)
index 0000000..66c0897
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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 __TIZEN_SOCIAL_CTSVC_INOTIFY_H__
+#define __TIZEN_SOCIAL_CTSVC_INOTIFY_H__
+
+#include "contacts_db.h"
+
+int ctsvc_inotify_init(void);
+void ctsvc_inotify_close(void);
+int ctsvc_inotify_subscribe(const char *view_uri, contacts_db_changed_cb cb, void *data);
+int ctsvc_inotify_unsubscribe(const char *view_uri, contacts_db_changed_cb cb, void *user_data);
+void ctsvc_inotify_call_blocked_callback();
+int ctsvc_inotify_subscribe_ipc_ready(void (*cb)(void *), void *user_data);
+int ctsvc_inotify_unsubscribe_ipc_ready();
+
+
+#endif //__TIZEN_SOCIAL_CTSVC_INOTIFY_H__
diff --git a/common/ctsvc_internal.h b/common/ctsvc_internal.h
new file mode 100644 (file)
index 0000000..bc86fb4
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 __TIZEN_SOCIAL_CTSVC_INTERNAL_H__
+#define __TIZEN_SOCIAL_CTSVC_INTERNAL_H__
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "contacts_errors.h"
+#include "ctsvc_struct.h"
+#include "ctsvc_view.h"
+
+#ifdef API
+#undef API
+#endif
+#define API __attribute__ ((visibility("default")))
+
+//#define CONTACTS_DEBUGGING
+//#define CONTACTS_TIMECHECK
+
+#define LOG_TAG "CONTACTS_SERVICE"
+#include <dlog.h>
+#define DLOG(prio, fmt, arg...) \
+       do { SLOG(prio, LOG_TAG, fmt, ##arg); } while (0)
+
+
+#if defined(_CONTACTS_IPC_SERVER)
+#define IPC_ROLE "[SERVER]"
+#elif defined(_CONTACTS_IPC_CLIENT)
+#define IPC_ROLE "[CLIENT]"
+#else
+#define IPC_ROLE "[LIB]"
+#endif
+
+#define INFO(fmt, arg...) SLOGI(IPC_ROLE" "fmt, ##arg)
+#define ERR(fmt, arg...) SLOGE(IPC_ROLE" "fmt, ##arg)
+#define DBG(fmt, arg...) SLOGD(IPC_ROLE" "fmt, ##arg)
+#define WARN(fmt, arg...) SLOGD(IPC_ROLE" "fmt, ##arg)
+#define VERBOSE(fmt, arg...) SLOGV(IPC_ROLE" "fmt, ##arg)
+
+#ifdef CONTACTS_DEBUGGING
+
+       #define CTS_FN_CALL DBG(">>>>>>>> called")
+       #define CTS_FN_END DBG("<<<<<<<< ended")
+
+       #define CTS_DBG(fmt, arg...) DBG(fmt, ##arg)
+       #define CTS_WARN(fmt, arg...) WARN(fmt, ##arg)
+       #define CTS_ERR(fmt, arg...) ERR(fmt, ##arg)
+       #define CTS_INFO(fmt, arg...) INFO(fmt, ##arg)
+       #define CTS_VERBOSE(fmt, arg...) VERBOSE(fmt, ##arg)
+
+#else /* CONTACTS_DEBUGGING */
+       #define CTS_FN_CALL
+       #define CTS_FN_END
+
+       #define CTS_DBG(fmt, arg...)
+       #define CTS_WARN(fmt, arg...)
+       #define CTS_ERR(fmt, arg...) ERR(fmt, ##arg)
+       #define CTS_INFO(fmt, arg...)
+       #define CTS_VERBOSE(fmt, arg...)
+
+       #define G_DISABLE_ASSERT
+#endif /* CONTACTS_DEBUGGING */
+
+#define WARN_IF(expr, fmt, arg...) do { \
+       if (expr) { \
+               CTS_WARN(fmt, ##arg); \
+       } \
+} while (0)
+#define RET_IF(expr) do { \
+       if (expr) { \
+               CTS_ERR("(%s)", #expr); \
+               return; \
+       } \
+} while (0)
+#define RETV_IF(expr, val) do { \
+       if (expr) { \
+               CTS_ERR("(%s)", #expr); \
+               return (val); \
+       } \
+} while (0)
+#define RETM_IF(expr, fmt, arg...) do { \
+       if (expr) { \
+               CTS_ERR(fmt, ##arg); \
+               return; \
+       } \
+} while (0)
+#define RETVM_IF(expr, val, fmt, arg...) do { \
+       if (expr) { \
+               CTS_ERR(fmt, ##arg); \
+               return (val); \
+       } \
+} while (0)
+
+
+// TO DISABLE THIS MACRO, DEFINE "G_DISABLE_ASSERT"
+#define ASSERT_NOT_REACHED(fmt, arg...) do { \
+        CTS_ERR(fmt, ##arg); \
+        assert(!"DO NOT REACH HERE!"); \
+       } while(0)
+
+
+#define CONTACTS_FREE(ptr) \
+ do { \
+  if (ptr) \
+    free(ptr); \
+  ptr = NULL; \
+ } while(0)
+
+// Thread-local storage
+#ifdef _CONTACTS_IPC_SERVER
+#define TLS __thread
+#elif _CONTACTS_IPC_CLIENT
+#define TLS __thread
+#else   //_CONTACTS_NATIVE
+#define TLS
+#endif
+
+#endif /* __TIZEN_SOCIAL_CTSVC_INTERNAL_H__ */
+
diff --git a/common/ctsvc_list.c b/common/ctsvc_list.c
new file mode 100644 (file)
index 0000000..5871b8d
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_list.h"
+#include "ctsvc_record.h"
+
+API int contacts_list_create( contacts_list_h* out_list )
+{
+       ctsvc_list_s *list_s;
+
+       RETV_IF(NULL == out_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_list = NULL;
+
+       list_s = (ctsvc_list_s*)calloc(1, sizeof(ctsvc_list_s));
+       RETVM_IF(NULL == list_s, CONTACTS_ERROR_OUT_OF_MEMORY, "Out of memory : calloc is failed");
+
+       list_s->l_type = -1;
+       *out_list = (contacts_list_h)list_s;
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_list_get_count( contacts_list_h list, int *count )
+{
+       ctsvc_list_s *list_s;
+
+       RETV_IF(NULL == count, CONTACTS_ERROR_INVALID_PARAMETER);
+       *count = 0;
+
+       RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
+       list_s = (ctsvc_list_s *)list;
+
+       *count = list_s->count;
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_list_add_child( contacts_list_h list, contacts_record_h child_record )
+{
+       ctsvc_list_s *s_list;
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == list || NULL == child_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_list = (ctsvc_list_s *)list;
+       s_record = (ctsvc_record_s *)child_record;
+
+       if (-1 == s_list->l_type) {
+               s_list->l_type = s_record->r_type;
+       }
+       else if (s_list->l_type != s_record->r_type)
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+
+       s_list->records = g_list_append(s_list->records, child_record);
+
+       if (s_list->count == 0)
+               s_list->cursor = s_list->records;
+
+       s_list->count++;
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_list_add( contacts_list_h list, contacts_record_h child_record )
+{
+       ctsvc_list_s *s_list;
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == list || NULL == child_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_list = (ctsvc_list_s *)list;
+       s_record = (ctsvc_record_s *)child_record;
+
+       if (-1 == s_list->l_type) {
+               s_list->l_type = s_record->r_type;
+       }
+       else if (s_list->l_type != s_record->r_type)
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+
+       s_list->records = g_list_append(s_list->records, child_record);
+
+       if (s_list->count == 0)
+               s_list->cursor = s_list->records;
+
+       s_list->count++;
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_list_prepend( contacts_list_h list, contacts_record_h child_record )
+{
+       ctsvc_list_s *s_list;
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == list || NULL == child_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_list = (ctsvc_list_s *)list;
+       s_record = (ctsvc_record_s *)child_record;
+
+       if (-1 == s_list->l_type) {
+               s_list->l_type = s_record->r_type;
+       }
+       else if (s_list->l_type != s_record->r_type)
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+
+       s_list->records = g_list_prepend(s_list->records, child_record);
+
+       if (s_list->count == 0)
+               s_list->cursor = s_list->records;
+
+       s_list->count++;
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_list_reverse( contacts_list_h list)
+{
+       ctsvc_list_s *s_list;
+
+       RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_list = (ctsvc_list_s *)list;
+
+
+       if (s_list->count != 0)
+               s_list->records =  g_list_reverse (s_list->records);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_list_remove_child( contacts_list_h list, contacts_record_h record, bool insert_delete_list )
+{
+       GList *cursor = NULL;
+       ctsvc_list_s *s_list;
+       ctsvc_record_s *s_record;
+       contacts_record_h delete_record;
+       contacts_error_e err = CONTACTS_ERROR_NONE;
+
+       RETV_IF(NULL == list || NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_list = (ctsvc_list_s *)list;
+       s_record = (ctsvc_record_s *)record;
+
+       if (s_list->l_type != s_record->r_type)
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+
+       for (cursor=s_list->records;cursor;cursor=cursor->next) {
+               ctsvc_record_s *data = (ctsvc_record_s *)cursor->data;
+               if (data == s_record) {
+                       s_list->count--;
+                       if (s_list->cursor == cursor)
+                               s_list->cursor = cursor->next;
+
+                       s_list->records = g_list_remove(s_list->records, s_record);
+                       if (insert_delete_list) {
+                               err = contacts_record_clone(record, &delete_record);
+                               RETVM_IF(CONTACTS_ERROR_NONE != err, err,"contacts_record_clone() Failed(%d)", err);
+                               s_list->deleted_records = g_list_append(s_list->deleted_records, delete_record);
+                       }
+                       return CONTACTS_ERROR_NONE;
+               }
+       }
+
+       return CONTACTS_ERROR_NO_DATA;
+}
+
+API int contacts_list_remove( contacts_list_h list, contacts_record_h record )
+{
+       GList *cursor = NULL;
+       ctsvc_list_s *s_list;
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == list || NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_list = (ctsvc_list_s *)list;
+       s_record = (ctsvc_record_s *)record;
+
+       if (s_list->l_type != s_record->r_type)
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+
+       for (cursor=s_list->records;cursor;cursor=cursor->next) {
+               ctsvc_record_s *data = (ctsvc_record_s *)cursor->data;
+               if (data == s_record){
+                       s_list->count--;
+                       if (s_list->cursor == cursor)
+                               s_list->cursor = cursor->next;
+                       s_list->records = g_list_remove(s_list->records, s_record);
+                       return CONTACTS_ERROR_NONE;
+               }
+       }
+
+       return CONTACTS_ERROR_NO_DATA;
+}
+
+API int contacts_list_get_current_record_p( contacts_list_h list, contacts_record_h* record )
+{
+       ctsvc_list_s *list_s;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *record = NULL;
+
+       RETV_IF(NULL == list || NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       list_s = (ctsvc_list_s *)list;
+
+       if (NULL == list_s->cursor) {
+               *record = NULL;
+               return CONTACTS_ERROR_NO_DATA;
+       }
+
+       *record = list_s->cursor->data;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_list_get_nth_record_p( contacts_list_h list, int index, contacts_record_h* record )
+{
+       GList *cursor = NULL;
+       ctsvc_list_s *list_s;
+       int i, j;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *record = NULL;
+
+       RETV_IF(NULL == list || NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       list_s = (ctsvc_list_s *)list;
+
+       for (i=0,j=0,cursor=list_s->records;cursor;cursor=cursor->next, i++) {
+               if (j == index) {
+                       *record = (contacts_record_h)cursor->data;
+                       return CONTACTS_ERROR_NONE;
+               }
+               j++;
+       }
+       *record = NULL;
+       return CONTACTS_ERROR_NO_DATA;
+}
+
+static int __ctsvc_list_move_cursor( contacts_list_h list, bool next )
+{
+       ctsvc_list_s *list_s;
+
+       RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
+       list_s = (ctsvc_list_s *)list;
+
+       if (NULL == list_s->cursor)
+               return CONTACTS_ERROR_NO_DATA;
+
+       list_s->cursor = next ? list_s->cursor->next : list_s->cursor->prev ;
+
+       if (NULL == list_s->cursor)
+               return CONTACTS_ERROR_NO_DATA;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_list_prev( contacts_list_h list )
+{
+       return __ctsvc_list_move_cursor(list, false);
+}
+
+API int contacts_list_next( contacts_list_h list )
+{
+       return __ctsvc_list_move_cursor(list, true);
+}
+
+
+
+API int contacts_list_first( contacts_list_h list )
+{
+       ctsvc_list_s *list_s;
+
+       RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
+       list_s = (ctsvc_list_s *)list;
+
+       list_s->cursor = list_s->records;
+       if (NULL == list_s->cursor)
+               return CONTACTS_ERROR_NO_DATA;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_list_last( contacts_list_h list )
+{
+       ctsvc_list_s *list_s;
+
+       RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
+       list_s = (ctsvc_list_s *)list;
+
+       list_s->cursor = g_list_last(list_s->records);
+       if (NULL == list_s->cursor)
+               return CONTACTS_ERROR_NO_DATA;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_list_destroy( contacts_list_h list, bool delete_child )
+{
+       ctsvc_list_s *s_list;
+       GList *cursor = NULL;
+
+       RETVM_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : The list is null");
+       s_list = (ctsvc_list_s *)list;
+
+       if (delete_child) {
+               for(cursor = s_list->records;cursor;cursor=cursor->next)
+                       contacts_record_destroy((contacts_record_h)(cursor->data), true);
+       }
+       g_list_free(s_list->records);
+
+       for(cursor = s_list->deleted_records;cursor;cursor=cursor->next)
+               contacts_record_destroy((contacts_record_h)(cursor->data), true);
+       g_list_free(s_list->deleted_records);
+
+       free(s_list);
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_list_clone(contacts_list_h list, contacts_list_h* out_list)
+{
+       ctsvc_list_s *list_s;
+       contacts_record_h new_record;
+       contacts_list_h new_list;
+       GList *cursor = NULL;
+       contacts_error_e err = CONTACTS_ERROR_NONE;
+
+       RETVM_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "The list is null");
+       list_s = (ctsvc_list_s *)list;
+
+       contacts_list_create(&new_list);
+       for(cursor = list_s->records;cursor;cursor=cursor->next) {
+               err = contacts_record_clone((contacts_record_h)cursor->data, &new_record);
+               if (CONTACTS_ERROR_NONE != err) {
+                       CTS_ERR("contacts_record_clone() Failed(%d)", err);
+                       contacts_list_destroy(new_list, true);
+                       return err;
+               }
+               ctsvc_list_prepend(new_list, new_record);
+       }
+       ctsvc_list_reverse(new_list);
+
+       for(cursor = list_s->deleted_records;cursor;cursor=cursor->next) {
+               err = contacts_record_clone((contacts_record_h)cursor->data, &new_record);
+               if (CONTACTS_ERROR_NONE != err) {
+                       CTS_ERR("contacts_record_clone() Failed(%d)", err);
+                       contacts_list_destroy(new_list, true);
+                       return err;
+               }
+               ((ctsvc_list_s*)new_list)->deleted_records = g_list_prepend(((ctsvc_list_s*)new_list)->deleted_records, new_record);
+       }
+       if (((ctsvc_list_s*)new_list)->deleted_records)
+               ((ctsvc_list_s*)new_list)->deleted_records = g_list_reverse(((ctsvc_list_s*)new_list)->deleted_records);
+
+       *out_list = new_list;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+
+int ctsvc_list_get_deleted_count(contacts_list_h list, unsigned int *count )
+{
+       ctsvc_list_s *list_s;
+
+       RETV_IF(NULL == count, CONTACTS_ERROR_INVALID_PARAMETER);
+       *count = 0;
+
+       RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
+       list_s = (ctsvc_list_s *)list;
+
+       if( NULL == list_s->deleted_records )
+       {
+               return CONTACTS_ERROR_NONE;
+       }
+
+       *count = g_list_length(list_s->deleted_records);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_list_get_deleted_nth_record_p( contacts_list_h list, int index, contacts_record_h* record )
+{
+       ctsvc_list_s *list_s;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *record = NULL;
+
+       RETV_IF(NULL == list || NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       list_s = (ctsvc_list_s *)list;
+
+       RETV_IF(NULL == list_s->deleted_records, CONTACTS_ERROR_NO_DATA);
+
+       *record = (contacts_record_h)g_list_nth_data(list_s->deleted_records, index);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_list_append_deleted_record(contacts_list_h list, contacts_record_h record)
+{
+       ctsvc_list_s *list_s;
+
+       RETV_IF(NULL == list || NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       list_s = (ctsvc_list_s *)list;
+
+       list_s->deleted_records = g_list_append(list_s->deleted_records, record);
+
+       return CONTACTS_ERROR_NONE;
+}
diff --git a/common/ctsvc_list.h b/common/ctsvc_list.h
new file mode 100644 (file)
index 0000000..b13f6bf
--- /dev/null
@@ -0,0 +1,40 @@
+/*\r
+ * Contacts Service\r
+ *\r
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: Dohyung Jin <dh.jin@samsung.com>\r
+ *                 Jongwon Lee <gogosing.lee@samsung.com>\r
+ *                 Donghee Ye <donghee.ye@samsung.com>\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
+\r
+#ifndef __TIZEN_SOCIAL_CTSVC_LIST_H__\r
+#define __TIZEN_SOCIAL_CTSVC_LIST_H__\r
+\r
+#include "contacts_views.h"\r
+\r
+int ctsvc_list_clone(contacts_list_h list, contacts_list_h* out_list);\r
+int ctsvc_list_get_nth_record_p( contacts_list_h list, int index, contacts_record_h* record );\r
+int ctsvc_list_add_child( contacts_list_h list, contacts_record_h child_record );\r
+int ctsvc_list_prepend( contacts_list_h list, contacts_record_h child_record );\r
+int ctsvc_list_reverse( contacts_list_h list);\r
+int ctsvc_list_remove_child( contacts_list_h list, contacts_record_h record, bool insert_delete_list );\r
+\r
+int ctsvc_list_get_deleted_count(contacts_list_h list, unsigned int *count );\r
+int ctsvc_list_get_deleted_nth_record_p( contacts_list_h list, int index, contacts_record_h* record );\r
+int ctsvc_list_append_deleted_record(contacts_list_h list, contacts_record_h record);\r
+\r
+#endif /*  __TIZEN_SOCIAL_CTSVC_LIST_H__ */\r
diff --git a/common/ctsvc_localize_utils.c b/common/ctsvc_localize_utils.c
new file mode 100755 (executable)
index 0000000..41dd830
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <unicode/ustring.h>
+#include <unicode/unorm.h>
+#include <unicode/ucol.h>
+#include <unicode/uset.h>
+
+#include "ctsvc_internal.h"
+#include "ctsvc_localize_utils.h"
+
+int ctsvc_check_utf8(char c)
+{
+       if ((c & 0xff) < (128 & 0xff))
+               return 1;
+       else if ((c & (char)0xe0) == (char)0xc0)
+               return 2;
+       else if ((c & (char)0xf0) == (char)0xe0)
+               return 3;
+       else if ((c & (char)0xf8) == (char)0xf0)
+               return 4;
+       else if ((c & (char)0xfc) == (char)0xf8)
+               return 5;
+       else if ((c & (char)0xfe) == (char)0xfc)
+               return 6;
+       else
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+/**
+ * check language type with first word(UChar) using UBLOCK
+ */
+int ctsvc_check_language(UChar *word)
+{
+       int type;
+
+       if (u_isdigit(word[0])) {
+               type = CTSVC_LANG_NUMBER;
+       }
+       else if (u_isalpha(word[0])) {
+               // refer to the uchar.h
+               // #define U_GC_L_MASK  (U_GC_LU_MASK|U_GC_LL_MASK|U_GC_LT_MASK|U_GC_LM_MASK|U_GC_LO_MASK)
+               // U_GC_LU_MASK : U_UPPERCASE_LETTER
+               // U_GC_LL_MASK : U_LOWERCASE_LETTER
+               // U_GC_LT_MASK : U_TITLECASE_LETTER
+               // U_GC_LM_MASK : U_MODIFIER_LETTER
+               // U_GC_LO_MASK : U_OTHER_LETTER
+
+               UBlockCode code = ublock_getCode(word[0]);
+               CTS_VERBOSE("Character unicode block is %d", code);
+
+               switch (code){
+               //english
+               case UBLOCK_BASIC_LATIN:                                                        // = 1, /*[0000]*/
+               case UBLOCK_LATIN_1_SUPPLEMENT:                                 // =2, /*[0080]*/
+               case UBLOCK_LATIN_EXTENDED_A:                                           // =3, /*[0100]*/
+               case UBLOCK_LATIN_EXTENDED_B:                                           // =4, /*[0180]*/
+               case UBLOCK_LATIN_EXTENDED_ADDITIONAL:                  // =38, /*[1E00]*/
+                       type = CTSVC_LANG_ENGLISH;
+                       // type = CTSVC_LANG_CATALAN;   // ca, Spain - Catalan
+                       // type = CTSVC_LANG_GERMAN:     // de, Germany - German
+                       // type = CTSVC_LANG_BASQUE:    // eu, Spain - Basque
+                       // type = CTSVC_LANG_DUTCH;             // nl_Nl, Netherlands Dutch
+                       // type = CTSVC_LANG_FRENCH;    // fr_CA, fr_FR
+                       // type = CTSVC_LANG_ITALIAN:   // it_IT, Italy - Italian
+                       // type = CTSVC_LANG_PORTUGUESE:         // pt_BR, pt_PT, Portugal
+                       // type = CTSVC_LANG_SPANISH: // es_ES, es_US, El Salvador - Spanish
+                       // type =  CTSVC_LANG_NORWAY: // nb, Norway
+                       // type = CTSVC_LANG_DANISH: // da, Denmark - Danish
+                       // type = CTSVC_LANG_AZERBAIJAN: // az, Azerbaijan
+                       // type = CTSVC_LANG_ROMANIA: // ro, Romania
+                       // type = CTSVC_LANG_CZECH: // cs, Czech Republic - Czech
+                       // type = CTSVC_LANG_ESTONIAN: // et, Estonia - Estonian
+                       // type = CTSVC_LANG_FINNISH: // fi, Finland - Finnish
+                       // type = CTSVC_LANG_IRISH: // ga, Ireland - Irish
+                       // type = CTSVC_LANG_GALICIAN: // gl, Spain - Galician
+                       // type = CTSVC_LANG_HUNGARIAN: // hu, Hungary - Hungarian
+                       // type = CTSVC_LANG_SWEDISH: // sv, Finland - Swedish
+                       // type = CTSVC_LANG_SLOVENIAN: // sl, Slovenia - Slovenian
+                       // type = CTSVC_LANG_SLOVAK: // sk, Slovakia - Slovak
+                       // type = CTSVC_LANG_LITHUANIAN: // lt, Lithuania - Lithuanian
+                       // type = CTSVC_LANG_POLISH: // pl, Polish
+                       // type = CTSVC_LANG_LATVIAN: // lv, Latvia - Latvian
+                       // type = CTSVC_LANG_CROATIAN: // hr, Bosnia and Herzegovina - Croatian
+                       // type = CTSVC_LANG_ICELANDIC: // is, Iceland - Icelandic
+                       break;
+
+               //korean
+               case UBLOCK_HANGUL_JAMO:                                                // =30, /*[1100]*/
+               case UBLOCK_HANGUL_COMPATIBILITY_JAMO:          // =65, /*[3130]*/
+               case UBLOCK_HANGUL_SYLLABLES:                           // =74, /*[AC00]*/
+               case UBLOCK_HANGUL_JAMO_EXTENDED_A:             // = 180, /*[A960]*/
+               case UBLOCK_HANGUL_JAMO_EXTENDED_B:             // = 185, /*[D7B0]*/
+                       type = CTSVC_LANG_KOREAN;
+                       break;
+
+               // chainese
+               case UBLOCK_CJK_RADICALS_SUPPLEMENT:                     //=58, /*[2E80]*/
+               case UBLOCK_CJK_SYMBOLS_AND_PUNCTUATION:                 //=61, /*[3000]*/
+               case UBLOCK_ENCLOSED_CJK_LETTERS_AND_MONTHS:  //=68, /*[3200]*/
+               case UBLOCK_CJK_STROKES:                                                         // =130, /*[31C0]*/
+               case UBLOCK_CJK_COMPATIBILITY:                                           // =69, /*[3300]*/
+               case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A: //=70, /*[3400]*/
+               case UBLOCK_CJK_UNIFIED_IDEOGRAPHS:                              //=71, /*[4E00]*/
+               case UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS:                //=79, /*[F900]*/
+               case UBLOCK_CJK_COMPATIBILITY_FORMS:                             //=83, /*[FE30]*/
+               case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B :       // =94, /*[20000]*/
+               case UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT:         // =95, /*[2F800]*/
+               case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C:         // =197, /*[2A700]*/
+               case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D:         // =209, /*[2B740]*/
+                       type = CTSVC_LANG_CHINESE;
+                       break;
+
+               // japanese
+               case UBLOCK_HIRAGANA:                                                           // =62, /*[3040]*/
+               case UBLOCK_KATAKANA:                                                           // =63, /*[30A0]*/
+               case UBLOCK_KATAKANA_PHONETIC_EXTENSIONS:               // =107, /*[31F0]*/
+               case UBLOCK_JAVANESE:                                                           // =181, /*[A980]*/
+                       type = CTSVC_LANG_JAPANESE;
+                       break;
+
+               case UBLOCK_GREEK:                                              // =8, /*[0370]*/
+               case UBLOCK_GREEK_EXTENDED:                             // =39, /*[1F00]*/
+                       type = CTSVC_LANG_GREEK;
+                       break;
+
+               case UBLOCK_CYRILLIC:                                                           // =9, /*[0400]*/
+               case UBLOCK_CYRILLIC_EXTENDED_A:                                        // = 158, /*[2DE0]*/
+               case UBLOCK_CYRILLIC_EXTENDED_B:                                        // = 160, /*[A640]*/
+               case UBLOCK_CYRILLIC_SUPPLEMENTARY:                             // = 97, UBLOCK_CYRILLIC_SUPPLEMENT = UBLOCK_CYRILLIC_SUPPLEMENTARY, /*[0500]*/
+                       type = CTSVC_LANG_RUSSIAN;
+                       // type = CTSVC_LANG_BULGARIAN: // bg, Bulgaria - Bulgarian
+                       // type = CTSVC_LANG_MACEDONIA: // mk, Macedonia
+                       // type = CTSVC_LANG_KAZAKHSTAN: // kk, Kazakhstan
+                       // type = CTSVC_LANG_SERBIAN: // sr, Serbia - Serbian
+                       // type = CTSVC_LANG_UKRAINE: // uk, Ukraine
+                       break;
+
+               case UBLOCK_ARMENIAN:                                           //=10, /*[0530]*/
+                       type = CTSVC_LANG_ARMENIAN;
+                       break;
+               case UBLOCK_ARABIC:                                             //=12, /*[0600]*/
+                       type = CTSVC_LANG_ARABIC;
+                       break;
+               case UBLOCK_DEVANAGARI:                                 // =15, /*[0900]*/
+               case UBLOCK_DEVANAGARI_EXTENDED:                // = 179, /*[A8E0]*/:
+                       type = CTSVC_LANG_HINDI;
+                       break;
+               case UBLOCK_GEORGIAN:                                           //=29, /*[10A0]*/
+               case UBLOCK_GEORGIAN_SUPPLEMENT:                // = 135, /*[2D00]*/
+                       type = CTSVC_LANG_GEORGIAN;
+                       break;
+               case UBLOCK_OLD_TURKIC:                                 // = 191, /*[10C00]*/
+                       type = CTSVC_LANG_TURKISH;
+                       break;
+               case UBLOCK_HALFWIDTH_AND_FULLWIDTH_FORMS:              // =87, /*[FF00]*/      // hangul : FFA0 ~ FFDC
+               {
+                       if (CTSVC_COMPARE_BETWEEN((UChar)0xFF21, word[0], (UChar)0xFF3A)
+                               || CTSVC_COMPARE_BETWEEN((UChar)0xFF41, word[0], (UChar)0xFF5A))
+                               type = CTSVC_LANG_ENGLISH;
+                       else if (CTSVC_COMPARE_BETWEEN((UChar)0xFF10, word[0], (UChar)0xFF19))
+                               type = CTSVC_LANG_NUMBER;
+                       else if (CTSVC_COMPARE_BETWEEN((UChar)0xFF65, word[0], (UChar)0xFF9F))
+                               type = CTSVC_LANG_JAPANESE;
+                       else if (CTSVC_COMPARE_BETWEEN((UChar)0xFFA0, word[0], (UChar)0xFFDC))
+                               type = CTSVC_LANG_KOREAN;
+                       else
+                               type = CTSVC_LANG_OTHERS;
+                       break;
+               }
+               default:
+                       type = CTSVC_LANG_OTHERS;
+                       break;
+               }
+       }
+       else
+               type = CTSVC_LANG_OTHERS;
+
+       CTS_VERBOSE("language type = %d", type);
+       return type;
+}
+
+// check language type by first word(char*) using UBLOCK
+int ctsvc_check_language_type(const char *src)
+{
+       int length = 0;
+       char temp[10] = {0};
+       UChar tmp_result[2];
+       UChar result[10];
+       UErrorCode status = 0;
+
+       if (src && src[0]) {
+               length = ctsvc_check_utf8(src[0]);
+               RETVM_IF(length <= 0, CONTACTS_ERROR_INTERNAL, "check_utf8 failed");
+
+               strncpy(temp, src, length);
+
+               CTS_VERBOSE("temp(%s) src(%s) length(%d)", temp, src, length);
+
+               u_strFromUTF8(tmp_result, array_sizeof(tmp_result), NULL, temp, -1, &status);
+                       RETVM_IF(U_FAILURE(status), CONTACTS_ERROR_SYSTEM,
+                                       "u_strFromUTF8() Failed(%s)", u_errorName(status));
+
+               u_strToUpper(tmp_result, array_sizeof(tmp_result), tmp_result, -1, NULL, &status);
+               RETVM_IF(U_FAILURE(status), CONTACTS_ERROR_SYSTEM,
+                               "u_strToLower() Failed(%s)", u_errorName(status));
+
+               unorm_normalize(tmp_result, -1, UNORM_NFD, 0,
+                               (UChar *)result, array_sizeof(result), &status);
+               RETVM_IF(U_FAILURE(status), CONTACTS_ERROR_SYSTEM,
+                               "unorm_normalize(%s) Failed(%s)", src, u_errorName(status));
+
+               CTS_VERBOSE("0x%x%x", (0xFF00 & (tmp_result[0])) >> 8,  (0xFF & (tmp_result[0])));
+
+               return ctsvc_check_language(result);
+       }
+
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
diff --git a/common/ctsvc_localize_utils.h b/common/ctsvc_localize_utils.h
new file mode 100755 (executable)
index 0000000..349aa59
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CTSVC_LOCALIZE_UTILS_H__
+#define __TIZEN_SOCIAL_CTSVC_LOCALIZE_UTILS_H__
+
+#include <unicode/utypes.h>
+
+enum LANGTYPE{
+       CTSVC_LANG_NUMBER = 0,
+       CTSVC_LANG_DEFAULT = 1,
+       CTSVC_LANG_SECONDARY = 2,
+       CTSVC_LANG_ENGLISH = 3,
+       CTSVC_LANG_KOREAN = 4, /* always last-first */
+       CTSVC_LANG_CHINESE = 5,
+       CTSVC_LANG_JAPANESE = 6,
+       CTSVC_LANG_FRENCH = 7,
+       CTSVC_LANG_GERMAN = 8,
+       CTSVC_LANG_ITALIAN = 9,
+       CTSVC_LANG_RUSSIAN = 10,
+       CTSVC_LANG_DUTCH = 11,
+       CTSVC_LANG_PORTUGUESE = 12,
+       CTSVC_LANG_TURKISH = 13,
+       CTSVC_LANG_GREEK = 14,
+       CTSVC_LANG_SPANISH = 15,
+       CTSVC_LANG_DANISH = 16,
+       CTSVC_LANG_AZERBAIJAN = 17,
+       CTSVC_LANG_ARABIC = 18,
+       CTSVC_LANG_BULGARIAN = 19,
+       CTSVC_LANG_CATALAN = 20,
+       CTSVC_LANG_CZECH = 21,
+       CTSVC_LANG_ESTONIAN = 22,
+       CTSVC_LANG_BASQUE = 23,
+       CTSVC_LANG_FINNISH = 24,
+       CTSVC_LANG_IRISH = 25,
+       CTSVC_LANG_GALICIAN = 26,
+       CTSVC_LANG_HINDI = 27,
+       CTSVC_LANG_CROATIAN = 28,
+       CTSVC_LANG_HUNGARIAN= 29,
+       CTSVC_LANG_ARMENIAN = 30,
+       CTSVC_LANG_ICELANDIC = 31,
+       CTSVC_LANG_GEORGIAN = 32,
+       CTSVC_LANG_KAZAKHSTAN = 33,
+       CTSVC_LANG_LITHUANIAN = 34,
+       CTSVC_LANG_LATVIAN = 35,
+       CTSVC_LANG_MACEDONIA = 36,
+       CTSVC_LANG_NORWAY= 37,
+       CTSVC_LANG_POLISH = 38,
+       CTSVC_LANG_ROMANIA = 39,
+       CTSVC_LANG_SLOVAK = 40,
+       CTSVC_LANG_SLOVENIAN = 41,
+       CTSVC_LANG_SERBIAN = 42,
+       CTSVC_LANG_SWEDISH = 43,
+       CTSVC_LANG_UKRAINE = 44,
+       CTSVC_LANG_THAI = 45,
+       CTSVC_LANG_BENGALI = 46,
+       CTSVC_LANG_PUNJABI = 47,
+       CTSVC_LANG_MALAYALAM = 48,
+       CTSVC_LANG_TELUGU = 49,
+       CTSVC_LANG_TAMIL = 50,
+       CTSVC_LANG_ORIYA = 51,
+       CTSVC_LANG_SINHALA = 52,
+       CTSVC_LANG_GUJARATI = 53,
+       CTSVC_LANG_KANNADA = 54,
+       CTSVC_LANG_LAO = 55,
+       CTSVC_LANG_HEBREW = 56,
+       CTSVC_LANG_VIETNAMESE = 57,
+       CTSVC_LANG_PERSIAN = 58,
+       CTSVC_LANG_UZBEK = 59,
+       CTSVC_LANG_URDU = 60,
+       CTSVC_LANG_ALBANIAN = 61,
+       CTSVC_LANG_BURMESE = 62,
+       CTSVC_LANG_MALAY = 63,
+       CTSVC_LANG_KHMER = 64,
+       CTSVC_LANG_INDONESIAN = 65,
+       CTSVC_LANG_TAGALOG = 66,
+       CTSVC_LANG_OTHERS = 1000,
+};
+
+#define array_sizeof(a) (sizeof(a) / sizeof(a[0]))
+
+#define CTSVC_COMPARE_BETWEEN(left_range, value, right_range) (((left_range) <= (value)) && ((value) <= (right_range)))
+
+int ctsvc_check_utf8(char c);
+int ctsvc_check_language(UChar *word);
+int ctsvc_check_language_type(const char *src);
+
+#endif // __TIZEN_SOCIAL_CTSVC_LOCALIZE_UTILS_H__
diff --git a/common/ctsvc_mutex.c b/common/ctsvc_mutex.c
new file mode 100755 (executable)
index 0000000..4a86362
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * 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 <pthread.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_mutex.h"
+
+typedef struct {
+       int (* lock) (pthread_mutex_t *mutex);
+       int (* unlock) (pthread_mutex_t *mutex);
+}cts_mutex_fns;
+
+static cts_mutex_fns __ctsvc_mutex_funtions =
+{
+       pthread_mutex_lock,
+       pthread_mutex_unlock
+};
+
+static pthread_mutex_t conn_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t sockfd_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t trans_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t ipc_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t ipc_pubsub_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t access_control_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static int __old_type = 0;
+static int __defered_ref = 0;
+
+static inline pthread_mutex_t* __ctsvc_mutex_get_mutex(int type)
+{
+       pthread_mutex_t *ret_val;
+
+       switch (type) {
+       case CTS_MUTEX_CONNECTION:
+               ret_val = &conn_mutex;
+               break;
+       case CTS_MUTEX_SOCKET_FD:
+               ret_val = &sockfd_mutex;
+               break;
+       case CTS_MUTEX_TRANSACTION:
+               ret_val = &trans_mutex;
+               break;
+       case CTS_MUTEX_PIMS_IPC_CALL:
+               ret_val = &ipc_mutex;
+               break;
+       case CTS_MUTEX_PIMS_IPC_PUBSUB:
+               ret_val = &ipc_pubsub_mutex;
+               break;
+       case CTS_MUTEX_ACCESS_CONTROL:
+               ret_val = &access_control_mutex;
+               break;
+       default:
+               CTS_ERR("unknown type(%d)", type);
+               ret_val = NULL;
+               break;
+       }
+       return ret_val;
+}
+
+void ctsvc_mutex_lock(int type)
+{
+       int ret;
+       pthread_mutex_t *mutex;
+
+       // If user use pthread_cancel, lock can be occured
+       // protect it, call pthread_set_canceltype as PTHREAD_CANCEL_DEFERRED
+       // But, if another module call PTHREAD_CANCEL_ASYNCHRONOUS,
+       // it can be occured again
+       // So, Do not use the pthread_cancel with contacts_service API
+       if (__defered_ref == 0)
+               pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &__old_type);
+       else
+               pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
+
+       __defered_ref++;
+
+       mutex = __ctsvc_mutex_get_mutex(type);
+
+       if (__ctsvc_mutex_funtions.lock) {
+               ret = __ctsvc_mutex_funtions.lock(mutex);
+               WARN_IF(ret, "mutex_lock Failed(%d)", ret);
+       }
+}
+
+void ctsvc_mutex_unlock(int type)
+{
+       int ret;
+       pthread_mutex_t *mutex;
+
+       mutex = __ctsvc_mutex_get_mutex(type);
+
+       if (__ctsvc_mutex_funtions.unlock) {
+               ret = __ctsvc_mutex_funtions.unlock(mutex);
+               WARN_IF(ret, "mutex_unlock Failed(%d)", ret);
+       }
+
+       __defered_ref--;
+       if (__defered_ref == 0) {
+               pthread_setcanceltype(__old_type, NULL);
+       }
+}
+
similarity index 78%
rename from src/cts-pthread.h
rename to common/ctsvc_mutex.h
index f7eb0e5..011785b 100755 (executable)
  * limitations under the License.
  *
  */
-#ifndef __CTS_PTHREAD_H__
-#define __CTS_PTHREAD_H__
+#ifndef __CTSVC_MUTEX_H__
+#define __CTSVC_MUTEX_H__
 
 enum {
        CTS_MUTEX_CONNECTION,
        CTS_MUTEX_UPDTATED_LIST_MEMPOOL,
        CTS_MUTEX_SOCKET_FD,
        CTS_MUTEX_TRANSACTION,
+       CTS_MUTEX_PIMS_IPC_CALL,
+       CTS_MUTEX_PIMS_IPC_PUBSUB,
+       CTS_MUTEX_ACCESS_CONTROL,
 };
 
-void cts_mutex_lock(int type);
-void cts_mutex_unlock(int type);
+void ctsvc_mutex_lock(int type);
+void ctsvc_mutex_unlock(int type);
 
 
-#endif //__CTS_PTHREAD_H__
-
+#endif //__CTSVC_MUTEX_H__
diff --git a/common/ctsvc_notify.h b/common/ctsvc_notify.h
new file mode 100644 (file)
index 0000000..e016185
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CTSVC_NOTIFY_H__
+#define __TIZEN_SOCIAL_CTSVC_NOTIFY_H__
+
+#define CTSVC_NOTI_IPC_READY   "/opt/usr/data/contacts-svc/.CONTACTS_SVC_IPC_READY"
+#define CTSVC_NOTI_ADDRESSBOOK_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_AB_CHANGED"
+#define CTSVC_NOTI_GROUP_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_GROUP_CHANGED"
+#define CTSVC_NOTI_PERSON_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_PERSON_CHANGED"
+#define CTSVC_NOTI_CONTACT_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_DB_CHANGED"
+#define CTSVC_NOTI_MY_PROFILE_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_MY_PROFILE_CHANGED"
+#define CTSVC_NOTI_NAME_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_NAME_CHANGED"
+#define CTSVC_NOTI_NUMBER_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_NUMBER_CHANGED"
+#define CTSVC_NOTI_EMAIL_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_EMAIL_CHANGED"
+#define CTSVC_NOTI_EVENT_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_EVENT_CHANGED"
+#define CTSVC_NOTI_URL_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_URL_CHANGED"
+#define CTSVC_NOTI_GROUP_RELATION_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_GROUP_RELATION_CHANGED"
+#define CTSVC_NOTI_ADDRESS_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_ADDRESS_CHANGED"
+#define CTSVC_NOTI_NOTE_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_NOTE_CHANGED"
+#define CTSVC_NOTI_COMPANY_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_COMPANY_CHANGED"
+#define CTSVC_NOTI_RELATIONSHIP_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_RELATIONSHIP_CHANGED"
+#define CTSVC_NOTI_IMAGE_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_IMAGE_CHANGED"
+#define CTSVC_NOTI_NICKNAME_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_NICKNAME_CHANGED"
+#define CTSVC_NOTI_MESSENGER_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_MESSENGER_CHANGED"
+#define CTSVC_NOTI_DATA_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_DATA_CHANGED"
+#define CTSVC_NOTI_SDN_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_SDN_CHANGED"
+#define CTSVC_NOTI_PROFILE_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_PROFILE_CHANGED"
+#define CTSVC_NOTI_ACTIVITY_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_ACTIVITY_CHANGED"
+#define CTSVC_NOTI_ACTIVITY_PHOTO_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_ACTIVITY_PHOTO_CHANGED"
+#define CTSVC_NOTI_PHONELOG_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_PLOG_CHANGED"
+#define CTSVC_NOTI_SPEEDDIAL_CHANGED  "/opt/usr/data/contacts-svc/.CONTACTS_SVC_SPEED_CHANGED"
+
+#define CTSVC_SETTING_DISPLAY_ORDER_CHANGED "contacts.setting.display_order"
+#define CTSVC_SETTING_SORTING_ORDER_CHANGED "contacts.setting.sorting_order"
+
+#endif /* __TIZEN_SOCIAL_CTSVC_NOTIFY_H__ */
diff --git a/common/ctsvc_query.c b/common/ctsvc_query.c
new file mode 100644 (file)
index 0000000..dc6e894
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_query.h"
+#include "ctsvc_filter.h"
+
+typedef enum {
+       QUERY_SORTKEY,
+       QUERY_PROJECTION,
+}query_property_type_e;
+
+static bool __ctsvc_query_property_check(const property_info_s *properties,
+               int count, query_property_type_e property_type, unsigned int property_id)
+{
+       int i;
+
+       for (i=0;i<count;i++) {
+               property_info_s *p = (property_info_s*)&(properties[i]);
+               if (property_id == p->property_id) {
+                       if (property_type == QUERY_PROJECTION) {
+                               if (p->property_type == CTSVC_SEARCH_PROPERTY_ALL || p->property_type == CTSVC_SEARCH_PROPERTY_PROJECTION)
+                                       return true;
+                               else
+                                       return false;
+                       }
+                       else
+                               return true;
+               }
+       }
+       return false;
+}
+
+API int contacts_query_create( const char* view_uri, contacts_query_h* out_query )
+{
+       ctsvc_query_s *query;
+
+       RETV_IF(NULL == out_query, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_query = NULL;
+
+       RETV_IF(NULL == view_uri || NULL == out_query, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       query = (ctsvc_query_s *)calloc(1, sizeof(ctsvc_query_s));
+       RETV_IF(NULL == query, CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       query->view_uri = strdup(view_uri);
+       query->properties = (property_info_s *)ctsvc_view_get_all_property_infos(view_uri, &query->property_count);
+       *out_query = (contacts_query_h)query;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_query_set_projection(contacts_query_h query, unsigned int property_ids[], int count)
+{
+       ctsvc_query_s *query_s;
+       int i;
+       bool find;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       query_s = (ctsvc_query_s *)query;
+
+       for (i=0;i<count;i++) {
+               find = __ctsvc_query_property_check(query_s->properties, query_s->property_count, QUERY_PROJECTION, property_ids[i]);
+               RETVM_IF(false == find, CONTACTS_ERROR_INVALID_PARAMETER,
+                                       "Invalid parameter : property_id(%d) is not supported on view_uri(%s)", property_ids[i], query_s->view_uri);
+       }
+       if (query_s->projection)
+               free(query_s->projection);
+
+       query_s->projection = calloc(count, sizeof(unsigned int));
+       RETVM_IF(NULL == query_s->projection, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+       memcpy(query_s->projection, property_ids, sizeof(unsigned int) * count);
+       query_s->projection_count = count;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_query_set_filter(contacts_query_h query, contacts_filter_h filter)
+{
+       int ret;
+       ctsvc_query_s *s_query;
+       contacts_filter_h new_filter;
+
+       RETV_IF(NULL == query || NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_filter_clone(filter, &new_filter);
+       RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "ctsvc_filter_clone Fail(%d)", ret);
+       s_query->filter = (ctsvc_composite_filter_s*)new_filter;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_query_set_sort(contacts_query_h query, unsigned int property_id, bool asc)
+{
+       ctsvc_query_s *query_s;
+       bool find = false;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       query_s = (ctsvc_query_s *)query;
+
+       find = __ctsvc_query_property_check(query_s->properties, query_s->property_count, QUERY_SORTKEY, property_id);
+       RETVM_IF(false == find, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is not supported on view_uri(%s)", property_id, query_s->view_uri);
+       query_s->sort_property_id = property_id;
+       query_s->sort_asc = asc;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_query_destroy( contacts_query_h query )
+{
+       ctsvc_query_s *s_query;
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       if (s_query->filter)
+               contacts_filter_destroy((contacts_filter_h)s_query->filter);
+
+       free(s_query->projection);
+       free(s_query->view_uri);
+       free(s_query);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_query_set_distinct(contacts_query_h query, bool set)
+{
+       ctsvc_query_s *query_s;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       query_s = (ctsvc_query_s *)query;
+       query_s->distinct = set;
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/common/ctsvc_query.h b/common/ctsvc_query.h
new file mode 100644 (file)
index 0000000..ead18e9
--- /dev/null
@@ -0,0 +1,29 @@
+/*\r
+ * Contacts Service\r
+ *\r
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: Dohyung Jin <dh.jin@samsung.com>\r
+ *                 Jongwon Lee <gogosing.lee@samsung.com>\r
+ *                 Donghee Ye <donghee.ye@samsung.com>\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
+\r
+#ifndef __TIZEN_SOCIAL_CTSVC_QUERY_H__\r
+#define __TIZEN_SOCIAL_CTSVC_QUERY_H__\r
+\r
+#endif /*  __TIZEN_SOCIAL_CTSVC_QUERY_H__ */\r
+\r
+\r
diff --git a/common/ctsvc_record.c b/common/ctsvc_record.c
new file mode 100755 (executable)
index 0000000..5b22b47
--- /dev/null
@@ -0,0 +1,632 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_record.h"
+#include "ctsvc_struct.h"
+#include "ctsvc_view.h"
+
+extern ctsvc_record_plugin_cb_s addressbook_plugin_cbs;
+extern ctsvc_record_plugin_cb_s group_plugin_cbs;
+extern ctsvc_record_plugin_cb_s person_plugin_cbs;
+extern ctsvc_record_plugin_cb_s contact_plugin_cbs;
+extern ctsvc_record_plugin_cb_s my_profile_plugin_cbs;
+extern ctsvc_record_plugin_cb_s simple_contact_plugin_cbs;
+extern ctsvc_record_plugin_cb_s updated_info_plugin_cbs;
+
+extern ctsvc_record_plugin_cb_s name_plugin_cbs;
+extern ctsvc_record_plugin_cb_s number_plugin_cbs;
+extern ctsvc_record_plugin_cb_s address_plugin_cbs;
+extern ctsvc_record_plugin_cb_s url_plugin_cbs;
+extern ctsvc_record_plugin_cb_s event_plugin_cbs;
+extern ctsvc_record_plugin_cb_s messenger_plugin_cbs;
+extern ctsvc_record_plugin_cb_s activity_plugin_cbs;
+extern ctsvc_record_plugin_cb_s activity_photo_plugin_cbs;
+extern ctsvc_record_plugin_cb_s relationship_plugin_cbs;
+extern ctsvc_record_plugin_cb_s image_plugin_cbs;
+extern ctsvc_record_plugin_cb_s group_relation_plugin_cbs;
+extern ctsvc_record_plugin_cb_s note_plugin_cbs;
+extern ctsvc_record_plugin_cb_s company_plugin_cbs;
+extern ctsvc_record_plugin_cb_s profile_plugin_cbs;
+extern ctsvc_record_plugin_cb_s nickname_plugin_cbs;
+extern ctsvc_record_plugin_cb_s email_plugin_cbs;
+extern ctsvc_record_plugin_cb_s result_plugin_cbs;
+#ifdef ENABLE_SIM_FEATURE
+extern ctsvc_record_plugin_cb_s sdn_plugin_cbs;
+extern ctsvc_record_plugin_cb_s speeddial_plugin_cbs;
+#endif // ENABLE_SIM_FEATURE
+extern ctsvc_record_plugin_cb_s extension_plugin_cbs;
+#ifdef ENABLE_LOG_FEATURE
+extern ctsvc_record_plugin_cb_s phonelog_plugin_cbs;
+#endif // ENABLE_LOG_FEATURE
+
+static const ctsvc_record_plugin_cb_s *__ctsvc_record_get_plugin_cb(int r_type)
+{
+       switch((int)r_type) {
+       case CTSVC_RECORD_ADDRESSBOOK:
+               return &addressbook_plugin_cbs;
+       case CTSVC_RECORD_GROUP:
+               return &group_plugin_cbs;
+       case CTSVC_RECORD_PERSON:
+               return &person_plugin_cbs;
+       case CTSVC_RECORD_CONTACT:
+               return &contact_plugin_cbs;
+       case CTSVC_RECORD_MY_PROFILE:
+               return &my_profile_plugin_cbs;
+       case CTSVC_RECORD_SIMPLE_CONTACT:
+               return &simple_contact_plugin_cbs;
+       case CTSVC_RECORD_NAME:
+               return &name_plugin_cbs;
+       case CTSVC_RECORD_COMPANY:
+               return &company_plugin_cbs;
+       case CTSVC_RECORD_NOTE:
+               return &note_plugin_cbs;
+       case CTSVC_RECORD_NUMBER:
+               return &number_plugin_cbs;
+       case CTSVC_RECORD_EMAIL:
+               return &email_plugin_cbs;
+       case CTSVC_RECORD_URL:
+               return &url_plugin_cbs;
+       case CTSVC_RECORD_EVENT:
+               return &event_plugin_cbs;
+       case CTSVC_RECORD_NICKNAME:
+               return &nickname_plugin_cbs;
+       case CTSVC_RECORD_ADDRESS:
+               return &address_plugin_cbs;
+       case CTSVC_RECORD_MESSENGER:
+               return &messenger_plugin_cbs;
+       case CTSVC_RECORD_GROUP_RELATION:
+               return &group_relation_plugin_cbs;
+       case CTSVC_RECORD_ACTIVITY:
+               return &activity_plugin_cbs;
+       case CTSVC_RECORD_ACTIVITY_PHOTO:
+               return &activity_photo_plugin_cbs;
+       case CTSVC_RECORD_PROFILE:
+               return &profile_plugin_cbs;
+       case CTSVC_RECORD_RELATIONSHIP:
+               return &relationship_plugin_cbs;
+       case CTSVC_RECORD_IMAGE:
+               return &image_plugin_cbs;
+       case CTSVC_RECORD_EXTENSION:
+               return &extension_plugin_cbs;
+#ifdef ENABLE_LOG_FEATURE
+       case CTSVC_RECORD_PHONELOG:
+               return &phonelog_plugin_cbs;
+#endif // ENABLE_LOG_FEATURE
+#ifdef ENABLE_SIM_FEATURE
+       case CTSVC_RECORD_SPEEDDIAL:
+               return &speeddial_plugin_cbs;
+       case CTSVC_RECORD_SDN:
+               return &sdn_plugin_cbs;
+#endif // ENABLE_SIM_FEATURE
+       case CTSVC_RECORD_UPDATED_INFO:
+               return &updated_info_plugin_cbs;
+       case CTSVC_RECORD_RESULT:
+               return &result_plugin_cbs;
+       default:
+               return NULL;
+       }
+}
+
+#define __INVALID_PARAMETER_ERROR_HANDLING() \
+               CTS_ERR("Invalid parameter: Operation restricted."); \
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+
+// This function is used for view_uri which is able to CRUD.
+// The view_uri's property should be sequencial value because it is used to find index at the below logic.
+bool ctsvc_record_check_property_flag(const ctsvc_record_s* s_record, unsigned int property_id, contacts_property_flag_e flag)
+{
+       int index = property_id & 0x000000FF;
+
+       if (CTSVC_RECORD_RESULT == s_record->r_type)
+               return true;
+
+       // Check it when getting value of property
+       // property_flag and properties_flags is set when getting record with query
+       if (CTSVC_PROPERTY_FLAG_PROJECTION == flag) {
+               // all property get.
+               if (NULL == s_record->properties_flags)
+                       return true;
+               // Or before inserting record from DB, just get after setting.
+               // properties_flags is not NULL when just setting dirty
+               if (0 == (CTSVC_PROPERTY_FLAG_PROJECTION & s_record->property_flag))
+                       return true;
+       }
+
+       // Check it when updating record
+       if (CTSVC_PROPERTY_FLAG_DIRTY == flag) {
+               // all property is clean
+               if (NULL == s_record->properties_flags)
+                       return false;
+       }
+       return ( s_record->properties_flags[index] & flag) ? true : false;
+}
+
+int ctsvc_record_set_property_flag(ctsvc_record_s* _record, int property_id, contacts_property_flag_e flag)
+{
+       int index = property_id & 0x000000FF;
+
+       if (CTSVC_RECORD_RESULT == _record->r_type)
+               return CONTACTS_ERROR_NONE;
+
+       if (NULL == _record->properties_flags) {
+               unsigned int count = 0;
+               ctsvc_view_get_all_property_infos(_record->view_uri, &count);
+               RETVM_IF(count <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "ctsvc_view_get_all_property_infos() Failed");
+
+               _record->properties_flags = calloc(count, sizeof(char));
+               _record->property_max_count = count;
+               RETVM_IF(NULL == _record->properties_flags, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc Failed");
+       }
+       _record->property_flag |= flag;
+       _record->properties_flags[index] |= flag;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+#define __CHECK_READ_ONLY_PROPERTY() \
+       if( CTSVC_READ_ONLY_CHECK(property_id, CTSVC_READ_ONLY_PROPERTY) ) \
+       { \
+               CTS_ERR("Invalid parameter: Don't try to change read-only property.(0x%0x)", property_id); \
+               return CONTACTS_ERROR_INVALID_PARAMETER; \
+       }
+
+#define __CHECK_PROJECTED_PROPERTY() \
+       if( false == ctsvc_record_check_property_flag( s_record, property_id, CTSVC_PROPERTY_FLAG_PROJECTION ) ) \
+       { \
+               CTS_ERR("Invalid parameter: Don't try to get un-projected property(0x%0x).", property_id); \
+               return CONTACTS_ERROR_INVALID_PARAMETER; \
+       }
+
+// Record constuct/destruct
+API int contacts_record_create( const char* view_uri, contacts_record_h* out_record )
+{
+       int ret;
+       ctsvc_record_type_e r_type;
+       const ctsvc_record_plugin_cb_s *plugin_cb;
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       r_type = ctsvc_view_get_record_type(view_uri);
+       RETVM_IF (CTSVC_RECORD_INVALID == r_type, CONTACTS_ERROR_INVALID_PARAMETER,
+                                       "Invalid parameter : view_uri(%s)", view_uri);
+
+       plugin_cb = __ctsvc_record_get_plugin_cb(r_type);
+       if (plugin_cb && plugin_cb->create) {
+               ret = plugin_cb->create(out_record);
+               if( CONTACTS_ERROR_NONE == ret ) {
+                       CTSVC_RECORD_INIT_BASE((ctsvc_record_s*)*out_record, r_type, plugin_cb, ctsvc_view_get_uri(view_uri));
+               }
+               return ret;
+       }
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int contacts_record_destroy( contacts_record_h record, bool delete_child )
+{
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_record = (ctsvc_record_s *)record;
+
+       if (s_record && s_record->plugin_cbs && s_record->plugin_cbs->destroy)
+               return s_record->plugin_cbs->destroy(record, delete_child);
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int contacts_record_clone( contacts_record_h record, contacts_record_h* out_record )
+{
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_record = (ctsvc_record_s *)record;
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->clone)
+               return s_record->plugin_cbs->clone(record, out_record);
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int contacts_record_get_uri_p( contacts_record_h record, const char** out_str )
+{
+    int ret = CONTACTS_ERROR_NONE;
+
+    ctsvc_record_s *temp = (ctsvc_record_s*)(record);
+
+    RETVM_IF(NULL == record || NULL == out_str, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    *out_str = (temp->view_uri);
+
+    return ret;
+}
+
+// Record get/set int,str, etc..
+API int contacts_record_get_str( contacts_record_h record, unsigned int property_id, char** out_str )
+{
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == out_str, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_str = NULL;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_record = (ctsvc_record_s *)record;
+
+       __CHECK_PROJECTED_PROPERTY();
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->get_str)
+               return s_record->plugin_cbs->get_str(record, property_id, out_str);
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int contacts_record_get_lli( contacts_record_h record, unsigned int property_id, long long int *value )
+{
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == value, CONTACTS_ERROR_INVALID_PARAMETER);
+       *value = 0;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_record = (ctsvc_record_s *)record;
+
+       __CHECK_PROJECTED_PROPERTY();
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->get_lli)
+               return s_record->plugin_cbs->get_lli(record, property_id, value);
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int contacts_record_get_double( contacts_record_h record, unsigned int property_id, double *value )
+{
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == value, CONTACTS_ERROR_INVALID_PARAMETER);
+       *value = 0;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_record = (ctsvc_record_s *)record;
+
+       __CHECK_PROJECTED_PROPERTY();
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->get_double)
+               return s_record->plugin_cbs->get_double(record, property_id, value);
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int contacts_record_get_str_p( contacts_record_h record, unsigned int property_id, char** out_str )
+{
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == out_str, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_str = NULL;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_record = (ctsvc_record_s *)record;
+
+       __CHECK_PROJECTED_PROPERTY();
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->get_str_p)
+               return s_record->plugin_cbs->get_str_p(record, property_id, out_str );
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int contacts_record_get_int( contacts_record_h record, unsigned int property_id, int* out_value )
+{
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == out_value, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_value = 0;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_record = (ctsvc_record_s *)record;
+
+       __CHECK_PROJECTED_PROPERTY();
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->get_int)
+               return s_record->plugin_cbs->get_int(record, property_id, out_value);
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int contacts_record_set_str( contacts_record_h record, unsigned int property_id, const char* value )
+{
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       __CHECK_READ_ONLY_PROPERTY();
+
+       return ctsvc_record_set_str(record, property_id, value);
+}
+
+int ctsvc_record_set_str( contacts_record_h record, unsigned int property_id, const char* value )
+{
+       char *str;
+       ctsvc_record_s *s_record;
+       int ret;
+
+       s_record = (ctsvc_record_s *)record;
+       __CHECK_PROJECTED_PROPERTY();
+
+       if (value && *value)
+               str = (char *)value;
+       else
+               str = NULL;
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->set_str) {
+               ret = s_record->plugin_cbs->set_str(record, property_id, str);
+               if (CONTACTS_ERROR_NONE == ret)
+                       ctsvc_record_set_property_flag(s_record, property_id, CTSVC_PROPERTY_FLAG_DIRTY);
+
+               return ret;
+       }
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int contacts_record_get_bool( contacts_record_h record, unsigned int property_id, bool* value )
+{
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == value, CONTACTS_ERROR_INVALID_PARAMETER);
+       *value = false;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_record = (ctsvc_record_s *)record;
+
+       __CHECK_PROJECTED_PROPERTY();
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->get_bool)
+               return s_record->plugin_cbs->get_bool(record, property_id, value);
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int        contacts_record_set_bool( contacts_record_h record, unsigned int property_id, bool value )
+{
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       __CHECK_READ_ONLY_PROPERTY();
+
+       return ctsvc_record_set_bool(record, property_id, value);
+}
+
+int ctsvc_record_set_bool( contacts_record_h record, unsigned int property_id, bool value )
+{
+       int ret;
+       ctsvc_record_s *s_record;
+       s_record = (ctsvc_record_s *)record;
+       __CHECK_PROJECTED_PROPERTY();
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->set_bool) {
+               ret = s_record->plugin_cbs->set_bool(record, property_id, value);
+               if (CONTACTS_ERROR_NONE == ret)
+                       ctsvc_record_set_property_flag(s_record, property_id, CTSVC_PROPERTY_FLAG_DIRTY);
+               return ret;
+       }
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int contacts_record_set_int( contacts_record_h record, unsigned int property_id, int value )
+{
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       __CHECK_READ_ONLY_PROPERTY();
+
+#ifdef _CONTACTS_IPC_CLIENT
+       if (CTSVC_RECORD_RESULT == ((ctsvc_record_s*)record)->r_type) {
+               CTS_ERR("Can not set int to result record");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+#endif
+       return ctsvc_record_set_int(record, property_id, value);
+}
+
+int ctsvc_record_set_int( contacts_record_h record, unsigned int property_id, int value )
+{
+       int ret;
+       ctsvc_record_s *s_record;
+       s_record = (ctsvc_record_s *)record;
+       __CHECK_PROJECTED_PROPERTY();
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->set_int) {
+               ret = s_record->plugin_cbs->set_int(record, property_id, value);
+               if (CONTACTS_ERROR_NONE == ret)
+                       ctsvc_record_set_property_flag(s_record, property_id, CTSVC_PROPERTY_FLAG_DIRTY);
+               return ret;
+       }
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int contacts_record_set_lli( contacts_record_h record, unsigned int property_id, long long int value )
+{
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       __CHECK_READ_ONLY_PROPERTY();
+
+       return ctsvc_record_set_lli(record, property_id, value);
+}
+
+int ctsvc_record_set_lli( contacts_record_h record, unsigned int property_id, long long int value )
+{
+       int ret;
+       ctsvc_record_s *s_record;
+       s_record = (ctsvc_record_s *)record;
+       __CHECK_PROJECTED_PROPERTY();
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->set_lli) {
+               ret = s_record->plugin_cbs->set_lli(record, property_id, value);
+               if (CONTACTS_ERROR_NONE == ret)
+                       ctsvc_record_set_property_flag(s_record, property_id, CTSVC_PROPERTY_FLAG_DIRTY);
+               return ret;
+       }
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int contacts_record_set_double( contacts_record_h record, unsigned int property_id, double value )
+{
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       __CHECK_READ_ONLY_PROPERTY();
+
+       return ctsvc_record_set_double(record, property_id, value);
+}
+
+int ctsvc_record_set_double( contacts_record_h record, unsigned int property_id, double value )
+{
+       int ret;
+       ctsvc_record_s *s_record;
+
+       s_record = (ctsvc_record_s *)record;
+       __CHECK_PROJECTED_PROPERTY();
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->set_double) {
+               ret = s_record->plugin_cbs->set_double(record, property_id, value);
+               if (CONTACTS_ERROR_NONE == ret)
+                       ctsvc_record_set_property_flag(s_record, property_id, CTSVC_PROPERTY_FLAG_DIRTY);
+               return ret;
+       }
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+// Record get/set child records
+API int        contacts_record_add_child_record( contacts_record_h record,
+               unsigned int property_id, contacts_record_h child_record )
+{
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == child_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_record = (ctsvc_record_s *)record;
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->add_child_record)
+               return s_record->plugin_cbs->add_child_record(record, property_id, child_record);
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int        contacts_record_remove_child_record( contacts_record_h record,
+               unsigned int property_id, contacts_record_h child_record )
+{
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == child_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_record = (ctsvc_record_s *)record;
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->remove_child_record)
+               return s_record->plugin_cbs->remove_child_record(record, property_id, child_record);
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int contacts_record_get_child_record_count( contacts_record_h record,
+               unsigned int property_id, int *count )
+{
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == count, CONTACTS_ERROR_INVALID_PARAMETER);
+       *count = 0;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_record = (ctsvc_record_s *)record;
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->get_child_record_count)
+               return s_record->plugin_cbs->get_child_record_count(record, property_id, count);
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int contacts_record_get_child_record_at_p( contacts_record_h record,
+               unsigned int property_id, int index, contacts_record_h* out_record )
+{
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_record = (ctsvc_record_s *)record;
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->get_child_record_at_p)
+               return s_record->plugin_cbs->get_child_record_at_p(record, property_id, index, out_record);
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+API int contacts_record_clone_child_record_list( contacts_record_h record,
+               unsigned int property_id, contacts_list_h* out_list )
+{
+       ctsvc_record_s *s_record;
+
+       RETV_IF(NULL == out_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_list = NULL;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_record = (ctsvc_record_s *)record;
+
+       if (s_record->plugin_cbs && s_record->plugin_cbs->clone_child_record_list)
+               return s_record->plugin_cbs->clone_child_record_list(record, property_id, out_list);
+
+       __INVALID_PARAMETER_ERROR_HANDLING();
+}
+
+int ctsvc_record_set_projection_flags( contacts_record_h record, const unsigned int *projection, const unsigned int projection_count, const unsigned int property_max_count)
+{
+       int i;
+
+       RETV_IF(record == NULL, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       ctsvc_record_s *_record = (ctsvc_record_s *)record;
+
+       CONTACTS_FREE(_record->properties_flags);
+
+       _record->properties_flags = calloc(property_max_count, sizeof(char));
+
+       RETVM_IF(NULL == _record->properties_flags, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc fail");
+
+       _record->property_max_count = property_max_count;
+
+       if (CTSVC_RECORD_RESULT == _record->r_type)
+               _record->property_flag |= CTSVC_PROPERTY_FLAG_PROJECTION;
+       else {
+               for (i=0;i<projection_count;i++)
+                       ctsvc_record_set_property_flag(_record, projection[i], CTSVC_PROPERTY_FLAG_PROJECTION);
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/common/ctsvc_record.h b/common/ctsvc_record.h
new file mode 100644 (file)
index 0000000..c79a34e
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 __TIZEN_SOCIAL_CTSVC_RECORD_H__
+#define __TIZEN_SOCIAL_CTSVC_RECORD_H__
+
+#define CTSVC_RECORD_INIT_BASE(base, type, cb, uri) do {\
+    (base)->r_type = (type);\
+    (base)->plugin_cbs = (cb);\
+    (base)->view_uri = (uri);\
+    (base)->property_max_count = 0;\
+} while (0)
+
+#define CTSVC_RECORD_COPY_BASE(dest, src) do {\
+       (dest)->r_type = (src)->r_type;\
+       (dest)->plugin_cbs = (src)->plugin_cbs;\
+       (dest)->view_uri = (src)->view_uri;\
+       (dest)->property_max_count = (src)->property_max_count;\
+       (dest)->property_flag = (src)->property_flag;\
+       if ((src)->properties_flags) \
+       {\
+               (dest)->properties_flags  = calloc((dest)->property_max_count, sizeof(char));\
+               if ((dest)->properties_flags) { \
+                       memcpy((dest)->properties_flags,(src)->properties_flags,sizeof(char)*(dest)->property_max_count);\
+               } \
+       }\
+} while (0)
+
+#define CTSVC_RECORD_RESET_PROPERTY_FLAGS(base)do {\
+    if ((base)->properties_flags) \
+    {\
+        free((base)->properties_flags); \
+        (base)->property_max_count = 0;\
+        (base)->properties_flags = NULL;\
+        (base)->property_flag = 0;\
+    }\
+} while (0)
+
+int ctsvc_record_set_property_flag(ctsvc_record_s* _record, int property_id, contacts_property_flag_e flag);
+int ctsvc_record_set_projection_flags( contacts_record_h record, const unsigned int *projection, const unsigned int projection_count, const unsigned int property_max_count);
+int ctsvc_record_set_str( contacts_record_h record, unsigned int property_id, const char* value );
+int ctsvc_record_set_bool( contacts_record_h record, unsigned int property_id, bool value );
+int ctsvc_record_set_int( contacts_record_h record, unsigned int property_id, int value );
+int ctsvc_record_set_lli( contacts_record_h record, unsigned int property_id, long long int value );
+int ctsvc_record_set_double( contacts_record_h record, unsigned int property_id, double value );
+bool ctsvc_record_check_property_flag(const ctsvc_record_s* s_record, unsigned int property_id, contacts_property_flag_e flag);
+
+#endif /* __TIZEN_SOCIAL_CTSVC_RECORD_H__ */
diff --git a/common/ctsvc_record_addressbook.c b/common/ctsvc_record_addressbook.c
new file mode 100644 (file)
index 0000000..5a88da6
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+
+#include "contacts.h"
+
+#include "ctsvc_internal.h"
+#include "ctsvc_record.h"
+
+static int __ctsvc_addressbook_create(contacts_record_h *out_record);
+static int __ctsvc_addressbook_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_addressbook_clone( contacts_record_h record, contacts_record_h* out_record );
+static int __ctsvc_addressbook_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_addressbook_get_str(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_addressbook_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_addressbook_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_addressbook_set_str(contacts_record_h record, unsigned int property_id, const char* str);
+
+ctsvc_record_plugin_cb_s addressbook_plugin_cbs = {
+       .create = __ctsvc_addressbook_create,
+       .destroy = __ctsvc_addressbook_destroy,
+       .clone = __ctsvc_addressbook_clone,
+       .get_str = __ctsvc_addressbook_get_str,
+       .get_str_p =  __ctsvc_addressbook_get_str_p,
+       .get_int = __ctsvc_addressbook_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_addressbook_set_str,
+       .set_int = __ctsvc_addressbook_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+static int __ctsvc_addressbook_create(contacts_record_h *out_record)
+{
+       ctsvc_addressbook_s *addressbook;
+
+       addressbook = (ctsvc_addressbook_s*)calloc(1, sizeof(ctsvc_addressbook_s));
+       RETVM_IF(NULL == addressbook, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)addressbook;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_addressbook_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_addressbook_s *addressbook = (ctsvc_addressbook_s*)record;
+
+       addressbook->base.plugin_cbs = NULL;    // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(addressbook->base.properties_flags);
+       free(addressbook->name);
+       free(addressbook);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_addressbook_clone( contacts_record_h record, contacts_record_h* out_record )
+{
+       ctsvc_addressbook_s *src = (ctsvc_addressbook_s*)record;
+       ctsvc_addressbook_s *dest;
+
+       dest = calloc(1, sizeof(ctsvc_addressbook_s));
+       RETVM_IF(NULL == dest, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       CTSVC_RECORD_COPY_BASE(&(dest->base), &(src->base));
+
+       dest->id = src->id;
+       dest->account_id = src->account_id;
+       dest->mode = src->mode;
+       dest->name = SAFE_STRDUP(src->name);
+
+       *out_record = (contacts_record_h)dest;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_addressbook_get_str_real(contacts_record_h record,
+               unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_addressbook_s *addressbook = (ctsvc_addressbook_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ADDRESSBOOK_NAME:
+               *out_str = GET_STR(copy, addressbook->name);
+               break;
+       default :
+               CTS_ERR("This field(%d) is not supported in value(addressbook)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_addressbook_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_addressbook_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_addressbook_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_addressbook_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_addressbook_set_str(contacts_record_h record,
+               unsigned int property_id, const char* str )
+{
+       ctsvc_addressbook_s *addressbook = (ctsvc_addressbook_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ADDRESSBOOK_NAME:
+               FREEandSTRDUP(addressbook->name, str);
+               break;
+       default :
+               CTS_ERR("This field(%d) is not supported in value(addressbook)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_addressbook_get_int(contacts_record_h record,
+               unsigned int property_id, int *out)
+{
+       ctsvc_addressbook_s *addressbook = (ctsvc_addressbook_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ADDRESSBOOK_ID:
+               *out = addressbook->id;
+               break;
+       case CTSVC_PROPERTY_ADDRESSBOOK_ACCOUNT_ID:
+               *out = addressbook->account_id;
+               break;
+       case CTSVC_PROPERTY_ADDRESSBOOK_MODE:
+               *out = addressbook->mode;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(addressbook)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_addressbook_set_int(contacts_record_h record,
+               unsigned int property_id, int value)
+{
+       ctsvc_addressbook_s *addressbook = (ctsvc_addressbook_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ADDRESSBOOK_ID:
+               addressbook->id = value;
+               break;
+       case CTSVC_PROPERTY_ADDRESSBOOK_MODE:
+               RETVM_IF(value != CONTACTS_ADDRESS_BOOK_MODE_NONE
+                                               && value != CONTACTS_ADDRESS_BOOK_MODE_READONLY,
+                               CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : address_book mode is %d", value);
+               addressbook->mode = value;
+               break;
+       case CTSVC_PROPERTY_ADDRESSBOOK_ACCOUNT_ID:
+               RETVM_IF(addressbook->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (addressbook)", property_id);
+               addressbook->account_id = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(addressbook)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/common/ctsvc_record_contact.c b/common/ctsvc_record_contact.c
new file mode 100755 (executable)
index 0000000..5e45bdd
--- /dev/null
@@ -0,0 +1,4499 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+#include <unistd.h>
+
+#include "contacts.h"
+
+#include "ctsvc_internal.h"
+#include "ctsvc_list.h"
+#include "ctsvc_record.h"
+#include "ctsvc_view.h"
+
+static int __ctsvc_activity_create(contacts_record_h *out_record);
+static int __ctsvc_activity_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_activity_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_activity_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_activity_get_str(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_activity_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_activity_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_activity_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+static int __ctsvc_activity_add_child_record(contacts_record_h record, unsigned int property_id, contacts_record_h child_record );
+static int __ctsvc_activity_remove_child_record(contacts_record_h record, unsigned int property_id, contacts_record_h child_record );
+static int __ctsvc_activity_get_child_record_count(contacts_record_h record, unsigned int property_id, int *count );
+static int __ctsvc_activity_get_child_record_at_p(contacts_record_h record, unsigned int property_id, int index, contacts_record_h* out_record );
+static int __ctsvc_activity_clone_child_record_list(contacts_record_h record, unsigned int property_id, contacts_list_h* out_list );
+
+static int __ctsvc_activity_photo_create(contacts_record_h *out_record);
+static int __ctsvc_activity_photo_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_activity_photo_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_activity_photo_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_activity_photo_get_str(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_activity_photo_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_activity_photo_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_activity_photo_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+
+
+static int __ctsvc_address_create(contacts_record_h *out_ecord);
+static int __ctsvc_address_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_address_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_address_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_address_get_str(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_address_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_address_get_bool(contacts_record_h record, unsigned int property_id, bool *value );
+static int __ctsvc_address_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_address_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+static int __ctsvc_address_set_bool(contacts_record_h record, unsigned int property_id, bool value);
+
+static int __ctsvc_company_create(contacts_record_h *out_record);
+static int __ctsvc_company_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_company_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_company_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_company_get_str(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_company_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_company_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_company_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+
+static int __ctsvc_contact_create(contacts_record_h *out_record);
+static int __ctsvc_contact_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_contact_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_contact_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_contact_get_str(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_contact_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_contact_get_bool(contacts_record_h record, unsigned int property_id, bool *value );
+static int __ctsvc_contact_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_contact_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+static int __ctsvc_contact_set_bool(contacts_record_h record, unsigned int property_id, bool value);
+static int __ctsvc_contact_clone_child_record_list(contacts_record_h record, unsigned int property_id, contacts_list_h* out_list );
+static int __ctsvc_contact_get_child_record_at_p(contacts_record_h record, unsigned int property_id, int index, contacts_record_h* out_record );
+static int __ctsvc_contact_get_child_record_count(contacts_record_h record, unsigned int property_id, int *count );
+static int __ctsvc_contact_add_child_record(contacts_record_h record, unsigned int property_id, contacts_record_h child_record );
+static int __ctsvc_contact_remove_child_record(contacts_record_h record, unsigned int property_id, contacts_record_h child_record );
+
+static int __ctsvc_email_create(contacts_record_h *out_record);
+static int __ctsvc_email_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_email_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_email_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_email_get_str(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_email_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_email_get_bool(contacts_record_h record, unsigned int property_id, bool *value );
+static int __ctsvc_email_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_email_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+static int __ctsvc_email_set_bool(contacts_record_h record, unsigned int property_id, bool value);
+
+static int __ctsvc_event_create(contacts_record_h *out_record);
+static int __ctsvc_event_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_event_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_event_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_event_get_str(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_event_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_event_get_bool(contacts_record_h record, unsigned int property_id, bool *value );
+static int __ctsvc_event_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_event_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+static int __ctsvc_event_set_bool(contacts_record_h record, unsigned int property_id, bool value);
+
+static int __ctsvc_extension_create(contacts_record_h *out_record);
+static int __ctsvc_extension_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_extension_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_extension_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_extension_get_str(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_extension_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_extension_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_extension_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+
+static int __ctsvc_group_relation_create(contacts_record_h *out_record);
+static int __ctsvc_group_relation_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_group_relation_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_group_relation_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_group_relation_get_str(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_group_relation_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_group_relation_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_group_relation_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+
+static int __ctsvc_messenger_create(contacts_record_h *out_record);
+static int __ctsvc_messenger_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_messenger_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_messenger_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_messenger_get_str(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_messenger_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_messenger_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_messenger_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+
+static int __ctsvc_name_create(contacts_record_h *out_record);
+static int __ctsvc_name_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_name_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_name_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_name_get_str(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_name_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_name_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_name_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+
+static int __ctsvc_nickname_create(contacts_record_h *out_record);
+static int __ctsvc_nickname_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_nickname_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_nickname_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_nickname_get_str(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_nickname_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_nickname_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_nickname_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+
+static int __ctsvc_note_create(contacts_record_h *out_record);
+static int __ctsvc_note_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_note_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_note_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_note_get_str(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_note_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_note_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_note_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+
+static int __ctsvc_number_create(contacts_record_h *out_record);
+static int __ctsvc_number_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_number_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_number_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_number_get_str(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_number_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_number_get_bool(contacts_record_h record, unsigned int property_id, bool *value );
+static int __ctsvc_number_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_number_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+static int __ctsvc_number_set_bool(contacts_record_h record, unsigned int property_id, bool value);
+
+static int __ctsvc_profile_create(contacts_record_h *out_record);
+static int __ctsvc_profile_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_profile_clone(contacts_record_h record, contacts_record_h *out_reord);
+static int __ctsvc_profile_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_profile_get_str(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_profile_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_profile_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_profile_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+
+static int __ctsvc_relationship_create(contacts_record_h *out_record);
+static int __ctsvc_relationship_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_relationship_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_relationship_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_relationship_get_str(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_relationship_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_relationship_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_relationship_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+
+static int __ctsvc_image_create(contacts_record_h *out_record);
+static int __ctsvc_image_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_image_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_image_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_image_get_str(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_image_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_image_get_bool(contacts_record_h record, unsigned int property_id, bool *value );
+static int __ctsvc_image_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_image_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+static int __ctsvc_image_set_bool(contacts_record_h record, unsigned int property_id, bool value);
+
+static int __ctsvc_simple_contact_create(contacts_record_h *out_record);
+static int __ctsvc_simple_contact_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_simple_contact_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_simple_contact_get_bool(contacts_record_h record, unsigned int property_id, bool *out);
+static int __ctsvc_simple_contact_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_simple_contact_get_str(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_simple_contact_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_simple_contact_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_simple_contact_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+
+static int __ctsvc_url_create(contacts_record_h *out_record);
+static int __ctsvc_url_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_url_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_url_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_url_get_str(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_url_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_url_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_url_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+
+static GHashTable *__ctsvc_temp_image_file_hash_table = NULL;
+
+ctsvc_record_plugin_cb_s name_plugin_cbs = {
+       .create = __ctsvc_name_create,
+       .destroy = __ctsvc_name_destroy,
+       .clone = __ctsvc_name_clone,
+       .get_str = __ctsvc_name_get_str,
+       .get_str_p = __ctsvc_name_get_str_p,
+       .get_int = __ctsvc_name_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_name_set_str,
+       .set_int = __ctsvc_name_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+ctsvc_record_plugin_cb_s number_plugin_cbs = {
+       .create = __ctsvc_number_create,
+       .destroy = __ctsvc_number_destroy,
+       .clone = __ctsvc_number_clone,
+       .get_str = __ctsvc_number_get_str,
+       .get_str_p = __ctsvc_number_get_str_p,
+       .get_int = __ctsvc_number_get_int,
+       .get_bool = __ctsvc_number_get_bool,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_number_set_str,
+       .set_int = __ctsvc_number_set_int,
+       .set_bool = __ctsvc_number_set_bool,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+ctsvc_record_plugin_cb_s address_plugin_cbs = {
+       .create = __ctsvc_address_create,
+       .destroy = __ctsvc_address_destroy,
+       .clone = __ctsvc_address_clone,
+       .get_str = __ctsvc_address_get_str,
+       .get_str_p = __ctsvc_address_get_str_p,
+       .get_int = __ctsvc_address_get_int,
+       .get_bool = __ctsvc_address_get_bool,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_address_set_str,
+       .set_int = __ctsvc_address_set_int,
+       .set_bool = __ctsvc_address_set_bool,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+ctsvc_record_plugin_cb_s url_plugin_cbs = {
+       .create = __ctsvc_url_create,
+       .destroy = __ctsvc_url_destroy,
+       .clone = __ctsvc_url_clone,
+       .get_str = __ctsvc_url_get_str,
+       .get_str_p = __ctsvc_url_get_str_p,
+       .get_int = __ctsvc_url_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_url_set_str,
+       .set_int = __ctsvc_url_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+ctsvc_record_plugin_cb_s event_plugin_cbs = {
+       .create = __ctsvc_event_create,
+       .destroy = __ctsvc_event_destroy,
+       .clone = __ctsvc_event_clone,
+       .get_str = __ctsvc_event_get_str,
+       .get_str_p = __ctsvc_event_get_str_p,
+       .get_int = __ctsvc_event_get_int,
+       .get_bool = __ctsvc_event_get_bool,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_event_set_str,
+       .set_int = __ctsvc_event_set_int,
+       .set_bool = __ctsvc_event_set_bool,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+ctsvc_record_plugin_cb_s messenger_plugin_cbs = {
+       .create = __ctsvc_messenger_create,
+       .destroy = __ctsvc_messenger_destroy,
+       .clone = __ctsvc_messenger_clone,
+       .get_str = __ctsvc_messenger_get_str,
+       .get_str_p = __ctsvc_messenger_get_str_p,
+       .get_int = __ctsvc_messenger_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_messenger_set_str,
+       .set_int = __ctsvc_messenger_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+ctsvc_record_plugin_cb_s activity_plugin_cbs = {
+       .create = __ctsvc_activity_create,
+       .destroy = __ctsvc_activity_destroy,
+       .clone = __ctsvc_activity_clone,
+       .get_str = __ctsvc_activity_get_str,
+       .get_str_p = __ctsvc_activity_get_str_p,
+       .get_int = __ctsvc_activity_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_activity_set_str,
+       .set_int = __ctsvc_activity_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = __ctsvc_activity_add_child_record,
+       .remove_child_record = __ctsvc_activity_remove_child_record,
+       .get_child_record_count = __ctsvc_activity_get_child_record_count,
+       .get_child_record_at_p = __ctsvc_activity_get_child_record_at_p,
+       .clone_child_record_list = __ctsvc_activity_clone_child_record_list,
+};
+
+ctsvc_record_plugin_cb_s activity_photo_plugin_cbs = {
+       .create = __ctsvc_activity_photo_create,
+       .destroy = __ctsvc_activity_photo_destroy,
+       .clone = __ctsvc_activity_photo_clone,
+       .get_str = __ctsvc_activity_photo_get_str,
+       .get_str_p = __ctsvc_activity_photo_get_str_p,
+       .get_int = __ctsvc_activity_photo_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_activity_photo_set_str,
+       .set_int = __ctsvc_activity_photo_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+ctsvc_record_plugin_cb_s relationship_plugin_cbs = {
+       .create = __ctsvc_relationship_create,
+       .destroy = __ctsvc_relationship_destroy,
+       .clone = __ctsvc_relationship_clone,
+       .get_str = __ctsvc_relationship_get_str,
+       .get_str_p = __ctsvc_relationship_get_str_p,
+       .get_int = __ctsvc_relationship_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_relationship_set_str,
+       .set_int = __ctsvc_relationship_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+ctsvc_record_plugin_cb_s image_plugin_cbs = {
+       .create = __ctsvc_image_create,
+       .destroy = __ctsvc_image_destroy,
+       .clone = __ctsvc_image_clone,
+       .get_str = __ctsvc_image_get_str,
+       .get_str_p = __ctsvc_image_get_str_p,
+       .get_int = __ctsvc_image_get_int,
+       .get_bool = __ctsvc_image_get_bool,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_image_set_str,
+       .set_int = __ctsvc_image_set_int,
+       .set_bool = __ctsvc_image_set_bool,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+ctsvc_record_plugin_cb_s group_relation_plugin_cbs = {
+       .create = __ctsvc_group_relation_create,
+       .destroy = __ctsvc_group_relation_destroy,
+       .clone = __ctsvc_group_relation_clone,
+       .get_str = __ctsvc_group_relation_get_str,
+       .get_str_p = __ctsvc_group_relation_get_str_p,
+       .get_int = __ctsvc_group_relation_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_group_relation_set_str,
+       .set_int = __ctsvc_group_relation_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+ctsvc_record_plugin_cb_s note_plugin_cbs = {
+       .create = __ctsvc_note_create,
+       .destroy = __ctsvc_note_destroy,
+       .clone = __ctsvc_note_clone,
+       .get_str = __ctsvc_note_get_str,
+       .get_str_p = __ctsvc_note_get_str_p,
+       .get_int = __ctsvc_note_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_note_set_str,
+       .set_int = __ctsvc_note_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+ctsvc_record_plugin_cb_s company_plugin_cbs = {
+       .create = __ctsvc_company_create,
+       .destroy = __ctsvc_company_destroy,
+       .clone = __ctsvc_company_clone,
+       .get_str = __ctsvc_company_get_str,
+       .get_str_p = __ctsvc_company_get_str_p,
+       .get_int = __ctsvc_company_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_company_set_str,
+       .set_int = __ctsvc_company_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+ctsvc_record_plugin_cb_s profile_plugin_cbs = {
+       .create = __ctsvc_profile_create,
+       .destroy = __ctsvc_profile_destroy,
+       .clone = __ctsvc_profile_clone,
+       .get_str = __ctsvc_profile_get_str,
+       .get_str_p = __ctsvc_profile_get_str_p,
+       .get_int = __ctsvc_profile_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_profile_set_str,
+       .set_int = __ctsvc_profile_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+ctsvc_record_plugin_cb_s nickname_plugin_cbs = {
+       .create = __ctsvc_nickname_create,
+       .destroy = __ctsvc_nickname_destroy,
+       .clone = __ctsvc_nickname_clone,
+       .get_str = __ctsvc_nickname_get_str,
+       .get_str_p = __ctsvc_nickname_get_str_p,
+       .get_int = __ctsvc_nickname_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_nickname_set_str,
+       .set_int = __ctsvc_nickname_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+ctsvc_record_plugin_cb_s email_plugin_cbs = {
+       .create = __ctsvc_email_create,
+       .destroy = __ctsvc_email_destroy,
+       .clone = __ctsvc_email_clone,
+       .get_str = __ctsvc_email_get_str,
+       .get_str_p = __ctsvc_email_get_str_p,
+       .get_int = __ctsvc_email_get_int,
+       .get_bool = __ctsvc_email_get_bool,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_email_set_str,
+       .set_int = __ctsvc_email_set_int,
+       .set_bool = __ctsvc_email_set_bool,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+ctsvc_record_plugin_cb_s extension_plugin_cbs = {
+       .create = __ctsvc_extension_create,
+       .destroy = __ctsvc_extension_destroy,
+       .clone = __ctsvc_extension_clone,
+       .get_str = __ctsvc_extension_get_str,
+       .get_str_p = __ctsvc_extension_get_str_p,
+       .get_int = __ctsvc_extension_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_extension_set_str,
+       .set_int = __ctsvc_extension_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+ctsvc_record_plugin_cb_s contact_plugin_cbs = {
+       .create = __ctsvc_contact_create,
+       .destroy = __ctsvc_contact_destroy,
+       .clone = __ctsvc_contact_clone,
+       .get_str = __ctsvc_contact_get_str,
+       .get_str_p = __ctsvc_contact_get_str_p,
+       .get_int = __ctsvc_contact_get_int,
+       .get_bool = __ctsvc_contact_get_bool,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_contact_set_str,
+       .set_int = __ctsvc_contact_set_int,
+       .set_bool = __ctsvc_contact_set_bool,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = __ctsvc_contact_add_child_record,
+       .remove_child_record = __ctsvc_contact_remove_child_record,
+       .get_child_record_count = __ctsvc_contact_get_child_record_count,
+       .get_child_record_at_p = __ctsvc_contact_get_child_record_at_p,
+       .clone_child_record_list = __ctsvc_contact_clone_child_record_list,
+};
+
+ctsvc_record_plugin_cb_s simple_contact_plugin_cbs = {
+       .create = __ctsvc_simple_contact_create,
+       .destroy = __ctsvc_simple_contact_destroy,
+       .clone = __ctsvc_simple_contact_clone,
+       .get_str = __ctsvc_simple_contact_get_str,
+       .get_str_p = __ctsvc_simple_contact_get_str_p,
+       .get_int = __ctsvc_simple_contact_get_int,
+       .get_bool = __ctsvc_simple_contact_get_bool,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_simple_contact_set_str,
+       .set_int = __ctsvc_simple_contact_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+static int __ctsvc_activity_create(contacts_record_h *out_record)
+{
+       ctsvc_activity_s *activity;
+       activity = (ctsvc_activity_s*)calloc(1, sizeof(ctsvc_activity_s));
+       RETVM_IF(NULL == activity, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       activity->photos = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == activity->photos) {
+               free(activity);
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       activity->photos->l_type = CTSVC_RECORD_ACTIVITY_PHOTO;
+
+       *out_record = (contacts_record_h)activity;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_activity_photo_create(contacts_record_h *out_record)
+{
+       ctsvc_activity_photo_s *photo;
+       photo = (ctsvc_activity_photo_s*)calloc(1, sizeof(ctsvc_activity_photo_s));
+       RETVM_IF(NULL == photo, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)photo;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_address_create(contacts_record_h *out_record)
+{
+       ctsvc_address_s *address;
+
+       address = (ctsvc_address_s*)calloc(1, sizeof(ctsvc_address_s));
+       RETVM_IF(NULL == address, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)address;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_company_create(contacts_record_h *out_record)
+{
+       ctsvc_company_s *company;
+
+       company = (ctsvc_company_s*)calloc(1, sizeof(ctsvc_company_s));
+       RETVM_IF(NULL == company, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)company;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_email_create(contacts_record_h *out_record)
+{
+       ctsvc_email_s *email;
+       email = (ctsvc_email_s*)calloc(1, sizeof(ctsvc_email_s));
+       RETVM_IF(NULL == email, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)email;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_event_create(contacts_record_h *out_record)
+{
+       ctsvc_event_s *event;
+       event = (ctsvc_event_s*)calloc(1, sizeof(ctsvc_event_s));
+       RETVM_IF(NULL == event, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)event;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_extension_create(contacts_record_h *out_record)
+{
+       ctsvc_extension_s *extension;
+       extension = (ctsvc_extension_s*)calloc(1, sizeof(ctsvc_extension_s));
+       RETVM_IF(NULL == extension, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)extension;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_group_relation_create(contacts_record_h *out_record)
+{
+       ctsvc_group_relation_s *group_relation;
+       group_relation = (ctsvc_group_relation_s*)calloc(1, sizeof(ctsvc_group_relation_s));
+       RETVM_IF(NULL == group_relation, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)group_relation;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_messenger_create(contacts_record_h *out_record)
+{
+       ctsvc_messenger_s *messenger;
+       messenger = (ctsvc_messenger_s*)calloc(1, sizeof(ctsvc_messenger_s));
+       RETVM_IF(NULL == messenger, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)messenger;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_name_create(contacts_record_h *out_record)
+{
+       ctsvc_name_s *name;
+
+       name = (ctsvc_name_s*)calloc(1, sizeof(ctsvc_name_s));
+       RETVM_IF(NULL == name, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)name;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_nickname_create(contacts_record_h *out_record)
+{
+       ctsvc_nickname_s *nickname;
+
+       nickname = (ctsvc_nickname_s*)calloc(1, sizeof(ctsvc_nickname_s));
+       RETVM_IF(NULL == nickname, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)nickname;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_note_create(contacts_record_h *out_record)
+{
+       ctsvc_note_s *note;
+
+       note = (ctsvc_note_s*)calloc(1, sizeof(ctsvc_note_s));
+       RETVM_IF(NULL == note, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)note;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_number_create(contacts_record_h *out_record)
+{
+       ctsvc_number_s *number;
+
+       number = (ctsvc_number_s*)calloc(1, sizeof(ctsvc_number_s));
+       RETVM_IF(NULL == number, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)number;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_profile_create(contacts_record_h *out_record)
+{
+       ctsvc_profile_s *profile;
+
+       profile = (ctsvc_profile_s*)calloc(1, sizeof(ctsvc_profile_s));
+       RETVM_IF(NULL == profile, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)profile;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_relationship_create(contacts_record_h *out_record)
+{
+       ctsvc_relationship_s *relationship;
+
+       relationship = (ctsvc_relationship_s*)calloc(1, sizeof(ctsvc_relationship_s));
+       RETVM_IF(NULL == relationship, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)relationship;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_image_create(contacts_record_h *out_record)
+{
+       ctsvc_image_s *image;
+
+       image = (ctsvc_image_s*)calloc(1, sizeof(ctsvc_image_s));
+       RETVM_IF(NULL == image, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)image;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_simple_contact_create(contacts_record_h *out_record)
+{
+       ctsvc_simple_contact_s *simple_contact;
+
+       simple_contact = (ctsvc_simple_contact_s*)calloc(1, sizeof(ctsvc_simple_contact_s));
+       RETVM_IF(NULL == simple_contact, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)simple_contact;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_url_create(contacts_record_h *out_record)
+{
+       ctsvc_url_s *url;
+
+       url = (ctsvc_url_s*)calloc(1, sizeof(ctsvc_url_s));
+       RETVM_IF(NULL == url, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)url;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_name_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_name_s *name = (ctsvc_name_s*)record;
+       name->base.plugin_cbs = NULL;   // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(name->base.properties_flags);
+
+       free(name->first);
+       free(name->last);
+       free(name->addition);
+       free(name->prefix);
+       free(name->suffix);
+       free(name->phonetic_first);
+       free(name->phonetic_middle);
+       free(name->phonetic_last);
+       free(name->lookup);
+       free(name->reverse_lookup);
+       free(name);
+
+       return CONTACTS_ERROR_NONE;
+};
+
+static void __ctsvc_temp_image_hash_table_insert(char *filename)
+{
+       int count = 0;
+       if (NULL == __ctsvc_temp_image_file_hash_table)
+               __ctsvc_temp_image_file_hash_table = g_hash_table_new(g_str_hash, g_str_equal);
+
+       count = GPOINTER_TO_INT(g_hash_table_lookup(__ctsvc_temp_image_file_hash_table, filename));
+       g_hash_table_insert(__ctsvc_temp_image_file_hash_table, filename, GINT_TO_POINTER(count+1));
+}
+
+static void __ctsvc_temp_image_hash_table_remove(char *filename)
+{
+       int count = 0;
+
+       if (NULL == __ctsvc_temp_image_file_hash_table) {
+               if (unlink(filename) < 0) {
+                       CTS_WARN("unlink Failed(%d)", errno);
+               }
+               return;
+       }
+
+       count = GPOINTER_TO_INT(g_hash_table_lookup(__ctsvc_temp_image_file_hash_table, filename));
+       if (count < 1) {
+               if (unlink(filename) < 0) {
+                       CTS_WARN("unlink Failed(%d)", errno);
+               }
+       }
+       else if (1 == count) {
+               g_hash_table_remove(__ctsvc_temp_image_file_hash_table, filename);
+               if (0 == g_hash_table_size(__ctsvc_temp_image_file_hash_table)) {
+                       g_hash_table_destroy(__ctsvc_temp_image_file_hash_table);
+                       __ctsvc_temp_image_file_hash_table = NULL;
+               }
+       }
+       else {
+               g_hash_table_insert(__ctsvc_temp_image_file_hash_table, filename, GINT_TO_POINTER(count-1));
+       }
+}
+
+#define CTSVC_VCARD_IMAGE_LOCATION "/opt/usr/data/contacts-svc/img/vcard"
+static int __ctsvc_company_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_company_s *company = (ctsvc_company_s*)record;
+       company->base.plugin_cbs = NULL;        // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(company->base.properties_flags);
+
+       free(company->label);
+       free(company->name);
+       free(company->department);
+       free(company->job_title);
+       free(company->role);
+       free(company->assistant_name);
+       if (company->logo && company->is_vcard)
+               __ctsvc_temp_image_hash_table_remove(company->logo);
+       free(company->logo);
+       free(company->location);
+       free(company->description);
+       free(company->phonetic_name);
+       free(company);
+
+       return CONTACTS_ERROR_NONE;
+};
+
+static int __ctsvc_note_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_note_s *note = (ctsvc_note_s*)record;
+       note->base.plugin_cbs = NULL;   // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(note->base.properties_flags);
+
+       free(note->note);
+       free(note);
+
+       return CONTACTS_ERROR_NONE;
+};
+
+static int __ctsvc_number_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_number_s *number = (ctsvc_number_s*)record;
+       number->base.plugin_cbs = NULL; // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(number->base.properties_flags);
+
+       free(number->label);
+       free(number->number);
+       free(number->normalized);
+       free(number->cleaned);
+       free(number->lookup);
+       free(number);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_email_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_email_s *email = (ctsvc_email_s*)record;
+       email->base.plugin_cbs = NULL;  // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(email->base.properties_flags);
+
+       free(email->label);
+       free(email->email_addr);
+       free(email);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_group_relation_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_group_relation_s *group = (ctsvc_group_relation_s*)record;
+       group->base.plugin_cbs = NULL;  // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(group->base.properties_flags);
+
+       free(group->group_name);
+       free(group);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_activity_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_activity_s *activity = (ctsvc_activity_s*)record;
+       activity->base.plugin_cbs = NULL;       // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(activity->base.properties_flags);
+
+       free(activity->source_name);
+       free(activity->status);
+       free(activity->service_operation);
+       free(activity->uri);
+       contacts_list_destroy((contacts_list_h)activity->photos, delete_child);
+       free(activity);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_activity_photo_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_activity_photo_s *photo = (ctsvc_activity_photo_s*)record;
+       photo->base.plugin_cbs = NULL;  // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(photo->base.properties_flags);
+
+       free(photo->photo_url);
+       free(photo);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_event_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_event_s *event = (ctsvc_event_s*)record;
+       event->base.plugin_cbs = NULL;  // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(event->base.properties_flags);
+
+       free(event->label);
+       free(event);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_messenger_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_messenger_s *messenger = (ctsvc_messenger_s*)record;
+       messenger->base.plugin_cbs = NULL;
+       free(messenger->base.properties_flags);
+
+       free(messenger->label);
+       free(messenger->im_id);
+       free(messenger);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_address_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_address_s *address = (ctsvc_address_s*)record;
+       address->base.plugin_cbs = NULL;        // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(address->base.properties_flags);
+
+       free(address->label);
+       free(address->pobox);
+       free(address->postalcode);
+       free(address->region);
+       free(address->locality);
+       free(address->street);
+       free(address->extended);
+       free(address->country);
+       free(address);
+
+       return CONTACTS_ERROR_NONE;
+}
+static int __ctsvc_url_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_url_s *url = (ctsvc_url_s*)record;
+       url->base.plugin_cbs = NULL;    // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(url->base.properties_flags);
+
+       free(url->label);
+       free(url->url);
+       free(url);
+
+       return CONTACTS_ERROR_NONE;
+}
+static int __ctsvc_nickname_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_nickname_s *nickname = (ctsvc_nickname_s*)record;
+       nickname->base.plugin_cbs = NULL;       // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(nickname->base.properties_flags);
+
+       free(nickname->label);
+       free(nickname->nickname);
+       free(nickname);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_profile_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_profile_s *profile = (ctsvc_profile_s*)record;
+       profile->base.plugin_cbs = NULL;        // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(profile->base.properties_flags);
+
+       free(profile->uid);
+       free(profile->text);
+       free(profile->service_operation);
+       free(profile->mime);
+       free(profile->app_id);
+       free(profile->uri);
+       free(profile->category);
+       free(profile->extra_data);
+       free(profile);
+
+       return CONTACTS_ERROR_NONE;
+}
+static int __ctsvc_relationship_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_relationship_s *relationship = (ctsvc_relationship_s*)record;
+       relationship->base.plugin_cbs = NULL;   // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(relationship->base.properties_flags);
+
+       free(relationship->label);
+       free(relationship->name);
+       free(relationship);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_image_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_image_s *image = (ctsvc_image_s*)record;
+       image->base.plugin_cbs = NULL;  // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(image->base.properties_flags);
+
+       free(image->label);
+       if (image->path && image->is_vcard)
+               __ctsvc_temp_image_hash_table_remove(image->path);
+       free(image->path);
+       free(image);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_extension_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_extension_s *data = (ctsvc_extension_s*)record;
+       data->base.plugin_cbs = NULL;   // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(data->base.properties_flags);
+
+       free(data->data2);
+       free(data->data3);
+       free(data->data4);
+       free(data->data5);
+       free(data->data6);
+       free(data->data7);
+       free(data->data8);
+       free(data->data9);
+       free(data->data10);
+       free(data->data11);
+       free(data->data12);
+       free(data);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_simple_contact_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_simple_contact_s *contact= (ctsvc_simple_contact_s*)record;
+       contact->base.plugin_cbs = NULL;        // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(contact->base.properties_flags);
+
+       free(contact->display_name);
+       free(contact->image_thumbnail_path);
+       free(contact->ringtone_path);
+       free(contact->vibration);
+       free(contact->message_alert);
+       free(contact->uid);
+       free(contact);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_contact_create(contacts_record_h *out_record)
+{
+       ctsvc_contact_s *contact;
+
+       contact = calloc(1, sizeof(ctsvc_contact_s));
+       RETVM_IF(NULL == contact, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       contact->name = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == contact->name) {
+               __ctsvc_contact_destroy((contacts_record_h)contact, true);
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       contact->name->l_type = CTSVC_RECORD_NAME;
+
+       contact->company = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == contact->company) {
+               __ctsvc_contact_destroy((contacts_record_h)contact, true);
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       contact->company->l_type = CTSVC_RECORD_COMPANY;
+
+       contact->note = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == contact->note) {
+               __ctsvc_contact_destroy((contacts_record_h)contact, true);
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       contact->note->l_type = CTSVC_RECORD_NOTE;
+
+       contact->numbers = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == contact->numbers) {
+               __ctsvc_contact_destroy((contacts_record_h)contact, true);
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       contact->numbers->l_type = CTSVC_RECORD_NUMBER;
+
+       contact->emails = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == contact->emails) {
+               __ctsvc_contact_destroy((contacts_record_h)contact, true);
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       contact->emails->l_type = CTSVC_RECORD_EMAIL;
+
+       contact->grouprelations = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == contact->grouprelations) {
+               __ctsvc_contact_destroy((contacts_record_h)contact, true);
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       contact->grouprelations->l_type = CTSVC_RECORD_GROUP_RELATION;
+
+       contact->events = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == contact->events) {
+               __ctsvc_contact_destroy((contacts_record_h)contact, true);
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       contact->events->l_type = CTSVC_RECORD_EVENT;
+
+       contact->messengers = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == contact->messengers) {
+               __ctsvc_contact_destroy((contacts_record_h)contact, true);
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       contact->messengers->l_type = CTSVC_RECORD_MESSENGER;
+
+       contact->postal_addrs = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == contact->postal_addrs) {
+               __ctsvc_contact_destroy((contacts_record_h)contact, true);
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       contact->postal_addrs->l_type = CTSVC_RECORD_ADDRESS;
+
+       contact->urls = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == contact->urls) {
+               __ctsvc_contact_destroy((contacts_record_h)contact, true);
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       contact->urls->l_type = CTSVC_RECORD_URL;
+
+       contact->nicknames = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == contact->nicknames) {
+               __ctsvc_contact_destroy((contacts_record_h)contact, true);
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       contact->nicknames->l_type = CTSVC_RECORD_NICKNAME;
+
+       contact->profiles = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == contact->profiles) {
+               __ctsvc_contact_destroy((contacts_record_h)contact, true);
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       contact->profiles->l_type = CTSVC_RECORD_PROFILE;
+
+       contact->relationships = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == contact->relationships) {
+               __ctsvc_contact_destroy((contacts_record_h)contact, true);
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       contact->relationships->l_type = CTSVC_RECORD_RELATIONSHIP;
+
+       contact->images = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == contact->images) {
+               __ctsvc_contact_destroy((contacts_record_h)contact, true);
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       contact->images->l_type = CTSVC_RECORD_IMAGE;
+
+       contact->extensions = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == contact->extensions) {
+               __ctsvc_contact_destroy((contacts_record_h)contact, true);
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       contact->extensions->l_type = CTSVC_RECORD_EXTENSION;
+
+       *out_record = (contacts_record_h)contact;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_contact_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
+       contact->base.plugin_cbs = NULL;        // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(contact->base.properties_flags);
+
+       free(contact->display_name);
+       free(contact->reverse_display_name);
+       free(contact->uid);
+       free(contact->image_thumbnail_path);
+       free(contact->ringtone_path);
+       free(contact->vibration);
+       free(contact->message_alert);
+       free(contact->sort_name);
+       free(contact->reverse_sort_name);
+       free(contact->sortkey);
+       free(contact->reverse_sortkey);
+
+       contacts_list_destroy((contacts_list_h)contact->name, delete_child);
+
+       contacts_list_destroy((contacts_list_h)contact->company, delete_child);
+
+       contacts_list_destroy((contacts_list_h)contact->note, delete_child);
+
+       contacts_list_destroy((contacts_list_h)contact->numbers, delete_child);
+
+       contacts_list_destroy((contacts_list_h)contact->emails, delete_child);
+
+       contacts_list_destroy((contacts_list_h)contact->grouprelations, delete_child);
+
+       contacts_list_destroy((contacts_list_h)contact->events, delete_child);
+
+       contacts_list_destroy((contacts_list_h)contact->messengers, delete_child);
+
+       contacts_list_destroy((contacts_list_h)contact->postal_addrs, delete_child);
+
+       contacts_list_destroy((contacts_list_h)contact->urls, delete_child);
+
+       contacts_list_destroy((contacts_list_h)contact->nicknames, delete_child);
+
+       contacts_list_destroy((contacts_list_h)contact->profiles, delete_child);
+
+       contacts_list_destroy((contacts_list_h)contact->relationships, delete_child);
+
+       contacts_list_destroy((contacts_list_h)contact->images, delete_child);
+
+       contacts_list_destroy((contacts_list_h)contact->extensions, delete_child);
+       free(contact);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+
+static int __ctsvc_contact_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_contact_s *contact = (ctsvc_contact_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_CONTACT_ID:
+               *out = contact->id;
+               break;
+       case CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID:
+               *out = contact->display_source_type;
+               break;
+       case CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID:
+               *out = contact->addressbook_id;
+               break;
+       case CTSVC_PROPERTY_CONTACT_PERSON_ID:
+               *out = contact->person_id;
+               break;
+       case CTSVC_PROPERTY_CONTACT_CHANGED_TIME:
+               *out = contact->changed_time;
+               break;
+       case CTSVC_PROPERTY_CONTACT_LINK_MODE:
+               *out = contact->link_mode;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(contact)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_simple_contact_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_simple_contact_s *contact = (ctsvc_simple_contact_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_CONTACT_ID:
+               *out = contact->contact_id;
+               break;
+       case CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID:
+               *out = contact->display_source_type;
+               break;
+       case CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID:
+               *out = contact->addressbook_id;
+               break;
+       case CTSVC_PROPERTY_CONTACT_PERSON_ID:
+               *out = contact->person_id;
+               break;
+       case CTSVC_PROPERTY_CONTACT_CHANGED_TIME:
+               *out = contact->changed_time;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(simple contact)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_name_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_name_s *name = (ctsvc_name_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NAME_ID:
+               *out = name->id;
+               break;
+       case CTSVC_PROPERTY_NAME_CONTACT_ID:
+               *out = name->contact_id;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(name)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_company_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_company_s *company = (ctsvc_company_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_COMPANY_ID:
+               *out = company->id;
+               break;
+       case CTSVC_PROPERTY_COMPANY_CONTACT_ID:
+               *out = company->contact_id;
+               break;
+       case CTSVC_PROPERTY_COMPANY_TYPE:
+               *out = company->type;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(company)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_note_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_note_s *note = (ctsvc_note_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NOTE_ID:
+               *out = note->id;
+               break;
+       case CTSVC_PROPERTY_NOTE_CONTACT_ID:
+               *out = note->contact_id;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(note)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_number_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_number_s *number = (ctsvc_number_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NUMBER_ID:
+               *out = number->id;
+               break;
+       case CTSVC_PROPERTY_NUMBER_CONTACT_ID:
+               *out = number->contact_id;
+               break;
+       case CTSVC_PROPERTY_NUMBER_TYPE:
+               *out = number->type;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(number)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_email_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_email_s *email = (ctsvc_email_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_EMAIL_ID:
+               *out = email->id;
+               break;
+       case CTSVC_PROPERTY_EMAIL_CONTACT_ID:
+               *out = email->contact_id;
+               break;
+       case CTSVC_PROPERTY_EMAIL_TYPE:
+               *out = email->type;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(email)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_url_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_url_s *url = (ctsvc_url_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_URL_ID:
+               *out = url->id;
+               break;
+       case CTSVC_PROPERTY_URL_CONTACT_ID:
+               *out = url->contact_id;
+               break;
+       case CTSVC_PROPERTY_URL_TYPE:
+               *out = url->type;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(url)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_event_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_event_s *event = (ctsvc_event_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_EVENT_ID:
+               *out = event->id;
+               break;
+       case CTSVC_PROPERTY_EVENT_CONTACT_ID:
+               *out = event->contact_id;
+               break;
+       case CTSVC_PROPERTY_EVENT_TYPE:
+               *out = event->type;
+               break;
+       case CTSVC_PROPERTY_EVENT_DATE:
+               *out = event->date;
+               break;
+       case CTSVC_PROPERTY_EVENT_CALENDAR_TYPE:
+               *out = event->calendar_type;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(event)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_nickname_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_nickname_s *nickname = (ctsvc_nickname_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NICKNAME_ID:
+               *out = nickname->id;
+               break;
+       case CTSVC_PROPERTY_NICKNAME_CONTACT_ID:
+               *out = nickname->contact_id;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(nickname)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_address_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_address_s *address = (ctsvc_address_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ADDRESS_ID:
+               *out = address->id;
+               break;
+       case CTSVC_PROPERTY_ADDRESS_CONTACT_ID:
+               *out = address->contact_id;
+               break;
+       case CTSVC_PROPERTY_ADDRESS_TYPE:
+               *out = address->type;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(address)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_messenger_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_messenger_s *messenger = (ctsvc_messenger_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_MESSENGER_ID:
+               *out = messenger->id;
+               break;
+       case CTSVC_PROPERTY_MESSENGER_CONTACT_ID:
+               *out = messenger->contact_id;
+               break;
+       case CTSVC_PROPERTY_MESSENGER_TYPE:
+               *out = messenger->type;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(messenger)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_group_relation_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_group_relation_s *group = (ctsvc_group_relation_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_GROUP_RELATION_ID:
+               *out = group->id;
+               break;
+       case CTSVC_PROPERTY_GROUP_RELATION_CONTACT_ID:
+               *out = group->contact_id;
+               break;
+       case CTSVC_PROPERTY_GROUP_RELATION_GROUP_ID:
+               *out = group->group_id;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(group)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_activity_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_activity_s *activity = (ctsvc_activity_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ACTIVITY_ID:
+               *out = activity->id;
+               break;
+       case CTSVC_PROPERTY_ACTIVITY_CONTACT_ID:
+               *out = activity->contact_id;
+               break;
+       case CTSVC_PROPERTY_ACTIVITY_TIMESTAMP:
+               *out = activity->timestamp;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(activity)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_activity_add_child_record(contacts_record_h record,
+               unsigned int property_id, contacts_record_h child_record )
+{
+       ctsvc_activity_s *s_activity = (ctsvc_activity_s *)record;
+       ctsvc_activity_photo_s *s_activity_photo = (ctsvc_activity_photo_s *)child_record;
+
+       RETVM_IF(property_id != CTSVC_PROPERTY_ACTIVITY_ACTIVITY_PHOTO, CONTACTS_ERROR_INVALID_PARAMETER, "property_id(%d) is not supported", property_id);
+       RETVM_IF(s_activity_photo->base.r_type != CTSVC_RECORD_ACTIVITY_PHOTO, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter: r_type(%d) is wrong", s_activity_photo->base.r_type);
+       s_activity_photo->id = 0;
+
+       return ctsvc_list_add_child((contacts_list_h)s_activity->photos, child_record);
+}
+
+static int __ctsvc_activity_remove_child_record(contacts_record_h record,
+               unsigned int property_id, contacts_record_h child_record )
+{
+       ctsvc_activity_s *s_activity = (ctsvc_activity_s *)record;
+       ctsvc_activity_photo_s *s_activity_photo = (ctsvc_activity_photo_s *)child_record;
+
+       RETVM_IF(property_id != CTSVC_PROPERTY_ACTIVITY_ACTIVITY_PHOTO, CONTACTS_ERROR_INVALID_PARAMETER, "property_id(%d) is not supported", property_id);
+
+       ctsvc_list_remove_child((contacts_list_h)s_activity->photos, child_record, (s_activity_photo->id?true:false));
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_activity_get_child_record_count(contacts_record_h record,
+               unsigned int property_id, int *count )
+{
+       ctsvc_activity_s *s_activity = (ctsvc_activity_s *)record;
+       RETVM_IF(property_id != CTSVC_PROPERTY_ACTIVITY_ACTIVITY_PHOTO, CONTACTS_ERROR_INVALID_PARAMETER, "property_id(%d) is not supported", property_id);
+
+       if (s_activity->photos)
+               contacts_list_get_count((contacts_list_h)s_activity->photos, count);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_activity_get_child_record_at_p(contacts_record_h record,
+               unsigned int property_id, int index, contacts_record_h* out_record )
+{
+       int count = 0;
+       ctsvc_activity_s *s_activity = (ctsvc_activity_s *)record;
+
+       RETVM_IF(property_id != CTSVC_PROPERTY_ACTIVITY_ACTIVITY_PHOTO, CONTACTS_ERROR_INVALID_PARAMETER, "property_id(%d) is not supported", property_id);
+
+       if (s_activity->photos)
+               contacts_list_get_count((contacts_list_h)s_activity->photos, &count);
+
+       if (count < index) {
+               CTS_ERR("The index(%d) is greather than total length(%d)", index, count);
+               *out_record = NULL;
+               return CONTACTS_ERROR_NO_DATA;
+       }
+
+       return ctsvc_list_get_nth_record_p((contacts_list_h)s_activity->photos, index, out_record);
+}
+
+
+static int __ctsvc_activity_clone_child_record_list(contacts_record_h record,
+               unsigned int property_id, contacts_list_h* out_list )
+{
+       int count;
+       ctsvc_activity_s *s_activity = (ctsvc_activity_s *)record;
+
+       RETVM_IF(property_id != CTSVC_PROPERTY_ACTIVITY_ACTIVITY_PHOTO, CONTACTS_ERROR_INVALID_PARAMETER, "property_id(%d) is not supported", property_id);
+
+       contacts_list_get_count((contacts_list_h)s_activity->photos, &count);
+       if (count <= 0) {
+               *out_list = NULL;
+               return CONTACTS_ERROR_NO_DATA;
+       }
+       return ctsvc_list_clone((contacts_list_h)s_activity->photos, out_list);
+}
+
+
+static int __ctsvc_activity_photo_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_activity_photo_s *photo = (ctsvc_activity_photo_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ACTIVITY_PHOTO_ID:
+               *out = photo->id;
+               break;
+       case CTSVC_PROPERTY_ACTIVITY_PHOTO_ACTIVITY_ID:
+               *out = photo->activity_id;
+               break;
+       case CTSVC_PROPERTY_ACTIVITY_PHOTO_SORT_INDEX:
+               *out = photo->sort_index;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(activity)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_profile_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_profile_s *profile = (ctsvc_profile_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_PROFILE_ID:
+               *out = profile->id;
+               break;
+       case CTSVC_PROPERTY_PROFILE_CONTACT_ID:
+               *out = profile->contact_id;
+               break;
+       case CTSVC_PROPERTY_PROFILE_ORDER:
+               *out = profile->order;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(profile)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_relationship_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_relationship_s *relationship = (ctsvc_relationship_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_RELATIONSHIP_ID:
+               *out = relationship->id;
+               break;
+       case CTSVC_PROPERTY_RELATIONSHIP_CONTACT_ID:
+               *out = relationship->contact_id;
+               break;
+       case CTSVC_PROPERTY_RELATIONSHIP_TYPE:
+               *out = relationship->type;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(relationship)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_image_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_image_s *image = (ctsvc_image_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_IMAGE_ID:
+               *out = image->id;
+               break;
+       case CTSVC_PROPERTY_IMAGE_CONTACT_ID:
+               *out = image->contact_id;
+               break;
+       case CTSVC_PROPERTY_IMAGE_TYPE:
+               *out = image->type;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(image)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_extension_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_extension_s *extension = (ctsvc_extension_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_EXTENSION_ID:
+               *out = extension->id;
+               break;
+       case CTSVC_PROPERTY_EXTENSION_CONTACT_ID:
+               *out = extension->contact_id;
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA1:
+               *out = extension->data1;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(extension)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+
+static int __ctsvc_contact_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_contact_s *contact = (ctsvc_contact_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_CONTACT_ID:
+               contact->id = value;
+               break;
+       case CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID:
+               contact->display_source_type = value;
+               break;
+       case CTSVC_PROPERTY_CONTACT_PERSON_ID:
+               RETVM_IF(contact->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (contact)", property_id);
+               contact->person_id = value;
+               break;
+       case CTSVC_PROPERTY_CONTACT_CHANGED_TIME:
+               contact->changed_time = value;
+               break;
+       case CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID:
+               RETVM_IF(contact->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (contact)", property_id);
+               contact->addressbook_id = value;
+               break;
+       case CTSVC_PROPERTY_CONTACT_LINK_MODE:
+               RETVM_IF(value != CONTACTS_CONTACT_LINK_MODE_NONE
+                                               && value != CONTACTS_CONTACT_LINK_MODE_IGNORE_ONCE,
+                               CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : link mode is in invalid range (%d)", value);
+               RETVM_IF(contact->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (contact)", property_id);
+               contact->link_mode = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value (contact)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_simple_contact_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_simple_contact_s *contact = (ctsvc_simple_contact_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_CONTACT_ID:
+               contact->contact_id = value;
+               break;
+       case CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID:
+               contact->display_source_type = value;
+               break;
+       case CTSVC_PROPERTY_CONTACT_PERSON_ID:
+               contact->person_id = value;
+               break;
+       case CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID:
+               RETVM_IF(contact->contact_id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalide parameter : property_id(%d) is a read-only value (contact)", property_id);
+               contact->addressbook_id = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(simple contact)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_name_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_name_s *name = (ctsvc_name_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NAME_ID:
+               name->id = value;
+               break;
+       case CTSVC_PROPERTY_NAME_CONTACT_ID:
+               RETVM_IF(name->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (name)", property_id);
+               name->contact_id = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(name)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_company_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_company_s *company = (ctsvc_company_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_COMPANY_ID:
+               company->id = value;
+               break;
+       case CTSVC_PROPERTY_COMPANY_CONTACT_ID:
+               RETVM_IF(company->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (company)", property_id);
+               company->contact_id = value;
+               break;
+       case CTSVC_PROPERTY_COMPANY_TYPE:
+               RETVM_IF(value < CONTACTS_COMPANY_TYPE_OTHER
+                                               || value > CONTACTS_COMPANY_TYPE_WORK,
+                               CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : company type is in invalid range (%d)", value);
+
+               company->type = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(company)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_note_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_note_s *note = (ctsvc_note_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NOTE_ID:
+               note->id = value;
+               break;
+       case CTSVC_PROPERTY_NOTE_CONTACT_ID:
+               RETVM_IF(note->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (note)", property_id);
+               note->contact_id = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(note)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_number_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_number_s *number = (ctsvc_number_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NUMBER_ID:
+               number->id = value;
+               break;
+       case CTSVC_PROPERTY_NUMBER_CONTACT_ID:
+               RETVM_IF(number->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (number)", property_id);
+               number->contact_id = value;
+               break;
+       case CTSVC_PROPERTY_NUMBER_TYPE:
+               number->type = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(number)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_email_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_email_s *email = (ctsvc_email_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_EMAIL_ID:
+               email->id = value;
+               break;
+       case CTSVC_PROPERTY_EMAIL_CONTACT_ID:
+               RETVM_IF(email->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (email)", property_id);
+               email->contact_id = value;
+               break;
+       case CTSVC_PROPERTY_EMAIL_TYPE:
+               RETVM_IF(value < CONTACTS_EMAIL_TYPE_OTHER
+                                               || value > CONTACTS_EMAIL_TYPE_MOBILE,
+                               CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : email type is in invalid range (%d)", value);
+
+               email->type = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(email)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_url_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_url_s *url = (ctsvc_url_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_URL_ID:
+               url->id = value;
+               break;
+       case CTSVC_PROPERTY_URL_CONTACT_ID:
+               RETVM_IF(url->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (url)", property_id);
+               url->contact_id = value;
+               break;
+       case CTSVC_PROPERTY_URL_TYPE:
+               RETVM_IF(value < CONTACTS_URL_TYPE_OTHER
+                                               || value > CONTACTS_URL_TYPE_WORK ,
+                               CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : url type is in invalid range (%d)", value);
+
+               url->type = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(url)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_event_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_event_s *event = (ctsvc_event_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_EVENT_ID:
+               event->id = value;
+               break;
+       case CTSVC_PROPERTY_EVENT_CONTACT_ID:
+               RETVM_IF(event->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (event)", property_id);
+               event->contact_id = value;
+               break;
+       case CTSVC_PROPERTY_EVENT_TYPE:
+               RETVM_IF(value < CONTACTS_EVENT_TYPE_OTHER
+                                               || value > CONTACTS_EVENT_TYPE_ANNIVERSARY,
+                               CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : event type is in invalid range (%d)", value);
+               event->type = value;
+               break;
+       case CTSVC_PROPERTY_EVENT_DATE:
+               event->date = value;
+               break;
+       case CTSVC_PROPERTY_EVENT_CALENDAR_TYPE:
+               event->calendar_type = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(event)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_nickname_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_nickname_s *nickname = (ctsvc_nickname_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NICKNAME_ID:
+               nickname->id = value;
+               break;
+       case CTSVC_PROPERTY_NICKNAME_CONTACT_ID:
+               RETVM_IF(nickname->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (nickname)", property_id);
+               nickname->contact_id = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(nickname)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_address_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_address_s *address = (ctsvc_address_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ADDRESS_ID:
+               address->id = value;
+               break;
+       case CTSVC_PROPERTY_ADDRESS_CONTACT_ID:
+               RETVM_IF(address->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (address)", property_id);
+               address->contact_id = value;
+               break;
+       case CTSVC_PROPERTY_ADDRESS_TYPE:
+               RETVM_IF(value < CONTACTS_ADDRESS_TYPE_OTHER
+                                               || value > CONTACTS_ADDRESS_TYPE_PARCEL,
+                               CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : address type is %d", value);
+               address->type = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(address)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_messenger_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_messenger_s *messenger = (ctsvc_messenger_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_MESSENGER_ID:
+               messenger->id = value;
+               break;
+       case CTSVC_PROPERTY_MESSENGER_CONTACT_ID:
+               RETVM_IF(messenger->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (messenger)", property_id);
+               messenger->contact_id = value;
+               break;
+       case CTSVC_PROPERTY_MESSENGER_TYPE:
+               RETVM_IF(value < CONTACTS_MESSENGER_TYPE_OTHER
+                                                       || value > CONTACTS_MESSENGER_TYPE_IRC,
+                                       CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : messenger type is in invalid range (%d)", value);
+
+               messenger->type = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(messenger)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_group_relation_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_group_relation_s *group = (ctsvc_group_relation_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_GROUP_RELATION_ID:
+               group->id = value;
+               break;
+       case CTSVC_PROPERTY_GROUP_RELATION_CONTACT_ID:
+               RETVM_IF(group->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (group)", property_id);
+               group->contact_id = value;
+               break;
+       case CTSVC_PROPERTY_GROUP_RELATION_GROUP_ID:
+               RETVM_IF(group->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (group)", property_id);
+               group->group_id = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(group relation)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_activity_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_activity_s *activity = (ctsvc_activity_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ACTIVITY_ID:
+               activity->id = value;
+               break;
+       case CTSVC_PROPERTY_ACTIVITY_CONTACT_ID:
+               RETVM_IF(activity->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (activity)", property_id);
+               activity->contact_id = value;
+               break;
+       case CTSVC_PROPERTY_ACTIVITY_TIMESTAMP:
+               activity->timestamp = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(activity)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_activity_photo_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_activity_photo_s *photo = (ctsvc_activity_photo_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ACTIVITY_PHOTO_ID:
+               photo->id = value;
+               break;
+       case CTSVC_PROPERTY_ACTIVITY_PHOTO_ACTIVITY_ID:
+               photo->activity_id = value;
+               break;
+       case CTSVC_PROPERTY_ACTIVITY_PHOTO_SORT_INDEX:
+               photo->sort_index = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(activity)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_profile_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_profile_s *profile = (ctsvc_profile_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_PROFILE_ID:
+               profile->id = value;
+               break;
+       case CTSVC_PROPERTY_PROFILE_CONTACT_ID:
+               RETVM_IF(profile->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (profile)", property_id);
+               profile->contact_id = value;
+               break;
+       case CTSVC_PROPERTY_PROFILE_ORDER:
+               profile->order = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(profile)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_relationship_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_relationship_s *relationship = (ctsvc_relationship_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_RELATIONSHIP_ID:
+               relationship->id = value;
+               break;
+       case CTSVC_PROPERTY_RELATIONSHIP_CONTACT_ID:
+               RETVM_IF(relationship->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (relationship)", property_id);
+               relationship->contact_id = value;
+               break;
+       case CTSVC_PROPERTY_RELATIONSHIP_TYPE:
+               RETVM_IF(value < CONTACTS_RELATIONSHIP_TYPE_OTHER
+                                               || value > CONTACTS_RELATIONSHIP_TYPE_CUSTOM,
+                               CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : relationship type is in invalid range (%d)", value);
+
+               relationship->type = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(relationship)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_image_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_image_s *image = (ctsvc_image_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_IMAGE_ID:
+               image->id = value;
+               break;
+       case CTSVC_PROPERTY_IMAGE_CONTACT_ID:
+               RETVM_IF(image->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (image)", property_id);
+               image->contact_id = value;
+               break;
+       case CTSVC_PROPERTY_IMAGE_TYPE:
+               RETVM_IF(value < CONTACTS_IMAGE_TYPE_OTHER || CONTACTS_IMAGE_TYPE_CUSTOM < value,
+                               CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : image type is in invalid range (%d)", value);
+               image->type = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(image)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_extension_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_extension_s *extension = (ctsvc_extension_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_EXTENSION_ID:
+               extension->id = value;
+               break;
+       case CTSVC_PROPERTY_EXTENSION_CONTACT_ID:
+               RETVM_IF(extension->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (extension)", property_id);
+               extension->contact_id = value;
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA1:
+               extension->data1 = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(extension)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_contact_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
+       switch(property_id) {
+       case CTSVC_PROPERTY_CONTACT_DISPLAY_NAME:
+               *out_str = GET_STR(copy, contact->display_name);
+               break;
+       case CTSVC_PROPERTY_CONTACT_RINGTONE:
+               *out_str = GET_STR(copy, contact->ringtone_path);
+               break;
+       case CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL:
+               *out_str = GET_STR(copy, contact->image_thumbnail_path);
+               break;
+       case CTSVC_PROPERTY_CONTACT_UID:
+               *out_str = GET_STR(copy, contact->uid);
+               break;
+       case CTSVC_PROPERTY_CONTACT_VIBRATION:
+               *out_str = GET_STR(copy, contact->vibration);
+               break;
+       case CTSVC_PROPERTY_CONTACT_MESSAGE_ALERT:
+               *out_str = GET_STR(copy, contact->message_alert);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(contact)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_contact_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_contact_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_contact_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_contact_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_contact_get_record_list_p(contacts_record_h record,
+               unsigned int property_id, contacts_list_h *list)
+{
+       ctsvc_contact_s *contact = (ctsvc_contact_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_CONTACT_NAME:
+               *list = (contacts_list_h)contact->name;
+               break;
+       case CTSVC_PROPERTY_CONTACT_COMPANY:
+               *list = (contacts_list_h)contact->company;
+               break;
+       case CTSVC_PROPERTY_CONTACT_NOTE:
+               *list = (contacts_list_h)contact->note;
+               break;
+       case CTSVC_PROPERTY_CONTACT_NUMBER:
+               *list = (contacts_list_h)contact->numbers;
+               break;
+       case CTSVC_PROPERTY_CONTACT_EMAIL:
+               *list = (contacts_list_h)contact->emails;
+               break;
+       case CTSVC_PROPERTY_CONTACT_EVENT:
+               *list = (contacts_list_h)contact->events;
+               break;
+       case CTSVC_PROPERTY_CONTACT_MESSENGER:
+               *list = (contacts_list_h)contact->messengers;
+               break;
+       case CTSVC_PROPERTY_CONTACT_ADDRESS:
+               *list = (contacts_list_h)contact->postal_addrs;
+               break;
+       case CTSVC_PROPERTY_CONTACT_URL:
+               *list = (contacts_list_h)contact->urls;
+               break;
+       case CTSVC_PROPERTY_CONTACT_NICKNAME:
+               *list = (contacts_list_h)contact->nicknames;
+               break;
+       case CTSVC_PROPERTY_CONTACT_PROFILE:
+               *list = (contacts_list_h)contact->profiles;
+               break;
+       case CTSVC_PROPERTY_CONTACT_RELATIONSHIP:
+               *list = (contacts_list_h)contact->relationships;
+               break;
+       case CTSVC_PROPERTY_CONTACT_IMAGE:
+               *list = (contacts_list_h)contact->images;
+               break;
+       case CTSVC_PROPERTY_CONTACT_GROUP_RELATION:
+               *list = (contacts_list_h)contact->grouprelations;
+               break;
+       case CTSVC_PROPERTY_CONTACT_EXTENSION:
+               *list = (contacts_list_h)contact->extensions;
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(contact)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_contact_get_child_record_count(contacts_record_h record,
+               unsigned int property_id, int *count )
+{
+       int ret;
+       contacts_list_h list = NULL;
+
+       *count = 0;
+       ret = __ctsvc_contact_get_record_list_p(record, property_id, &list);
+       if (CONTACTS_ERROR_INVALID_PARAMETER == ret)
+               return ret;
+
+       if(list)
+               contacts_list_get_count(list, count);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_contact_get_child_record_at_p(contacts_record_h record,
+               unsigned int property_id, int index, contacts_record_h* out_record )
+{
+       int ret;
+       int count;
+       contacts_list_h list = NULL;
+
+       ret = __ctsvc_contact_get_record_list_p(record, property_id, &list);
+       if (CONTACTS_ERROR_INVALID_PARAMETER == ret)
+               return ret;
+
+       contacts_list_get_count(list, &count);
+       if (count < index) {
+               CTS_ERR("The index(%d) is greather than total length(%d)", index, count);
+               *out_record = NULL;
+               return CONTACTS_ERROR_NO_DATA;
+       }
+       else
+               return ctsvc_list_get_nth_record_p(list, index, out_record);
+}
+
+static int __ctsvc_contact_clone_child_record_list(contacts_record_h record,
+               unsigned int property_id, contacts_list_h* out_list )
+{
+       int ret;
+       int count;
+       contacts_list_h list = NULL;
+
+       ret = __ctsvc_contact_get_record_list_p(record, property_id, &list);
+       if (CONTACTS_ERROR_INVALID_PARAMETER == ret)
+               return ret;
+
+       contacts_list_get_count(list, &count);
+       if (count <= 0) {
+               *out_list = NULL;
+               return CONTACTS_ERROR_NO_DATA;
+       }
+       ctsvc_list_clone(list, out_list);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+
+static int __ctsvc_contact_reset_child_record_id(contacts_record_h child_record)
+{
+       ctsvc_record_s *record = (ctsvc_record_s*)child_record;
+
+       switch(record->r_type) {
+       case CTSVC_RECORD_NAME:
+               ((ctsvc_name_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_COMPANY:
+               ((ctsvc_company_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_NOTE:
+               ((ctsvc_note_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_NUMBER:
+               ((ctsvc_number_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_EMAIL:
+               ((ctsvc_email_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_URL:
+               ((ctsvc_url_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_EVENT:
+               ((ctsvc_event_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_NICKNAME:
+               ((ctsvc_nickname_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_ADDRESS:
+               ((ctsvc_address_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_MESSENGER:
+               ((ctsvc_messenger_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_GROUP_RELATION:
+               ((ctsvc_group_relation_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_ACTIVITY:
+               ((ctsvc_activity_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_PROFILE:
+               ((ctsvc_profile_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_RELATIONSHIP:
+               ((ctsvc_relationship_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_IMAGE:
+               ((ctsvc_image_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_EXTENSION:
+               ((ctsvc_extension_s *)record)->id = 0;
+               break;
+       default :
+               CTS_ERR("Invalid parameter : record(%d) is not child of contact", record->r_type);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_contact_get_child_record_id(contacts_record_h child_record)
+{
+       ctsvc_record_s *record = (ctsvc_record_s*)child_record;
+
+       switch(record->r_type) {
+       case CTSVC_RECORD_NAME:
+               return ((ctsvc_name_s *)record)->id;
+       case CTSVC_RECORD_COMPANY:
+               return ((ctsvc_company_s *)record)->id;
+       case CTSVC_RECORD_NOTE:
+               return ((ctsvc_note_s *)record)->id;
+       case CTSVC_RECORD_NUMBER:
+               return ((ctsvc_number_s *)record)->id;
+       case CTSVC_RECORD_EMAIL:
+               return ((ctsvc_email_s *)record)->id;
+       case CTSVC_RECORD_URL:
+               return ((ctsvc_url_s *)record)->id;
+       case CTSVC_RECORD_EVENT:
+               return ((ctsvc_event_s *)record)->id;
+       case CTSVC_RECORD_NICKNAME:
+               return ((ctsvc_nickname_s *)record)->id;
+       case CTSVC_RECORD_ADDRESS:
+               return ((ctsvc_address_s *)record)->id;
+       case CTSVC_RECORD_MESSENGER:
+               return ((ctsvc_messenger_s *)record)->id;
+       case CTSVC_RECORD_GROUP_RELATION:
+               return ((ctsvc_group_relation_s *)record)->id;
+       case CTSVC_RECORD_ACTIVITY:
+               return ((ctsvc_activity_s *)record)->id;
+       case CTSVC_RECORD_PROFILE:
+               return ((ctsvc_profile_s *)record)->id;
+       case CTSVC_RECORD_RELATIONSHIP:
+               return ((ctsvc_relationship_s *)record)->id;
+       case CTSVC_RECORD_IMAGE:
+               return ((ctsvc_image_s *)record)->id;
+       case CTSVC_RECORD_EXTENSION:
+               return ((ctsvc_extension_s *)record)->id;
+       default :
+               CTS_ERR("Invalid parameter : record(%d) is not child of contact", record->r_type);
+               return 0;
+       }
+       return 0;
+}
+
+static int __ctsvc_contact_add_child_record(contacts_record_h record,
+               unsigned int property_id, contacts_record_h child_record )
+{
+       int ret;
+       contacts_list_h list = NULL;
+       ctsvc_record_s *s_record = (ctsvc_record_s *)child_record;
+
+       ret = __ctsvc_contact_get_record_list_p(record, property_id, &list);
+       if (CONTACTS_ERROR_INVALID_PARAMETER == ret)
+               return ret;
+
+       if (CTSVC_RECORD_NAME == s_record->r_type && 1 == ((ctsvc_list_s *)list)->count) {
+               CTS_ERR("This type(%d) of child_record can not be added anymore", s_record->r_type);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = __ctsvc_contact_reset_child_record_id(child_record);
+       if (CONTACTS_ERROR_INVALID_PARAMETER == ret)
+               return ret;
+
+       ctsvc_list_add_child(list, child_record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_contact_remove_child_record(contacts_record_h record,
+               unsigned int property_id, contacts_record_h child_record )
+{
+       int id;
+       int ret;
+       contacts_list_h list = NULL;
+
+       ret = __ctsvc_contact_get_record_list_p(record, property_id, &list);
+       if (CONTACTS_ERROR_INVALID_PARAMETER == ret)
+               return ret;
+
+       id = __ctsvc_contact_get_child_record_id(child_record);
+       ctsvc_list_remove_child(list, child_record, (id?true:false));
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_simple_contact_get_str_real(contacts_record_h record,
+               unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_simple_contact_s *contact = (ctsvc_simple_contact_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_CONTACT_DISPLAY_NAME:
+               *out_str = GET_STR(copy, contact->display_name);
+               break;
+       case CTSVC_PROPERTY_CONTACT_RINGTONE:
+               *out_str = GET_STR(copy, contact->ringtone_path);
+               break;
+       case CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL:
+               *out_str = GET_STR(copy, contact->image_thumbnail_path);
+               break;
+       case CTSVC_PROPERTY_CONTACT_UID:
+               *out_str = GET_STR(copy, contact->uid);
+               break;
+       case CTSVC_PROPERTY_CONTACT_VIBRATION:
+               *out_str = GET_STR(copy, contact->vibration);
+               break;
+       case CTSVC_PROPERTY_CONTACT_MESSAGE_ALERT:
+               *out_str = GET_STR(copy, contact->message_alert);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(simple_contact)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_simple_contact_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_simple_contact_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_simple_contact_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_simple_contact_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_name_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_name_s *name = (ctsvc_name_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NAME_FIRST:
+               *out_str = GET_STR(copy, name->first);
+               break;
+       case CTSVC_PROPERTY_NAME_LAST:
+               *out_str = GET_STR(copy, name->last);
+               break;
+       case CTSVC_PROPERTY_NAME_ADDITION:
+               *out_str = GET_STR(copy, name->addition);
+               break;
+       case CTSVC_PROPERTY_NAME_SUFFIX:
+               *out_str = GET_STR(copy, name->suffix);
+               break;
+       case CTSVC_PROPERTY_NAME_PREFIX:
+               *out_str = GET_STR(copy, name->prefix);
+               break;
+       case CTSVC_PROPERTY_NAME_PHONETIC_FIRST:
+               *out_str = GET_STR(copy, name->phonetic_first);
+               break;
+       case CTSVC_PROPERTY_NAME_PHONETIC_MIDDLE:
+               *out_str = GET_STR(copy, name->phonetic_middle);
+               break;
+       case CTSVC_PROPERTY_NAME_PHONETIC_LAST:
+               *out_str = GET_STR(copy, name->phonetic_last);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(name)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_name_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_name_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_name_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_name_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_company_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_company_s *company = (ctsvc_company_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_COMPANY_LABEL:
+               *out_str = GET_STR(copy, company->label);
+               break;
+       case CTSVC_PROPERTY_COMPANY_NAME:
+               *out_str = GET_STR(copy, company->name);
+               break;
+       case CTSVC_PROPERTY_COMPANY_DEPARTMENT:
+               *out_str = GET_STR(copy, company->department);
+               break;
+       case CTSVC_PROPERTY_COMPANY_JOB_TITLE:
+               *out_str = GET_STR(copy, company->job_title);
+               break;
+       case CTSVC_PROPERTY_COMPANY_ASSISTANT_NAME:
+               *out_str = GET_STR(copy, company->assistant_name);
+               break;
+       case CTSVC_PROPERTY_COMPANY_ROLE:
+               *out_str = GET_STR(copy, company->role);
+               break;
+       case CTSVC_PROPERTY_COMPANY_LOGO:
+               *out_str = GET_STR(copy, company->logo);
+               break;
+       case CTSVC_PROPERTY_COMPANY_LOCATION:
+               *out_str = GET_STR(copy, company->location);
+               break;
+       case CTSVC_PROPERTY_COMPANY_DESCRIPTION:
+               *out_str = GET_STR(copy, company->description);
+               break;
+       case CTSVC_PROPERTY_COMPANY_PHONETIC_NAME:
+               *out_str = GET_STR(copy, company->phonetic_name);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(company)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_company_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_company_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_company_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_company_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_note_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_note_s *note = (ctsvc_note_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NOTE_NOTE:
+               *out_str = GET_STR(copy, note->note);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(note)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_note_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_note_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_note_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_note_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_number_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_number_s *number = (ctsvc_number_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NUMBER_LABEL:
+               *out_str = GET_STR(copy, number->label);
+               break;
+       case CTSVC_PROPERTY_NUMBER_NUMBER:
+               *out_str = GET_STR(copy, number->number);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(number)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_number_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_number_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_number_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_number_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_email_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_email_s *email = (ctsvc_email_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_EMAIL_EMAIL:
+               *out_str = GET_STR(copy, email->email_addr);
+               break;
+       case CTSVC_PROPERTY_EMAIL_LABEL:
+               *out_str = GET_STR(copy, email->label);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(email)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_email_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_email_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_email_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_email_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_url_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_url_s *url = (ctsvc_url_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_URL_URL:
+               *out_str = GET_STR(copy, url->url);
+               break;
+       case CTSVC_PROPERTY_URL_LABEL:
+               *out_str = GET_STR(copy, url->label);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(url)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_url_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_url_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_url_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_url_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_event_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_event_s *event = (ctsvc_event_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_EVENT_LABEL:
+               *out_str = GET_STR(copy, event->label);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(event)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_event_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_event_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_event_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_event_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_nickname_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_nickname_s *nickname = (ctsvc_nickname_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NICKNAME_NAME:
+               *out_str = GET_STR(copy, nickname->nickname);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(nickname)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_nickname_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_nickname_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_nickname_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_nickname_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_address_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_address_s *address = (ctsvc_address_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ADDRESS_LABEL:
+               *out_str = GET_STR(copy, address->label);
+               break;
+       case CTSVC_PROPERTY_ADDRESS_POSTBOX:
+               *out_str = GET_STR(copy, address->pobox);
+               break;
+       case CTSVC_PROPERTY_ADDRESS_POSTAL_CODE:
+               *out_str = GET_STR(copy, address->postalcode);
+               break;
+       case CTSVC_PROPERTY_ADDRESS_REGION:
+               *out_str = GET_STR(copy, address->region);
+               break;
+       case CTSVC_PROPERTY_ADDRESS_LOCALITY:
+               *out_str = GET_STR(copy, address->locality);
+               break;
+       case CTSVC_PROPERTY_ADDRESS_STREET:
+               *out_str = GET_STR(copy, address->street);
+               break;
+       case CTSVC_PROPERTY_ADDRESS_COUNTRY:
+               *out_str = GET_STR(copy, address->country);
+               break;
+       case CTSVC_PROPERTY_ADDRESS_EXTENDED:
+               *out_str = GET_STR(copy, address->extended);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(address)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_address_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_address_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_address_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_address_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_messenger_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_messenger_s *messenger = (ctsvc_messenger_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_MESSENGER_LABEL:
+               *out_str = GET_STR(copy, messenger->label);
+               break;
+       case CTSVC_PROPERTY_MESSENGER_IM_ID:
+               *out_str = GET_STR(copy, messenger->im_id);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(messenger)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_messenger_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_messenger_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_messenger_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_messenger_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_group_relation_get_str_real(contacts_record_h record,
+               unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_group_relation_s *group_relation = (ctsvc_group_relation_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_GROUP_RELATION_GROUP_NAME:
+               *out_str = GET_STR(copy, group_relation->group_name);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(group_relation)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_group_relation_get_str_p(contacts_record_h record,
+               unsigned int property_id, char** out_str)
+{
+       return __ctsvc_group_relation_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_group_relation_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_group_relation_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_activity_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_activity_s *activity = (ctsvc_activity_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ACTIVITY_SOURCE_NAME:
+               *out_str = GET_STR(copy, activity->source_name);
+               break;
+       case CTSVC_PROPERTY_ACTIVITY_STATUS:
+               *out_str = GET_STR(copy, activity->status);
+               break;
+       case CTSVC_PROPERTY_ACTIVITY_SERVICE_OPERATION:
+               *out_str = GET_STR(copy, activity->service_operation);
+               break;
+       case CTSVC_PROPERTY_ACTIVITY_URI:
+               *out_str = GET_STR(copy, activity->uri);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(activity)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_activity_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_activity_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_activity_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_activity_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_activity_photo_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_activity_photo_s *photo = (ctsvc_activity_photo_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ACTIVITY_PHOTO_URL:
+               *out_str = GET_STR(copy, photo->photo_url);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(activity)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_activity_photo_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_activity_photo_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_activity_photo_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_activity_photo_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_profile_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_profile_s *profile = (ctsvc_profile_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_PROFILE_UID:
+               *out_str = GET_STR(copy, profile->uid);
+               break;
+       case CTSVC_PROPERTY_PROFILE_TEXT:
+               *out_str = GET_STR(copy, profile->text);
+               break;
+       case CTSVC_PROPERTY_PROFILE_SERVICE_OPERATION:
+               *out_str = GET_STR(copy, profile->service_operation);
+               break;
+       case CTSVC_PROPERTY_PROFILE_MIME:
+               *out_str = GET_STR(copy, profile->mime);
+               break;
+       case CTSVC_PROPERTY_PROFILE_APP_ID:
+               *out_str = GET_STR(copy, profile->app_id);
+               break;
+       case CTSVC_PROPERTY_PROFILE_URI:
+               *out_str = GET_STR(copy, profile->uri);
+               break;
+       case CTSVC_PROPERTY_PROFILE_CATEGORY:
+               *out_str = GET_STR(copy, profile->category);
+               break;
+       case CTSVC_PROPERTY_PROFILE_EXTRA_DATA:
+               *out_str = GET_STR(copy, profile->extra_data);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(profile)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_profile_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_profile_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_profile_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_profile_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_relationship_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_relationship_s *relationship = (ctsvc_relationship_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_RELATIONSHIP_LABEL:
+               *out_str = GET_STR(copy, relationship->label);
+               break;
+       case CTSVC_PROPERTY_RELATIONSHIP_NAME:
+               *out_str = GET_STR(copy, relationship->name);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(relationship)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_relationship_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_relationship_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_relationship_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_relationship_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_image_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_image_s *image = (ctsvc_image_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_IMAGE_LABEL:
+               *out_str = GET_STR(copy, image->label);
+               break;
+       case CTSVC_PROPERTY_IMAGE_PATH:
+               *out_str = GET_STR(copy, image->path);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(image)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_image_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_image_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_image_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_image_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_extension_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_extension_s *extension = (ctsvc_extension_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_EXTENSION_DATA2:
+               *out_str = GET_STR(copy, extension->data2);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA3:
+               *out_str = GET_STR(copy, extension->data3);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA4:
+               *out_str = GET_STR(copy, extension->data4);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA5:
+               *out_str = GET_STR(copy, extension->data5);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA6:
+               *out_str = GET_STR(copy, extension->data6);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA7:
+               *out_str = GET_STR(copy, extension->data7);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA8:
+               *out_str = GET_STR(copy, extension->data8);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA9:
+               *out_str = GET_STR(copy, extension->data9);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA10:
+               *out_str = GET_STR(copy, extension->data10);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA11:
+               *out_str = GET_STR(copy, extension->data11);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA12:
+               *out_str = GET_STR(copy, extension->data12);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(extension)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_extension_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_extension_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_extension_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_extension_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_contact_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_contact_s *contact = (ctsvc_contact_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_CONTACT_DISPLAY_NAME:
+               FREEandSTRDUP(contact->display_name, str);
+               break;
+/*
+               CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (contact)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+*/
+       case CTSVC_PROPERTY_CONTACT_RINGTONE:
+               FREEandSTRDUP(contact->ringtone_path, str);
+               break;
+       case CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL:
+               FREEandSTRDUP(contact->image_thumbnail_path, str);
+               break;
+       case CTSVC_PROPERTY_CONTACT_UID:
+               FREEandSTRDUP(contact->uid, str);
+               break;
+       case CTSVC_PROPERTY_CONTACT_VIBRATION:
+               FREEandSTRDUP(contact->vibration, str);
+               break;
+       case CTSVC_PROPERTY_CONTACT_MESSAGE_ALERT:
+               FREEandSTRDUP(contact->message_alert, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(contact)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+
+static int __ctsvc_simple_contact_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_simple_contact_s *contact = (ctsvc_simple_contact_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_CONTACT_DISPLAY_NAME:
+               FREEandSTRDUP(contact->display_name, str);
+               break;
+/*
+               CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (contact)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+*/
+       case CTSVC_PROPERTY_CONTACT_RINGTONE:
+               FREEandSTRDUP(contact->ringtone_path, str);
+               break;
+       case CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL:
+               FREEandSTRDUP(contact->image_thumbnail_path, str);
+               break;
+       case CTSVC_PROPERTY_CONTACT_UID:
+               FREEandSTRDUP(contact->uid, str);
+               break;
+       case CTSVC_PROPERTY_CONTACT_VIBRATION:
+               FREEandSTRDUP(contact->vibration, str);
+               break;
+       case CTSVC_PROPERTY_CONTACT_MESSAGE_ALERT:
+               FREEandSTRDUP(contact->message_alert, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(simple_contact)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_name_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_name_s *name = (ctsvc_name_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NAME_FIRST:
+               FREEandSTRDUP(name->first, str);
+               break;
+       case CTSVC_PROPERTY_NAME_LAST:
+               FREEandSTRDUP(name->last, str);
+               break;
+       case CTSVC_PROPERTY_NAME_ADDITION:
+               FREEandSTRDUP(name->addition, str);
+               break;
+       case CTSVC_PROPERTY_NAME_SUFFIX:
+               FREEandSTRDUP(name->suffix, str);
+               break;
+       case CTSVC_PROPERTY_NAME_PREFIX:
+               FREEandSTRDUP(name->prefix, str);
+               break;
+       case CTSVC_PROPERTY_NAME_PHONETIC_FIRST:
+               FREEandSTRDUP(name->phonetic_first, str);
+               break;
+       case CTSVC_PROPERTY_NAME_PHONETIC_MIDDLE:
+               FREEandSTRDUP(name->phonetic_middle, str);
+               break;
+       case CTSVC_PROPERTY_NAME_PHONETIC_LAST:
+               FREEandSTRDUP(name->phonetic_last, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(name)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_company_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_company_s *company = (ctsvc_company_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_COMPANY_LABEL:
+               FREEandSTRDUP(company->label, str);
+               break;
+       case CTSVC_PROPERTY_COMPANY_NAME:
+               FREEandSTRDUP(company->name, str);
+               break;
+       case CTSVC_PROPERTY_COMPANY_DEPARTMENT:
+               FREEandSTRDUP(company->department, str);
+               break;
+       case CTSVC_PROPERTY_COMPANY_JOB_TITLE:
+               FREEandSTRDUP(company->job_title, str);
+               break;
+       case CTSVC_PROPERTY_COMPANY_ASSISTANT_NAME:
+               FREEandSTRDUP(company->assistant_name, str);
+               break;
+       case CTSVC_PROPERTY_COMPANY_ROLE:
+               FREEandSTRDUP(company->role, str);
+               break;
+       case CTSVC_PROPERTY_COMPANY_LOGO:
+               if (company->logo && company->is_vcard && (NULL == str || 0 != strcmp(company->logo, str))) {
+                       company->is_vcard = false;
+                       __ctsvc_temp_image_hash_table_remove(company->logo);
+               }
+               FREEandSTRDUP(company->logo, str);
+               break;
+       case CTSVC_PROPERTY_COMPANY_LOCATION:
+               FREEandSTRDUP(company->location, str);
+               break;
+       case CTSVC_PROPERTY_COMPANY_DESCRIPTION:
+               FREEandSTRDUP(company->description, str);
+               break;
+       case CTSVC_PROPERTY_COMPANY_PHONETIC_NAME:
+               FREEandSTRDUP(company->phonetic_name, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(company)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_note_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_note_s *note = (ctsvc_note_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NOTE_NOTE:
+               FREEandSTRDUP(note->note, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(note)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_number_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_number_s *number = (ctsvc_number_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NUMBER_LABEL:
+               FREEandSTRDUP(number->label, str);
+               break;
+       case CTSVC_PROPERTY_NUMBER_NUMBER:
+               FREEandSTRDUP(number->number, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(number)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_email_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_email_s *email = (ctsvc_email_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_EMAIL_EMAIL:
+               FREEandSTRDUP(email->email_addr, str);
+               break;
+       case CTSVC_PROPERTY_EMAIL_LABEL:
+               FREEandSTRDUP(email->label, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(email)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_url_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_url_s *url = (ctsvc_url_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_URL_URL:
+               FREEandSTRDUP(url->url, str);
+               break;
+       case CTSVC_PROPERTY_URL_LABEL:
+               FREEandSTRDUP(url->label, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(url)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_event_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_event_s *event = (ctsvc_event_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_EVENT_LABEL:
+               FREEandSTRDUP(event->label, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(event)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_nickname_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_nickname_s *nickname = (ctsvc_nickname_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NICKNAME_NAME:
+               FREEandSTRDUP(nickname->nickname, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(nickname)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_address_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_address_s *address = (ctsvc_address_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ADDRESS_LABEL:
+               FREEandSTRDUP(address->label, str);
+               break;
+       case CTSVC_PROPERTY_ADDRESS_POSTBOX:
+               FREEandSTRDUP(address->pobox, str);
+               break;
+       case CTSVC_PROPERTY_ADDRESS_POSTAL_CODE:
+               FREEandSTRDUP(address->postalcode, str);
+               break;
+       case CTSVC_PROPERTY_ADDRESS_REGION:
+               FREEandSTRDUP(address->region, str);
+               break;
+       case CTSVC_PROPERTY_ADDRESS_LOCALITY:
+               FREEandSTRDUP(address->locality, str);
+               break;
+       case CTSVC_PROPERTY_ADDRESS_STREET:
+               FREEandSTRDUP(address->street, str);
+               break;
+       case CTSVC_PROPERTY_ADDRESS_COUNTRY:
+               FREEandSTRDUP(address->country, str);
+               break;
+       case CTSVC_PROPERTY_ADDRESS_EXTENDED:
+               FREEandSTRDUP(address->extended, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(address)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_messenger_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_messenger_s *messenger = (ctsvc_messenger_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_MESSENGER_LABEL:
+               FREEandSTRDUP(messenger->label, str);
+               break;
+       case CTSVC_PROPERTY_MESSENGER_IM_ID:
+               FREEandSTRDUP(messenger->im_id, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(messenger)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_group_relation_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_group_relation_s *group_relation = (ctsvc_group_relation_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_GROUP_RELATION_GROUP_NAME:
+               FREEandSTRDUP(group_relation->group_name, str);
+               break;
+/*
+               CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (group_relation)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+*/
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(group_relation)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_activity_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_activity_s *activity = (ctsvc_activity_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ACTIVITY_SOURCE_NAME:
+               FREEandSTRDUP(activity->source_name, str);
+               break;
+       case CTSVC_PROPERTY_ACTIVITY_STATUS:
+               FREEandSTRDUP(activity->status, str);
+               break;
+       case CTSVC_PROPERTY_ACTIVITY_SERVICE_OPERATION:
+               FREEandSTRDUP(activity->service_operation, str);
+               break;
+       case CTSVC_PROPERTY_ACTIVITY_URI:
+               FREEandSTRDUP(activity->uri, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(activity)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_activity_photo_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_activity_photo_s *photo = (ctsvc_activity_photo_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ACTIVITY_PHOTO_URL:
+               FREEandSTRDUP(photo->photo_url, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(activity)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_profile_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_profile_s *profile = (ctsvc_profile_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_PROFILE_UID:
+               FREEandSTRDUP(profile->uid, str);
+               break;
+       case CTSVC_PROPERTY_PROFILE_TEXT:
+               FREEandSTRDUP(profile->text, str);
+               break;
+       case CTSVC_PROPERTY_PROFILE_SERVICE_OPERATION:
+               FREEandSTRDUP(profile->service_operation, str);
+               break;
+       case CTSVC_PROPERTY_PROFILE_MIME:
+               FREEandSTRDUP(profile->mime, str);
+               break;
+       case CTSVC_PROPERTY_PROFILE_APP_ID:
+               FREEandSTRDUP(profile->app_id, str);
+               break;
+       case CTSVC_PROPERTY_PROFILE_URI:
+               FREEandSTRDUP(profile->uri, str);
+               break;
+       case CTSVC_PROPERTY_PROFILE_CATEGORY:
+               FREEandSTRDUP(profile->category, str);
+               break;
+       case CTSVC_PROPERTY_PROFILE_EXTRA_DATA:
+               FREEandSTRDUP(profile->extra_data, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(profile)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_relationship_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_relationship_s *relationship = (ctsvc_relationship_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_RELATIONSHIP_LABEL:
+               FREEandSTRDUP(relationship->label, str);
+               break;
+       case CTSVC_PROPERTY_RELATIONSHIP_NAME:
+               FREEandSTRDUP(relationship->name, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(relationship)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_image_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_image_s *image = (ctsvc_image_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_IMAGE_LABEL:
+               FREEandSTRDUP(image->label, str);
+               break;
+       case CTSVC_PROPERTY_IMAGE_PATH:
+               if (image->path && image->is_vcard && (NULL == str || 0 != strcmp(image->path, str))) {
+                       image->is_vcard = false;
+                       __ctsvc_temp_image_hash_table_remove(image->path);
+               }
+               FREEandSTRDUP(image->path, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(image)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_extension_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_extension_s *extension = (ctsvc_extension_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_EXTENSION_DATA2:
+               FREEandSTRDUP(extension->data2, str);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA3:
+               FREEandSTRDUP(extension->data3, str);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA4:
+               FREEandSTRDUP(extension->data4, str);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA5:
+               FREEandSTRDUP(extension->data5, str);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA6:
+               FREEandSTRDUP(extension->data6, str);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA7:
+               FREEandSTRDUP(extension->data7, str);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA8:
+               FREEandSTRDUP(extension->data8, str);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA9:
+               FREEandSTRDUP(extension->data9, str);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA10:
+               FREEandSTRDUP(extension->data10, str);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA11:
+               FREEandSTRDUP(extension->data11, str);
+               break;
+       case CTSVC_PROPERTY_EXTENSION_DATA12:
+               FREEandSTRDUP(extension->data12, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(extension)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_contact_get_bool(contacts_record_h record, unsigned int property_id, bool *value )
+{
+       ctsvc_contact_s *contact = (ctsvc_contact_s *)record;
+       switch (property_id) {
+       case CTSVC_PROPERTY_CONTACT_IS_FAVORITE:
+               *value = contact->is_favorite;
+               break;
+       case CTSVC_PROPERTY_CONTACT_HAS_PHONENUMBER:
+               *value = contact->has_phonenumber;
+               break;
+       case CTSVC_PROPERTY_CONTACT_HAS_EMAIL:
+               *value = contact->has_email;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(0x%x) is not supported in value(contact)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_simple_contact_get_bool(contacts_record_h record, unsigned int property_id, bool *value )
+{
+       ctsvc_simple_contact_s *contact = (ctsvc_simple_contact_s *)record;
+       switch (property_id) {
+       case CTSVC_PROPERTY_CONTACT_IS_FAVORITE:
+               *value = contact->is_favorite;
+               break;
+       case CTSVC_PROPERTY_CONTACT_HAS_PHONENUMBER:
+               *value = contact->has_phonenumber;
+               break;
+       case CTSVC_PROPERTY_CONTACT_HAS_EMAIL:
+               *value = contact->has_email;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(0x%x) is not supported in value(contact)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+
+static int __ctsvc_number_get_bool(contacts_record_h record, unsigned int property_id, bool *value )
+{
+       ctsvc_number_s *number = (ctsvc_number_s*)record;
+       switch (property_id) {
+       case CTSVC_PROPERTY_NUMBER_IS_DEFAULT:
+               *value = number->is_default;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(0x%x) is not supported in value(number)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_email_get_bool(contacts_record_h record, unsigned int property_id, bool *value )
+{
+       ctsvc_email_s *email = (ctsvc_email_s *)record;
+       switch (property_id) {
+       case CTSVC_PROPERTY_EMAIL_IS_DEFAULT:
+               *value = email->is_default;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(0x%x) is not supported in value(email)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_event_get_bool(contacts_record_h record, unsigned int property_id, bool *value )
+{
+       ctsvc_event_s *event = (ctsvc_event_s *)record;
+       switch (property_id) {
+       case CTSVC_PROPERTY_EVENT_IS_LEAP_MONTH:
+               *value = event->is_leap_month;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(0x%x) is not supported in value(event)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_image_get_bool(contacts_record_h record, unsigned int property_id, bool *value )
+{
+       ctsvc_image_s *image = (ctsvc_image_s *)record;
+       switch (property_id) {
+       case CTSVC_PROPERTY_IMAGE_IS_DEFAULT:
+               *value = image->is_default;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(0x%x) is not supported in value(image)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_address_get_bool(contacts_record_h record, unsigned int property_id, bool *value )
+{
+       ctsvc_address_s *address = (ctsvc_address_s *)record;
+       switch (property_id) {
+       case CTSVC_PROPERTY_ADDRESS_IS_DEFAULT:
+               *value = address->is_default;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(0x%x) is not supported in value(address)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_contact_set_bool(contacts_record_h record, unsigned int property_id, bool value)
+{
+       ctsvc_contact_s *contact = (ctsvc_contact_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_CONTACT_IS_FAVORITE:
+               contact->is_favorite = value;
+               break;
+       case CTSVC_PROPERTY_CONTACT_HAS_PHONENUMBER:
+               contact->has_phonenumber = value;
+               break;
+       case CTSVC_PROPERTY_CONTACT_HAS_EMAIL:
+               contact->has_email = value;
+               break;
+/*
+               CTS_ERR("Invalid parameter : property_id(%d) is a read-only value(contact)", property_id);
+               break;
+*/
+       default:
+               CTS_ERR("Invalid parameter : property_id(0x%x) is not supported in value(contact)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_number_set_bool(contacts_record_h record, unsigned int property_id, bool value)
+{
+       ctsvc_number_s *number = (ctsvc_number_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_NUMBER_IS_DEFAULT:
+               number->is_default = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(number)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_email_set_bool(contacts_record_h record, unsigned int property_id, bool value)
+{
+       ctsvc_email_s *email = (ctsvc_email_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_EMAIL_IS_DEFAULT:
+               email->is_default = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(email)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_event_set_bool(contacts_record_h record, unsigned int property_id, bool value)
+{
+       ctsvc_event_s *event = (ctsvc_event_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_EVENT_IS_LEAP_MONTH:
+               event->is_leap_month = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(event)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_image_set_bool(contacts_record_h record, unsigned int property_id, bool value)
+{
+       ctsvc_image_s *image = (ctsvc_image_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_IMAGE_IS_DEFAULT:
+               image->is_default = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(0x%x) is not supported in value(image)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_address_set_bool(contacts_record_h record, unsigned int property_id, bool value)
+{
+       ctsvc_address_s *address = (ctsvc_address_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_ADDRESS_IS_DEFAULT:
+               address->is_default = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(address)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_contact_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_contact_s *out_data = NULL;
+       ctsvc_contact_s *src_data = NULL;
+
+       src_data = (ctsvc_contact_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_contact_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_contact_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->person_id = src_data->person_id;
+       out_data->addressbook_id = src_data->addressbook_id;
+       out_data->changed_time = src_data->changed_time;
+       out_data->changed_ver = src_data->changed_ver;
+       out_data->link_mode = src_data->link_mode;
+       out_data->display_source_type = src_data->display_source_type;
+       out_data->display_name_language = src_data->display_name_language;
+       out_data->reverse_display_name_language = src_data->reverse_display_name_language;
+       out_data->has_phonenumber = src_data->has_phonenumber;
+       out_data->has_email = src_data->has_email;
+       out_data->is_favorite = src_data->is_favorite;
+
+       out_data->display_name = SAFE_STRDUP(src_data->display_name);
+       out_data->reverse_display_name = SAFE_STRDUP(src_data->reverse_display_name);
+       out_data->uid = SAFE_STRDUP(src_data->uid);
+       out_data->ringtone_path = SAFE_STRDUP(src_data->ringtone_path);
+       out_data->vibration = SAFE_STRDUP(src_data->vibration);
+       out_data->message_alert = SAFE_STRDUP(src_data->message_alert);
+       out_data->image_thumbnail_path = SAFE_STRDUP(src_data->image_thumbnail_path);
+       out_data->sort_name = SAFE_STRDUP(src_data->sort_name);
+       out_data->reverse_sort_name = SAFE_STRDUP(src_data->reverse_sort_name);
+       out_data->sortkey = SAFE_STRDUP(src_data->sortkey);
+       out_data->reverse_sortkey = SAFE_STRDUP(src_data->reverse_sortkey);
+
+       ctsvc_list_clone((contacts_list_h)src_data->name, (contacts_list_h*)&out_data->name);
+       out_data->name->l_type = CTSVC_RECORD_NAME;
+
+       ctsvc_list_clone((contacts_list_h)src_data->company, (contacts_list_h*)&out_data->company);
+       out_data->company->l_type = CTSVC_RECORD_COMPANY;
+
+       ctsvc_list_clone((contacts_list_h)src_data->note, (contacts_list_h*)&out_data->note);
+       out_data->note->l_type = CTSVC_RECORD_NOTE;
+
+       ctsvc_list_clone((contacts_list_h)src_data->numbers, (contacts_list_h*)&out_data->numbers);
+       out_data->numbers->l_type = CTSVC_RECORD_NUMBER;
+
+       ctsvc_list_clone((contacts_list_h)src_data->emails, (contacts_list_h*)&out_data->emails);
+       out_data->emails->l_type = CTSVC_RECORD_EMAIL;
+
+       ctsvc_list_clone((contacts_list_h)src_data->grouprelations, (contacts_list_h*)&out_data->grouprelations);
+       out_data->grouprelations->l_type = CTSVC_RECORD_GROUP_RELATION;
+
+       ctsvc_list_clone((contacts_list_h)src_data->events, (contacts_list_h*)&out_data->events);
+       out_data->events->l_type = CTSVC_RECORD_EVENT;
+
+       ctsvc_list_clone((contacts_list_h)src_data->messengers, (contacts_list_h*)&out_data->messengers);
+       out_data->messengers->l_type = CTSVC_RECORD_MESSENGER;
+
+       ctsvc_list_clone((contacts_list_h)src_data->postal_addrs, (contacts_list_h*)&out_data->postal_addrs);
+       out_data->postal_addrs->l_type = CTSVC_RECORD_ADDRESS;
+
+       ctsvc_list_clone((contacts_list_h)src_data->urls, (contacts_list_h*)&out_data->urls);
+       out_data->urls->l_type = CTSVC_RECORD_URL;
+
+       ctsvc_list_clone((contacts_list_h)src_data->nicknames, (contacts_list_h*)&out_data->nicknames);
+       out_data->nicknames->l_type = CTSVC_RECORD_NICKNAME;
+
+       ctsvc_list_clone((contacts_list_h)src_data->profiles, (contacts_list_h*)&out_data->profiles);
+       out_data->profiles->l_type = CTSVC_RECORD_PROFILE;
+
+       ctsvc_list_clone((contacts_list_h)src_data->relationships, (contacts_list_h*)&out_data->relationships);
+       out_data->relationships->l_type = CTSVC_RECORD_RELATIONSHIP;
+
+       ctsvc_list_clone((contacts_list_h)src_data->images, (contacts_list_h*)&out_data->images);
+       out_data->images->l_type = CTSVC_RECORD_IMAGE;
+
+       ctsvc_list_clone((contacts_list_h)src_data->extensions, (contacts_list_h*)&out_data->extensions);
+       out_data->extensions->l_type = CTSVC_RECORD_EXTENSION;
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+
+static int __ctsvc_activity_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_activity_s *out_data = NULL;
+       ctsvc_activity_s *src_data = NULL;
+
+       src_data = (ctsvc_activity_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_activity_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_activity_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->contact_id = src_data->contact_id;
+       out_data->timestamp = src_data->timestamp;
+       out_data->source_name = SAFE_STRDUP(src_data->source_name);
+       out_data->status = SAFE_STRDUP(src_data->status);
+       out_data->service_operation = SAFE_STRDUP(src_data->service_operation);
+       out_data->uri = SAFE_STRDUP(src_data->uri);
+
+       ctsvc_list_clone((contacts_list_h)src_data->photos, (contacts_list_h*)&out_data->photos);
+       out_data->photos->l_type = CTSVC_RECORD_ACTIVITY_PHOTO;
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_activity_photo_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_activity_photo_s *out_data = NULL;
+       ctsvc_activity_photo_s *src_data = NULL;
+
+       src_data = (ctsvc_activity_photo_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_activity_photo_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_activity_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->activity_id = src_data->activity_id;
+       out_data->photo_url = SAFE_STRDUP(src_data->photo_url);
+       out_data->sort_index = src_data->sort_index;
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_address_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_address_s *out_data = NULL;
+       ctsvc_address_s *src_data = NULL;
+
+       src_data = (ctsvc_address_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_address_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_address_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->contact_id = src_data->contact_id;
+       out_data->type = src_data->type;
+       out_data->is_default = src_data->is_default;
+       out_data->label = SAFE_STRDUP(src_data->label);
+       out_data->pobox = SAFE_STRDUP(src_data->pobox);
+       out_data->postalcode = SAFE_STRDUP(src_data->postalcode);
+       out_data->region = SAFE_STRDUP(src_data->region);
+       out_data->locality = SAFE_STRDUP(src_data->locality);
+       out_data->street = SAFE_STRDUP(src_data->street);
+       out_data->extended = SAFE_STRDUP(src_data->extended);
+       out_data->country = SAFE_STRDUP(src_data->country);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_company_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_company_s *out_data = NULL;
+       ctsvc_company_s *src_data = NULL;
+
+       src_data = (ctsvc_company_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_company_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_company_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->contact_id = src_data->contact_id;
+       out_data->is_default = src_data->is_default;
+       out_data->type = src_data->type;
+       out_data->is_vcard = src_data->is_vcard;
+       out_data->label = SAFE_STRDUP(src_data->label);
+       out_data->name = SAFE_STRDUP(src_data->name);
+       out_data->department = SAFE_STRDUP(src_data->department);
+       out_data->job_title = SAFE_STRDUP(src_data->job_title);
+       out_data->role = SAFE_STRDUP(src_data->role);
+       out_data->assistant_name = SAFE_STRDUP(src_data->assistant_name);
+       if (src_data->logo && src_data->is_vcard)
+               __ctsvc_temp_image_hash_table_insert(src_data->logo);
+       out_data->logo = SAFE_STRDUP(src_data->logo);
+       out_data->location = SAFE_STRDUP(src_data->location);
+       out_data->description = SAFE_STRDUP(src_data->description);
+       out_data->phonetic_name = SAFE_STRDUP(src_data->phonetic_name);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_email_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_email_s *out_data = NULL;
+       ctsvc_email_s *src_data = NULL;
+
+       src_data = (ctsvc_email_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_email_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_email_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->is_default = src_data->is_default;
+       out_data->contact_id = src_data->contact_id;
+       out_data->type = src_data->type;
+       out_data->label = SAFE_STRDUP(src_data->label);
+       out_data->email_addr = SAFE_STRDUP(src_data->email_addr);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_event_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_event_s *out_data = NULL;
+       ctsvc_event_s *src_data = NULL;
+
+       src_data = (ctsvc_event_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_event_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_event_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->contact_id = src_data->contact_id;
+       out_data->type = src_data->type;
+       out_data->label = SAFE_STRDUP(src_data->label);
+       out_data->date = src_data->date;
+       out_data->calendar_type = src_data->calendar_type;
+       out_data->is_leap_month = src_data->is_leap_month;
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_extension_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_extension_s *out_data = NULL;
+       ctsvc_extension_s *src_data = NULL;
+
+       src_data = (ctsvc_extension_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_extension_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_extension_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->contact_id = src_data->contact_id;
+//     out_data->is_default = src_data->is_default;
+       out_data->data1 = src_data->data1;
+       out_data->data2 = SAFE_STRDUP(src_data->data2);
+       out_data->data3 = SAFE_STRDUP(src_data->data3);
+       out_data->data4 = SAFE_STRDUP(src_data->data4);
+       out_data->data5 = SAFE_STRDUP(src_data->data5);
+       out_data->data6 = SAFE_STRDUP(src_data->data6);
+       out_data->data7 = SAFE_STRDUP(src_data->data7);
+       out_data->data8 = SAFE_STRDUP(src_data->data8);
+       out_data->data9 = SAFE_STRDUP(src_data->data9);
+       out_data->data10 = SAFE_STRDUP(src_data->data10);
+       out_data->data11 = SAFE_STRDUP(src_data->data11);
+       out_data->data12 = SAFE_STRDUP(src_data->data12);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_group_relation_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_group_relation_s *out_data = NULL;
+       ctsvc_group_relation_s *src_data = NULL;
+
+       src_data = (ctsvc_group_relation_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_group_relation_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_group_relation_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->group_id = src_data->group_id;
+       out_data->contact_id = src_data->contact_id;
+       out_data->group_name = SAFE_STRDUP(src_data->group_name);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_messenger_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_messenger_s *out_data = NULL;
+       ctsvc_messenger_s *src_data = NULL;
+
+       src_data = (ctsvc_messenger_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_messenger_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_messenger_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->contact_id = src_data->contact_id;
+       out_data->type = src_data->type;
+       out_data->label = SAFE_STRDUP(src_data->label);
+       out_data->im_id = SAFE_STRDUP(src_data->im_id);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_name_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_name_s *out_data = NULL;
+       ctsvc_name_s *src_data = NULL;
+
+       src_data = (ctsvc_name_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_name_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_name_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->is_default = src_data->is_default;
+       out_data->id = src_data->id;
+       out_data->contact_id= src_data->contact_id;
+       out_data->language_type = src_data->language_type;
+       out_data->first = SAFE_STRDUP(src_data->first);
+       out_data->last = SAFE_STRDUP(src_data->last);
+       out_data->addition = SAFE_STRDUP(src_data->addition);
+       out_data->prefix = SAFE_STRDUP(src_data->prefix);
+       out_data->suffix = SAFE_STRDUP(src_data->suffix);
+       out_data->phonetic_first = SAFE_STRDUP(src_data->phonetic_first);
+       out_data->phonetic_middle = SAFE_STRDUP(src_data->phonetic_middle);
+       out_data->phonetic_last = SAFE_STRDUP(src_data->phonetic_last);
+       out_data->lookup = SAFE_STRDUP(src_data->lookup);
+       out_data->reverse_lookup = SAFE_STRDUP(src_data->reverse_lookup);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_nickname_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_nickname_s *out_data = NULL;
+       ctsvc_nickname_s *src_data = NULL;
+
+       src_data = (ctsvc_nickname_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_nickname_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_nickname_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->contact_id = src_data->contact_id;
+       out_data->type = src_data->type;
+       out_data->label = SAFE_STRDUP(src_data->label);
+       out_data->nickname = SAFE_STRDUP(src_data->nickname);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_note_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_note_s *out_data = NULL;
+       ctsvc_note_s *src_data = NULL;
+
+       src_data = (ctsvc_note_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_note_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_note_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->contact_id = src_data->contact_id;
+       out_data->note = SAFE_STRDUP(src_data->note);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_number_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_number_s *out_data = NULL;
+       ctsvc_number_s *src_data = NULL;
+
+       src_data = (ctsvc_number_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_number_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_number_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->is_default = src_data->is_default;
+       out_data->id = src_data->id;
+       out_data->contact_id = src_data->contact_id;
+       out_data->type = src_data->type;
+       out_data->label = SAFE_STRDUP(src_data->label);
+       out_data->number = SAFE_STRDUP(src_data->number);
+       out_data->lookup = SAFE_STRDUP(src_data->lookup);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_profile_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_profile_s *out_data = NULL;
+       ctsvc_profile_s *src_data = NULL;
+
+       src_data = (ctsvc_profile_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_profile_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_profile_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->contact_id = src_data->contact_id;
+       out_data->order = src_data->order;
+       out_data->uid = SAFE_STRDUP(src_data->uid);
+       out_data->text = SAFE_STRDUP(src_data->text);
+       out_data->service_operation = SAFE_STRDUP(src_data->service_operation);
+       out_data->mime = SAFE_STRDUP(src_data->mime);
+       out_data->app_id = SAFE_STRDUP(src_data->app_id);
+       out_data->uri = SAFE_STRDUP(src_data->uri);
+       out_data->category = SAFE_STRDUP(src_data->category);
+       out_data->extra_data = SAFE_STRDUP(src_data->extra_data);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_relationship_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_relationship_s *out_data = NULL;
+       ctsvc_relationship_s *src_data = NULL;
+
+       src_data = (ctsvc_relationship_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_relationship_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_relationship_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->contact_id = src_data->contact_id;
+       out_data->type = src_data->type;
+       out_data->label = SAFE_STRDUP(src_data->label);
+       out_data->name = SAFE_STRDUP(src_data->name);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_image_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_image_s *out_data = NULL;
+       ctsvc_image_s *src_data = NULL;
+
+       src_data = (ctsvc_image_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_image_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_image_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->is_default = src_data->is_default;
+       out_data->id = src_data->id;
+       out_data->contact_id = src_data->contact_id;
+       out_data->type = src_data->type;
+       out_data->is_vcard = src_data->is_vcard;
+       out_data->label = SAFE_STRDUP(src_data->label);
+       if (src_data->path && src_data->is_vcard)
+               __ctsvc_temp_image_hash_table_insert(src_data->path);
+       out_data->path = SAFE_STRDUP(src_data->path);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_simple_contact_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_simple_contact_s *out_data = NULL;
+       ctsvc_simple_contact_s *src_data = NULL;
+
+       src_data = (ctsvc_simple_contact_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_simple_contact_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_simple_contact_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->contact_id = src_data->contact_id;
+       out_data->person_id = src_data->person_id;
+       out_data->addressbook_id = src_data->addressbook_id;
+       out_data->changed_time = src_data->changed_time;
+       out_data->display_source_type = src_data->display_source_type;
+       out_data->has_phonenumber = src_data->has_phonenumber;
+       out_data->has_email = src_data->has_email;
+       out_data->is_favorite = src_data->is_favorite;
+
+       out_data->display_name = SAFE_STRDUP(src_data->display_name);
+       out_data->uid = SAFE_STRDUP(src_data->uid);
+       out_data->ringtone_path = SAFE_STRDUP(src_data->ringtone_path);
+       out_data->vibration = SAFE_STRDUP(src_data->vibration);
+       out_data->message_alert = SAFE_STRDUP(src_data->message_alert);
+       out_data->image_thumbnail_path = SAFE_STRDUP(src_data->image_thumbnail_path);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_url_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_url_s *out_data = NULL;
+       ctsvc_url_s *src_data = NULL;
+
+       src_data = (ctsvc_url_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_url_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_url_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->contact_id = src_data->contact_id;
+       out_data->type = src_data->type;
+       out_data->label = SAFE_STRDUP(src_data->label);
+       out_data->url = SAFE_STRDUP(src_data->url);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/common/ctsvc_record_group.c b/common/ctsvc_record_group.c
new file mode 100644 (file)
index 0000000..5405bb7
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_record.h"
+#include "ctsvc_view.h"
+
+static int __ctsvc_group_create(contacts_record_h *out_record);
+static int __ctsvc_group_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_group_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_group_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_group_get_str(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_group_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_group_get_bool( contacts_record_h record, unsigned int property_id, bool *value );
+static int __ctsvc_group_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_group_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+static int __ctsvc_group_set_bool(contacts_record_h record, unsigned int property_id, bool value);
+
+
+ctsvc_record_plugin_cb_s group_plugin_cbs = {
+       .create = __ctsvc_group_create,
+       .destroy = __ctsvc_group_destroy,
+       .clone = __ctsvc_group_clone,
+       .get_str = __ctsvc_group_get_str,
+       .get_str_p = __ctsvc_group_get_str_p,
+       .get_int = __ctsvc_group_get_int,
+       .get_bool = __ctsvc_group_get_bool,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_group_set_str,
+       .set_int = __ctsvc_group_set_int,
+       .set_bool = __ctsvc_group_set_bool,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+static int __ctsvc_group_create(contacts_record_h *out_record)
+{
+       ctsvc_group_s *group;
+
+       group = (ctsvc_group_s*)calloc(1, sizeof(ctsvc_group_s));
+       RETVM_IF(NULL == group, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "calloc is failed");
+
+       *out_record = (contacts_record_h)group;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_group_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_group_s *group = (ctsvc_group_s*)record;
+       group->base.plugin_cbs = NULL;  // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(group->base.properties_flags);
+
+       free(group->name);
+       free(group->ringtone_path);
+       free(group->vibration);
+       free(group->message_alert);
+       free(group->image_thumbnail_path);
+       free(group->extra_data);
+       free(group);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_group_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+    ctsvc_group_s *out_data = NULL;
+    ctsvc_group_s *src_data = NULL;
+
+    src_data = (ctsvc_group_s*)record;
+    out_data = calloc(1, sizeof(ctsvc_group_s));
+    RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                        "Out of memeory : calloc(ctsvc_group_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->addressbook_id = src_data->addressbook_id;
+       out_data->is_read_only = src_data->is_read_only;
+       out_data->name = SAFE_STRDUP(src_data->name);
+       out_data->extra_data = SAFE_STRDUP(src_data->extra_data);
+       out_data->vibration = SAFE_STRDUP(src_data->vibration);
+       out_data->message_alert = SAFE_STRDUP(src_data->message_alert);
+       out_data->ringtone_path = SAFE_STRDUP(src_data->ringtone_path);
+       out_data->image_thumbnail_path = SAFE_STRDUP(src_data->image_thumbnail_path);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_group_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_group_s *group = (ctsvc_group_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_GROUP_ID:
+               *out = group->id;
+               break;
+       case CTSVC_PROPERTY_GROUP_ADDRESSBOOK_ID:
+               *out = group->addressbook_id;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(group)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_group_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_group_s *group = (ctsvc_group_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_GROUP_NAME:
+               *out_str = GET_STR(copy, group->name);
+               break;
+       case CTSVC_PROPERTY_GROUP_RINGTONE:
+               *out_str = GET_STR(copy, group->ringtone_path);
+               break;
+       case CTSVC_PROPERTY_GROUP_IMAGE:
+               *out_str = GET_STR(copy, group->image_thumbnail_path);
+               break;
+       case CTSVC_PROPERTY_GROUP_VIBRATION:
+               *out_str = GET_STR(copy, group->vibration);
+               break;
+       case CTSVC_PROPERTY_GROUP_MESSAGE_ALERT:
+               *out_str = GET_STR(copy, group->message_alert);
+               break;
+       case CTSVC_PROPERTY_GROUP_EXTRA_DATA:
+               *out_str = GET_STR(copy, group->extra_data);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(group)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_group_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_group_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_group_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_group_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_group_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_group_s *group = (ctsvc_group_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_GROUP_ID:
+               group->id = value;
+               break;
+       case CTSVC_PROPERTY_GROUP_ADDRESSBOOK_ID:
+               RETVM_IF(group->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (group)", property_id);
+               group->addressbook_id = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(group)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_group_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_group_s *group = (ctsvc_group_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_GROUP_NAME:
+               FREEandSTRDUP(group->name, str);
+               break;
+       case CTSVC_PROPERTY_GROUP_RINGTONE:
+               FREEandSTRDUP(group->ringtone_path, str);
+               break;
+       case CTSVC_PROPERTY_GROUP_IMAGE:
+               FREEandSTRDUP(group->image_thumbnail_path, str);
+               break;
+       case CTSVC_PROPERTY_GROUP_VIBRATION:
+               FREEandSTRDUP(group->vibration, str);
+               break;
+       case CTSVC_PROPERTY_GROUP_MESSAGE_ALERT:
+               FREEandSTRDUP(group->message_alert, str);
+               break;
+       case CTSVC_PROPERTY_GROUP_EXTRA_DATA:
+               FREEandSTRDUP(group->extra_data, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(group)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_group_get_bool(contacts_record_h record, unsigned int property_id, bool *value )
+{
+       ctsvc_group_s *group = (ctsvc_group_s*)record;
+       switch (property_id) {
+       case CTSVC_PROPERTY_GROUP_IS_READ_ONLY:
+               *value = group->is_read_only;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(group)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_group_set_bool(contacts_record_h record, unsigned int property_id, bool value)
+{
+       ctsvc_group_s *group = (ctsvc_group_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_GROUP_IS_READ_ONLY:
+               RETVM_IF(group->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (group)", property_id);
+               group->is_read_only = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(group)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/common/ctsvc_record_my_profile.c b/common/ctsvc_record_my_profile.c
new file mode 100644 (file)
index 0000000..8f926b8
--- /dev/null
@@ -0,0 +1,667 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_list.h"
+#include "ctsvc_record.h"
+#include "ctsvc_view.h"
+
+static int __ctsvc_my_profile_create(contacts_record_h *out_record);
+static int __ctsvc_my_profile_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_my_profile_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_my_profile_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_my_profile_get_str(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_my_profile_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_my_profile_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_my_profile_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+static int __ctsvc_my_profile_clone_child_record_list(contacts_record_h record, unsigned int property_id, contacts_list_h* out_list );
+static int __ctsvc_my_profile_get_child_record_at_p(contacts_record_h record, unsigned int property_id, int index, contacts_record_h* out_record );
+static int __ctsvc_my_profile_get_child_record_count(contacts_record_h record, unsigned int property_id, int *count );
+static int __ctsvc_my_profile_add_child_record(contacts_record_h record, unsigned int property_id, contacts_record_h child_record );
+static int __ctsvc_my_profile_remove_child_record(contacts_record_h record, unsigned int property_id, contacts_record_h child_record );
+
+ctsvc_record_plugin_cb_s my_profile_plugin_cbs = {
+       .create = __ctsvc_my_profile_create,
+       .destroy = __ctsvc_my_profile_destroy,
+       .clone = __ctsvc_my_profile_clone,
+       .get_str = __ctsvc_my_profile_get_str,
+       .get_str_p = __ctsvc_my_profile_get_str_p,
+       .get_int = __ctsvc_my_profile_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_my_profile_set_str,
+       .set_int = __ctsvc_my_profile_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = __ctsvc_my_profile_add_child_record,
+       .remove_child_record = __ctsvc_my_profile_remove_child_record,
+       .get_child_record_count = __ctsvc_my_profile_get_child_record_count,
+       .get_child_record_at_p = __ctsvc_my_profile_get_child_record_at_p,
+       .clone_child_record_list = __ctsvc_my_profile_clone_child_record_list,
+};
+
+static int __ctsvc_my_profile_create(contacts_record_h *out_record)
+{
+       ctsvc_my_profile_s *my_profile;
+
+       my_profile = calloc(1, sizeof(ctsvc_my_profile_s));
+       RETVM_IF(NULL == my_profile, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       my_profile->name = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == my_profile->name) {
+               CTS_ERR("calloc() return NULL");
+               __ctsvc_my_profile_destroy((contacts_record_h)my_profile, true);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       my_profile->name->l_type = CTSVC_RECORD_NAME;
+
+       my_profile->company = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == my_profile->company) {
+               CTS_ERR("calloc() return NULL");
+               __ctsvc_my_profile_destroy((contacts_record_h)my_profile, true);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       my_profile->company->l_type = CTSVC_RECORD_COMPANY;
+
+       my_profile->note = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == my_profile->note) {
+               CTS_ERR("calloc() return NULL");
+               __ctsvc_my_profile_destroy((contacts_record_h)my_profile, true);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       my_profile->note->l_type = CTSVC_RECORD_NOTE;
+
+       my_profile->numbers = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == my_profile->numbers) {
+               CTS_ERR("calloc() return NULL");
+               __ctsvc_my_profile_destroy((contacts_record_h)my_profile, true);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       my_profile->numbers->l_type = CTSVC_RECORD_NUMBER;
+
+       my_profile->emails = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == my_profile->emails) {
+               CTS_ERR("calloc() return NULL");
+               __ctsvc_my_profile_destroy((contacts_record_h)my_profile, true);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       my_profile->emails->l_type = CTSVC_RECORD_EMAIL;
+
+       my_profile->events = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == my_profile->events) {
+               CTS_ERR("calloc() return NULL");
+               __ctsvc_my_profile_destroy((contacts_record_h)my_profile, true);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       my_profile->events->l_type = CTSVC_RECORD_EVENT;
+
+       my_profile->messengers = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == my_profile->messengers) {
+               CTS_ERR("calloc() return NULL");
+               __ctsvc_my_profile_destroy((contacts_record_h)my_profile, true);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       my_profile->messengers->l_type = CTSVC_RECORD_MESSENGER;
+
+       my_profile->postal_addrs = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == my_profile->postal_addrs) {
+               CTS_ERR("calloc() return NULL");
+               __ctsvc_my_profile_destroy((contacts_record_h)my_profile, true);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       my_profile->postal_addrs->l_type = CTSVC_RECORD_ADDRESS;
+
+       my_profile->urls = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == my_profile->urls) {
+               CTS_ERR("calloc() return NULL");
+               __ctsvc_my_profile_destroy((contacts_record_h)my_profile, true);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       my_profile->urls->l_type = CTSVC_RECORD_URL;
+
+       my_profile->nicknames = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == my_profile->nicknames) {
+               CTS_ERR("calloc() return NULL");
+               __ctsvc_my_profile_destroy((contacts_record_h)my_profile, true);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       my_profile->nicknames->l_type = CTSVC_RECORD_NICKNAME;
+
+       my_profile->profiles = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == my_profile->profiles) {
+               CTS_ERR("calloc() return NULL");
+               __ctsvc_my_profile_destroy((contacts_record_h)my_profile, true);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       my_profile->profiles->l_type = CTSVC_RECORD_PROFILE;
+
+       my_profile->relationships = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == my_profile->relationships) {
+               CTS_ERR("calloc() return NULL");
+               __ctsvc_my_profile_destroy((contacts_record_h)my_profile, true);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       my_profile->relationships->l_type = CTSVC_RECORD_RELATIONSHIP;
+
+       my_profile->images = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == my_profile->images) {
+               CTS_ERR("calloc() return NULL");
+               __ctsvc_my_profile_destroy((contacts_record_h)my_profile, true);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       my_profile->images->l_type = CTSVC_RECORD_IMAGE;
+
+       my_profile->extensions = calloc(1, sizeof(ctsvc_list_s));
+       if (NULL == my_profile->extensions) {
+               CTS_ERR("calloc() return NULL");
+               __ctsvc_my_profile_destroy((contacts_record_h)my_profile, true);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       my_profile->extensions->l_type = CTSVC_RECORD_EXTENSION;
+
+       *out_record = (contacts_record_h)my_profile;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_my_profile_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_my_profile_s *my_profile = (ctsvc_my_profile_s*)record;
+       my_profile->base.plugin_cbs = NULL;     // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(my_profile->base.properties_flags);
+
+       free(my_profile->display_name);
+       free(my_profile->reverse_display_name);
+       free(my_profile->uid);
+       free(my_profile->image_thumbnail_path);
+
+       contacts_list_destroy((contacts_list_h)my_profile->name, delete_child);
+
+       contacts_list_destroy((contacts_list_h)my_profile->company, delete_child);
+
+       contacts_list_destroy((contacts_list_h)my_profile->note, delete_child);
+
+       contacts_list_destroy((contacts_list_h)my_profile->numbers, delete_child);
+
+       contacts_list_destroy((contacts_list_h)my_profile->emails, delete_child);
+
+       contacts_list_destroy((contacts_list_h)my_profile->events, delete_child);
+
+       contacts_list_destroy((contacts_list_h)my_profile->messengers, delete_child);
+
+       contacts_list_destroy((contacts_list_h)my_profile->postal_addrs, delete_child);
+
+       contacts_list_destroy((contacts_list_h)my_profile->urls, delete_child);
+
+       contacts_list_destroy((contacts_list_h)my_profile->nicknames, delete_child);
+
+       contacts_list_destroy((contacts_list_h)my_profile->profiles, delete_child);
+
+       contacts_list_destroy((contacts_list_h)my_profile->relationships, delete_child);
+
+       contacts_list_destroy((contacts_list_h)my_profile->images, delete_child);
+
+       contacts_list_destroy((contacts_list_h)my_profile->extensions, delete_child);
+
+       free(my_profile);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_my_profile_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_my_profile_s *my_profile = (ctsvc_my_profile_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_MY_PROFILE_ID:
+               *out = my_profile->id;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_ADDRESSBOOK_ID:
+               *out = my_profile->addressbook_id;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_CHANGED_TIME:
+               *out = my_profile->changed_time;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(my_profile)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_my_profile_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_my_profile_s *my_profile = (ctsvc_my_profile_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_MY_PROFILE_ID:
+               my_profile->id = value;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_CHANGED_TIME:
+               my_profile->changed_time = value;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_ADDRESSBOOK_ID:
+               RETVM_IF(my_profile->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (my_profile)", property_id);
+               my_profile->addressbook_id = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in valuecontact)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_my_profile_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_my_profile_s *my_profile = (ctsvc_my_profile_s*)record;
+       switch(property_id) {
+       case CTSVC_PROPERTY_MY_PROFILE_DISPLAY_NAME:
+               *out_str = GET_STR(copy, my_profile->display_name);
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_IMAGE_THUMBNAIL:
+               *out_str = GET_STR(copy, my_profile->image_thumbnail_path);
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_UID:
+               *out_str = GET_STR(copy, my_profile->uid);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(my_profile)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_my_profile_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_my_profile_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_my_profile_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_my_profile_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_my_profile_get_record_list_p(contacts_record_h record,
+               unsigned int property_id, contacts_list_h *list)
+{
+       ctsvc_my_profile_s *contact = (ctsvc_my_profile_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_MY_PROFILE_NAME:
+               *list = (contacts_list_h)contact->name;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_COMPANY:
+               *list = (contacts_list_h)contact->company;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_NOTE:
+               *list = (contacts_list_h)contact->note;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_NUMBER:
+               *list = (contacts_list_h)contact->numbers;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_EMAIL:
+               *list = (contacts_list_h)contact->emails;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_EVENT:
+               *list = (contacts_list_h)contact->events;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_MESSENGER:
+               *list = (contacts_list_h)contact->messengers;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_ADDRESS:
+               *list = (contacts_list_h)contact->postal_addrs;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_URL:
+               *list = (contacts_list_h)contact->urls;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_NICKNAME:
+               *list = (contacts_list_h)contact->nicknames;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_PROFILE:
+               *list = (contacts_list_h)contact->profiles;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_RELATIONSHIP:
+               *list = (contacts_list_h)contact->relationships;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_IMAGE:
+               *list = (contacts_list_h)contact->images;
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_EXTENSION:
+               *list = (contacts_list_h)contact->extensions;
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(contact)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_my_profile_get_child_record_count(contacts_record_h record,
+               unsigned int property_id, int *count )
+{
+       int ret;
+       contacts_list_h list = NULL;
+
+       *count = 0;
+       ret = __ctsvc_my_profile_get_record_list_p(record, property_id, &list);
+       if (CONTACTS_ERROR_INVALID_PARAMETER == ret)
+               return ret;
+
+       if(list)
+               contacts_list_get_count(list, count);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_my_profile_get_child_record_at_p(contacts_record_h record,
+               unsigned int property_id, int index, contacts_record_h* out_record )
+{
+       int ret;
+       int count;
+       contacts_list_h list = NULL;
+
+       ret = __ctsvc_my_profile_get_record_list_p(record, property_id, &list);
+       if (CONTACTS_ERROR_INVALID_PARAMETER == ret)
+               return ret;
+
+       contacts_list_get_count(list, &count);
+       if (count < index) {
+               CTS_ERR("The index(%d) is greather than total length(%d)", index, count);
+               *out_record = NULL;
+               return CONTACTS_ERROR_NO_DATA;
+       }
+       else
+               return ctsvc_list_get_nth_record_p(list, index, out_record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_my_profile_clone_child_record_list(contacts_record_h record,
+               unsigned int property_id, contacts_list_h* out_list )
+{
+       int ret;
+       int count;
+       contacts_list_h list = NULL;
+
+       ret = __ctsvc_my_profile_get_record_list_p(record, property_id, &list);
+       if (CONTACTS_ERROR_INVALID_PARAMETER == ret)
+               return ret;
+
+       contacts_list_get_count(list, &count);
+       if (count <= 0) {
+               *out_list = NULL;
+               return CONTACTS_ERROR_NO_DATA;
+       }
+       ctsvc_list_clone(list, out_list);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_my_profile_reset_child_record_id(contacts_record_h child_record)
+{
+       ctsvc_record_s *record = (ctsvc_record_s*)child_record;
+
+       switch(record->r_type) {
+       case CTSVC_RECORD_NAME:
+               ((ctsvc_name_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_COMPANY:
+               ((ctsvc_company_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_NOTE:
+               ((ctsvc_note_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_NUMBER:
+               ((ctsvc_number_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_EMAIL:
+               ((ctsvc_email_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_URL:
+               ((ctsvc_url_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_EVENT:
+               ((ctsvc_event_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_NICKNAME:
+               ((ctsvc_nickname_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_ADDRESS:
+               ((ctsvc_address_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_MESSENGER:
+               ((ctsvc_messenger_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_GROUP_RELATION:
+               ((ctsvc_group_relation_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_ACTIVITY:
+               ((ctsvc_activity_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_PROFILE:
+               ((ctsvc_profile_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_RELATIONSHIP:
+               ((ctsvc_relationship_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_IMAGE:
+               ((ctsvc_image_s *)record)->id = 0;
+               break;
+       case CTSVC_RECORD_EXTENSION:
+               ((ctsvc_extension_s *)record)->id = 0;
+               break;
+       default :
+               CTS_ERR("Invalid parameter : record(%d) is not child of contact", record->r_type);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+
+static int __ctsvc_my_profile_add_child_record(contacts_record_h record,
+               unsigned int property_id, contacts_record_h child_record )
+{
+       int ret;
+       contacts_list_h list = NULL;
+       ctsvc_record_s *s_record = (ctsvc_record_s *)child_record;
+
+       ret = __ctsvc_my_profile_get_record_list_p(record, property_id, &list);
+       if (CONTACTS_ERROR_INVALID_PARAMETER == ret)
+               return ret;
+
+       if (CTSVC_RECORD_NAME == s_record->r_type && 1 == ((ctsvc_list_s *)list)->count) {
+               CTS_ERR("This type(%d) of child_record can not be added anymore", s_record->r_type);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (CTSVC_RECORD_IMAGE == s_record->r_type && 1 == ((ctsvc_list_s *)list)->count) {
+               CTS_ERR("This type(%d) of child_record can not be added anymore", s_record->r_type);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = __ctsvc_my_profile_reset_child_record_id(child_record);
+       if (CONTACTS_ERROR_INVALID_PARAMETER == ret)
+               return ret;
+
+       ctsvc_list_add_child(list, child_record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_my_profile_get_child_record_id(contacts_record_h child_record)
+{
+       ctsvc_record_s *record = (ctsvc_record_s*)child_record;
+
+       switch(record->r_type) {
+       case CTSVC_RECORD_NAME:
+               return ((ctsvc_name_s *)record)->id;
+       case CTSVC_RECORD_COMPANY:
+               return ((ctsvc_company_s *)record)->id;
+       case CTSVC_RECORD_NOTE:
+               return ((ctsvc_note_s *)record)->id;
+       case CTSVC_RECORD_NUMBER:
+               return ((ctsvc_number_s *)record)->id;
+       case CTSVC_RECORD_EMAIL:
+               return ((ctsvc_email_s *)record)->id;
+       case CTSVC_RECORD_URL:
+               return ((ctsvc_url_s *)record)->id;
+       case CTSVC_RECORD_EVENT:
+               return ((ctsvc_event_s *)record)->id;
+       case CTSVC_RECORD_NICKNAME:
+               return ((ctsvc_nickname_s *)record)->id;
+       case CTSVC_RECORD_ADDRESS:
+               return ((ctsvc_address_s *)record)->id;
+       case CTSVC_RECORD_MESSENGER:
+               return ((ctsvc_messenger_s *)record)->id;
+       case CTSVC_RECORD_GROUP_RELATION:
+               return ((ctsvc_group_relation_s *)record)->id;
+       case CTSVC_RECORD_ACTIVITY:
+               return ((ctsvc_activity_s *)record)->id;
+       case CTSVC_RECORD_PROFILE:
+               return ((ctsvc_profile_s *)record)->id;
+       case CTSVC_RECORD_RELATIONSHIP:
+               return ((ctsvc_relationship_s *)record)->id;
+       case CTSVC_RECORD_IMAGE:
+               return ((ctsvc_image_s *)record)->id;
+       case CTSVC_RECORD_EXTENSION:
+               return ((ctsvc_extension_s *)record)->id;
+       default :
+               CTS_ERR("Invalid parameter : record(%d) is not child of contact", record->r_type);
+               return 0;
+       }
+       return 0;
+}
+
+
+static int __ctsvc_my_profile_remove_child_record(contacts_record_h record,
+               unsigned int property_id, contacts_record_h child_record )
+{
+       int id;
+       int ret;
+       contacts_list_h list = NULL;
+
+       ret = __ctsvc_my_profile_get_record_list_p(record, property_id, &list);
+       if (CONTACTS_ERROR_INVALID_PARAMETER == ret)
+               return ret;
+
+       id = __ctsvc_my_profile_get_child_record_id(child_record);
+       ctsvc_list_remove_child(list, child_record, (id?true:false));
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_my_profile_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_my_profile_s *my_profile = (ctsvc_my_profile_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_MY_PROFILE_DISPLAY_NAME:
+               FREEandSTRDUP(my_profile->display_name, str);
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_IMAGE_THUMBNAIL:
+               FREEandSTRDUP(my_profile->image_thumbnail_path, str);
+               break;
+       case CTSVC_PROPERTY_MY_PROFILE_UID:
+               FREEandSTRDUP(my_profile->uid, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(my_profile)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_my_profile_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_my_profile_s *out_data = NULL;
+       ctsvc_my_profile_s *src_data = NULL;
+
+       src_data = (ctsvc_my_profile_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_my_profile_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_my_profile_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->addressbook_id = src_data->addressbook_id;
+       out_data->changed_time = src_data->changed_time;
+
+       out_data->display_name = SAFE_STRDUP(src_data->display_name);
+       out_data->reverse_display_name = SAFE_STRDUP(src_data->reverse_display_name);
+       out_data->uid = SAFE_STRDUP(src_data->uid);
+       out_data->image_thumbnail_path = SAFE_STRDUP(src_data->image_thumbnail_path);
+
+       ctsvc_list_clone((contacts_list_h)src_data->name, (contacts_list_h*)&out_data->name);
+       out_data->name->l_type = CTSVC_RECORD_NAME;
+
+       ctsvc_list_clone((contacts_list_h)src_data->company, (contacts_list_h*)&out_data->company);
+       out_data->company->l_type = CTSVC_RECORD_COMPANY;
+
+       ctsvc_list_clone((contacts_list_h)src_data->note, (contacts_list_h*)&out_data->note);
+       out_data->note->l_type = CTSVC_RECORD_NOTE;
+
+       ctsvc_list_clone((contacts_list_h)src_data->numbers, (contacts_list_h*)&out_data->numbers);
+       out_data->numbers->l_type = CTSVC_RECORD_NUMBER;
+
+       ctsvc_list_clone((contacts_list_h)src_data->emails, (contacts_list_h*)&out_data->emails);
+       out_data->emails->l_type = CTSVC_RECORD_EMAIL;
+
+       ctsvc_list_clone((contacts_list_h)src_data->events, (contacts_list_h*)&out_data->events);
+       out_data->events->l_type = CTSVC_RECORD_EVENT;
+
+       ctsvc_list_clone((contacts_list_h)src_data->messengers, (contacts_list_h*)&out_data->messengers);
+       out_data->messengers->l_type = CTSVC_RECORD_MESSENGER;
+
+       ctsvc_list_clone((contacts_list_h)src_data->postal_addrs, (contacts_list_h*)&out_data->postal_addrs);
+       out_data->postal_addrs->l_type = CTSVC_RECORD_ADDRESS;
+
+       ctsvc_list_clone((contacts_list_h)src_data->urls, (contacts_list_h*)&out_data->urls);
+       out_data->urls->l_type = CTSVC_RECORD_URL;
+
+       ctsvc_list_clone((contacts_list_h)src_data->nicknames, (contacts_list_h*)&out_data->nicknames);
+       out_data->nicknames->l_type = CTSVC_RECORD_NICKNAME;
+
+       ctsvc_list_clone((contacts_list_h)src_data->profiles, (contacts_list_h*)&out_data->profiles);
+       out_data->profiles->l_type = CTSVC_RECORD_PROFILE;
+
+       ctsvc_list_clone((contacts_list_h)src_data->relationships, (contacts_list_h*)&out_data->relationships);
+       out_data->relationships->l_type = CTSVC_RECORD_RELATIONSHIP;
+
+       ctsvc_list_clone((contacts_list_h)src_data->images, (contacts_list_h*)&out_data->images);
+       out_data->images->l_type = CTSVC_RECORD_IMAGE;
+
+       ctsvc_list_clone((contacts_list_h)src_data->extensions, (contacts_list_h*)&out_data->extensions);
+       out_data->extensions->l_type = CTSVC_RECORD_EXTENSION;
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/common/ctsvc_record_person.c b/common/ctsvc_record_person.c
new file mode 100755 (executable)
index 0000000..cc779ff
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <glib.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_record.h"
+#include "ctsvc_view.h"
+
+static int __ctsvc_person_create(contacts_record_h* out_record);
+static int __ctsvc_person_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_person_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_person_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_person_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_person_get_str(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_person_get_bool( contacts_record_h record, unsigned int property_id, bool *value );
+static int __ctsvc_person_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_person_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+static int __ctsvc_person_set_bool(contacts_record_h record, unsigned int property_id, bool value);
+
+
+ctsvc_record_plugin_cb_s person_plugin_cbs = {
+       .create = __ctsvc_person_create,
+       .destroy = __ctsvc_person_destroy,
+       .clone = __ctsvc_person_clone,
+       .get_str = __ctsvc_person_get_str,
+       .get_str_p = __ctsvc_person_get_str_p,
+       .get_int = __ctsvc_person_get_int,
+       .get_bool = __ctsvc_person_get_bool,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_person_set_str,
+       .set_int = __ctsvc_person_set_int,
+       .set_bool = __ctsvc_person_set_bool,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+static int __ctsvc_person_create(contacts_record_h* out_record)
+{
+       ctsvc_person_s *person;
+       person = (ctsvc_person_s*)calloc(1, sizeof(ctsvc_person_s));
+       RETVM_IF(NULL == person, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)person;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_person_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_person_s *person = (ctsvc_person_s*)record;
+       person->base.plugin_cbs = NULL; // help to find double-destroy bug (refer to the contacts_record_destroy)
+       free(person->base.properties_flags);
+
+       free(person->display_name);
+       free(person->display_name_index);
+       free(person->ringtone_path);
+       free(person->vibration);
+       free(person->message_alert);
+       free(person->image_thumbnail_path);
+       free(person->status);
+       free(person->addressbook_ids);
+       free(person);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_person_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+    ctsvc_person_s *out_data = NULL;
+    ctsvc_person_s *src_data = NULL;
+
+    src_data = (ctsvc_person_s*)record;
+    out_data = calloc(1, sizeof(ctsvc_person_s));
+    RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                        "Out of memeory : calloc(ctsvc_person_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->is_favorite = src_data->is_favorite;
+       out_data->has_phonenumber = src_data->has_phonenumber;
+       out_data->has_email = src_data->has_email;
+       out_data->person_id = src_data->person_id;
+       out_data->name_contact_id = src_data->name_contact_id;
+       out_data->link_count = src_data->link_count;
+       out_data->addressbook_ids = SAFE_STRDUP(src_data->addressbook_ids);
+       out_data->display_name = SAFE_STRDUP(src_data->display_name);
+       out_data->display_name_index = SAFE_STRDUP(src_data->display_name_index);
+       out_data->image_thumbnail_path = SAFE_STRDUP(src_data->image_thumbnail_path);
+       out_data->ringtone_path = SAFE_STRDUP(src_data->ringtone_path);
+       out_data->vibration = SAFE_STRDUP(src_data->vibration);
+       out_data->message_alert = SAFE_STRDUP(src_data->message_alert);
+       out_data->status = SAFE_STRDUP(src_data->status);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_person_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_person_s *person = (ctsvc_person_s *)record;
+       switch(property_id) {
+       case CTSVC_PROPERTY_PERSON_ID:
+               *out = person->person_id;
+               break;
+       case CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID:
+               *out = person->name_contact_id;
+               break;
+       case CTSVC_PROPERTY_PERSON_LINK_COUNT:
+               *out = person->link_count;
+               break;
+       default:
+               CTS_ERR("This field(%d) is not supported in value(person)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_person_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_person_s *person = (ctsvc_person_s *)record;
+       switch(property_id) {
+       case CTSVC_PROPERTY_PERSON_DISPLAY_NAME:
+               *out_str = GET_STR(copy, person->display_name);
+               break;
+       case CTSVC_PROPERTY_PERSON_RINGTONE:
+               *out_str = GET_STR(copy, person->ringtone_path);
+               break;
+       case CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL:
+               *out_str = GET_STR(copy, person->image_thumbnail_path);
+               break;
+       case CTSVC_PROPERTY_PERSON_VIBRATION:
+               *out_str = GET_STR(copy, person->vibration);
+               break;
+       case CTSVC_PROPERTY_PERSON_MESSAGE_ALERT:
+               *out_str = GET_STR(copy, person->message_alert);
+               break;
+       case CTSVC_PROPERTY_PERSON_STATUS:
+               *out_str = GET_STR(copy, person->status);
+               break;
+       case CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX:
+               *out_str = GET_STR(copy, person->display_name_index);
+               break;
+       case CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS:
+               *out_str = GET_STR(copy, person->addressbook_ids);
+               break;
+       default :
+               CTS_ERR("This field(%d) is not supported in value(person)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_person_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_person_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_person_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_person_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_person_get_bool(contacts_record_h record, unsigned int property_id, bool *value )
+{
+       ctsvc_person_s *person = (ctsvc_person_s *)record;
+       switch (property_id) {
+       case CTSVC_PROPERTY_PERSON_IS_FAVORITE:
+               *value = person->is_favorite;
+               break;
+       case CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER:
+               *value = person->has_phonenumber;
+               break;
+       case CTSVC_PROPERTY_PERSON_HAS_EMAIL:
+               *value = person->has_email;
+               break;
+       default:
+               CTS_ERR("This field(%d) is not supported in value(company)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_person_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_person_s *person = (ctsvc_person_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID:
+               person->name_contact_id = value;
+               break;
+       case CTSVC_PROPERTY_PERSON_ID:
+               person->person_id = value;
+               break;
+       case CTSVC_PROPERTY_PERSON_LINK_COUNT:
+               person->link_count = value;
+               break;
+       default:
+               CTS_ERR("This field(0x%0x) is not supported in value(person)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_person_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_person_s *person = (ctsvc_person_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_PERSON_DISPLAY_NAME:
+               FREEandSTRDUP( person->display_name, str);
+               break;
+       case CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX:
+               FREEandSTRDUP( person->display_name_index, str);
+               break;
+       case CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL:
+               FREEandSTRDUP(person->image_thumbnail_path, str);
+               break;
+       case CTSVC_PROPERTY_PERSON_RINGTONE:
+               FREEandSTRDUP(person->ringtone_path, str);
+               break;
+       case CTSVC_PROPERTY_PERSON_VIBRATION:
+               FREEandSTRDUP(person->vibration, str);
+               break;
+       case CTSVC_PROPERTY_PERSON_MESSAGE_ALERT:
+               FREEandSTRDUP(person->message_alert, str);
+               break;
+       default :
+               CTS_ERR("This field(%d) is not supported in value(person)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_person_set_bool(contacts_record_h record, unsigned int property_id, bool value)
+{
+       ctsvc_person_s *person = (ctsvc_person_s *)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_PERSON_IS_FAVORITE:
+               if (person->is_favorite != value) {
+                       person->is_favorite = value;
+               }
+               break;
+       default:
+               CTS_ERR("This field(%d) is not supported in value(person)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+
diff --git a/common/ctsvc_record_phonelog.c b/common/ctsvc_record_phonelog.c
new file mode 100644 (file)
index 0000000..0aa3c2a
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+
+#include "contacts.h"
+
+#include "ctsvc_internal.h"
+#include "ctsvc_record.h"
+#include "ctsvc_view.h"
+
+static int __ctsvc_phonelog_create(contacts_record_h *out_record);
+static int __ctsvc_phonelog_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_phonelog_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_phonelog_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_phonelog_get_str(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_phonelog_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_phonelog_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_phonelog_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+
+ctsvc_record_plugin_cb_s phonelog_plugin_cbs = {
+       .create = __ctsvc_phonelog_create,
+       .destroy = __ctsvc_phonelog_destroy,
+       .clone = __ctsvc_phonelog_clone,
+       .get_str = __ctsvc_phonelog_get_str,
+       .get_str_p = __ctsvc_phonelog_get_str_p,
+       .get_int = __ctsvc_phonelog_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_phonelog_set_str,
+       .set_int = __ctsvc_phonelog_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+static int __ctsvc_phonelog_create(contacts_record_h *out_record)
+{
+       ctsvc_phonelog_s *phonelog;
+
+       phonelog = (ctsvc_phonelog_s*)calloc(1, sizeof(ctsvc_phonelog_s));
+       RETVM_IF(NULL == phonelog, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)phonelog;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_phonelog_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_phonelog_s* phonelog = (ctsvc_phonelog_s*)record;
+       phonelog->base.plugin_cbs = NULL;       // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(phonelog->base.properties_flags);
+
+       free(phonelog->address);
+       free(phonelog->extra_data2);
+       free(phonelog);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_phonelog_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+    ctsvc_phonelog_s *out_data = NULL;
+    ctsvc_phonelog_s *src_data = NULL;
+
+    src_data = (ctsvc_phonelog_s*)record;
+    out_data = calloc(1, sizeof(ctsvc_phonelog_s));
+    RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                        "Out of memeory : calloc(ctsvc_phonelog_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->address = SAFE_STRDUP(src_data->address);
+       out_data->person_id = src_data->person_id;
+       out_data->log_time = src_data->log_time;
+       out_data->log_type = src_data->log_type;
+       out_data->extra_data1 = src_data->extra_data1;
+       out_data->extra_data2 = SAFE_STRDUP(src_data->extra_data2);
+       out_data->sim_slot_no = src_data->sim_slot_no;
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_phonelog_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_phonelog_s* phonelog = (ctsvc_phonelog_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_PHONELOG_ID:
+               *out = phonelog->id;
+               break;
+       case CTSVC_PROPERTY_PHONELOG_PERSON_ID:
+               *out = phonelog->person_id;
+               break;
+       case CTSVC_PROPERTY_PHONELOG_LOG_TIME:
+               *out = phonelog->log_time;
+               break;
+       case CTSVC_PROPERTY_PHONELOG_LOG_TYPE:
+               *out = phonelog->log_type;
+               break;
+       case CTSVC_PROPERTY_PHONELOG_EXTRA_DATA1:
+               *out = phonelog->extra_data1;
+               break;
+       case CTSVC_PROPERTY_PHONELOG_SIM_SLOT_NO:
+               *out = phonelog->sim_slot_no;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(phonelog)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_phonelog_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_phonelog_s* phonelog = (ctsvc_phonelog_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_PHONELOG_ADDRESS:
+               *out_str = GET_STR(copy, phonelog->address);
+               break;
+       case CTSVC_PROPERTY_PHONELOG_EXTRA_DATA2:
+               *out_str = GET_STR(copy, phonelog->extra_data2);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(phonelog)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_phonelog_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_phonelog_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_phonelog_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_phonelog_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_phonelog_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_phonelog_s* phonelog = (ctsvc_phonelog_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_PHONELOG_ID:
+               phonelog->id = value;
+               break;
+       case CTSVC_PROPERTY_PHONELOG_PERSON_ID:
+               RETVM_IF(phonelog->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (phonelog)", property_id);
+               phonelog->person_id = value;
+               break;
+       case CTSVC_PROPERTY_PHONELOG_LOG_TIME:
+               RETVM_IF(phonelog->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (phonelog)", property_id);
+               phonelog->log_time = value;
+               break;
+       case CTSVC_PROPERTY_PHONELOG_LOG_TYPE:
+               if ((CONTACTS_PLOG_TYPE_NONE <= value
+                                       && value <= CONTACTS_PLOG_TYPE_VIDEO_BLOCKED)
+                               || (CONTACTS_PLOG_TYPE_MMS_INCOMMING <= value
+                                       && value <= CONTACTS_PLOG_TYPE_MMS_BLOCKED)
+                               || (CONTACTS_PLOG_TYPE_EMAIL_RECEIVED <= value
+                                       && value <= CONTACTS_PLOG_TYPE_EMAIL_SENT)
+                       )
+                       phonelog->log_type = value;
+               else {
+                       CTS_ERR("Invalid parameter : log type is in invalid range (%d)", value);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               break;
+       case CTSVC_PROPERTY_PHONELOG_EXTRA_DATA1:
+               RETVM_IF(phonelog->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (phonelog)", property_id);
+               phonelog->extra_data1 = value;
+               break;
+       case CTSVC_PROPERTY_PHONELOG_SIM_SLOT_NO:
+               RETVM_IF(phonelog->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : property_id(%d) is a read-only value (phonelog)", property_id);
+               phonelog->sim_slot_no = value;
+               break;
+       default:
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(phonelog)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_phonelog_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_phonelog_s* phonelog = (ctsvc_phonelog_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_PHONELOG_ADDRESS:
+               RETVM_IF(phonelog->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : property_id(%d) is a read-only value (phonelog)", property_id);
+               FREEandSTRDUP(phonelog->address, str);
+               break;
+       case CTSVC_PROPERTY_PHONELOG_EXTRA_DATA2:
+               FREEandSTRDUP(phonelog->extra_data2, str);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : property_id(%d) is not supported in value(phonelog)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/common/ctsvc_record_result.c b/common/ctsvc_record_result.c
new file mode 100644 (file)
index 0000000..c1d7f32
--- /dev/null
@@ -0,0 +1,473 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+
+#include "ctsvc_internal.h"
+#include "ctsvc_record.h"
+#include "ctsvc_view.h"
+
+#ifdef _CONTACTS_IPC_SERVER
+#ifdef ENABLE_SIM_FEATURE
+#include "ctsvc_server_sim.h"
+#endif // ENABLE_SIM_FEATURE
+#endif
+
+static int __ctsvc_result_create(contacts_record_h* out_record);
+static int __ctsvc_result_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_result_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_result_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_result_get_str(contacts_record_h record, unsigned int property_id, char** out_str);
+static int __ctsvc_result_get_int(contacts_record_h record, unsigned int property_id, int* out_value );
+static int __ctsvc_result_get_lli(contacts_record_h record, unsigned int property_id, long long int* out_value );
+static int __ctsvc_result_get_bool(contacts_record_h record, unsigned int property_id, bool* out_value );
+static int __ctsvc_result_get_double(contacts_record_h record, unsigned int property_id, double* out_value );
+static int __ctsvc_result_set_int(contacts_record_h record, unsigned int property_id, int value );
+static int __ctsvc_result_set_lli(contacts_record_h record, unsigned int property_id, long long int value );
+static int __ctsvc_result_set_bool(contacts_record_h record, unsigned int property_id, bool value );
+static int __ctsvc_result_set_str(contacts_record_h record, unsigned int property_id, const char *str );
+static int __ctsvc_result_set_double(contacts_record_h record, unsigned int property_id, double value );
+
+ctsvc_record_plugin_cb_s result_plugin_cbs = {
+       .create = __ctsvc_result_create,
+       .destroy = __ctsvc_result_destroy,
+       .clone = __ctsvc_result_clone,
+       .get_str = __ctsvc_result_get_str,
+       .get_str_p = __ctsvc_result_get_str_p,
+       .get_int = __ctsvc_result_get_int,
+       .get_bool = __ctsvc_result_get_bool,
+       .get_lli = __ctsvc_result_get_lli,
+       .get_double = __ctsvc_result_get_double,
+       .set_str = __ctsvc_result_set_str,
+       .set_int = __ctsvc_result_set_int,
+       .set_bool = __ctsvc_result_set_bool,
+       .set_lli = __ctsvc_result_set_lli,
+       .set_double = __ctsvc_result_set_double,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+static int __ctsvc_result_create(contacts_record_h* out_record)
+{
+       ctsvc_result_s *result;
+       result = (ctsvc_result_s*)calloc(1, sizeof(ctsvc_result_s));
+       RETVM_IF(NULL == result, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)result;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_result_destroy(contacts_record_h record, bool delete_child)
+{
+       GSList *cursor;
+       ctsvc_result_s* result = (ctsvc_result_s*)record;
+
+       for(cursor = result->values;cursor;cursor=cursor->next){
+               ctsvc_result_value_s *data = cursor->data;
+               if (data->type == CTSVC_VIEW_DATA_TYPE_STR)
+                       free(data->value.s);
+               free(data);
+       }
+       g_slist_free(result->values);
+       result->base.plugin_cbs = NULL; // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(result->base.properties_flags);
+
+       free(result);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_result_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+       ctsvc_result_s *out_data = NULL;
+       ctsvc_result_s *src_data = NULL;
+       GSList *cursor;
+
+       src_data = (ctsvc_result_s*)record;
+       out_data = calloc(1, sizeof(ctsvc_result_s));
+       RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memeory : calloc(ctsvc_result_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       for(cursor=src_data->values;cursor;cursor=cursor->next) {
+               ctsvc_result_value_s *src = cursor->data;
+               ctsvc_result_value_s *dest = calloc(1, sizeof(ctsvc_result_value_s));
+               if (NULL == dest) {
+                       CTS_ERR("calloc() return NULL");
+                       __ctsvc_result_destroy((contacts_record_h)out_data, true);
+                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+               }
+
+               dest->property_id = src->property_id;
+               dest->type = src->type;
+               switch(src->type) {
+               case CTSVC_VIEW_DATA_TYPE_BOOL:
+                       dest->value.b = src->value.b;
+                       break;
+               case CTSVC_VIEW_DATA_TYPE_INT:
+                       dest->value.i = src->value.i;
+                       break;
+               case CTSVC_VIEW_DATA_TYPE_LLI:
+                       dest->value.l = src->value.l;
+                       break;
+               case CTSVC_VIEW_DATA_TYPE_STR:
+                       dest->value.s = SAFE_STRDUP(src->value.s);
+                       break;
+               case CTSVC_VIEW_DATA_TYPE_DOUBLE:
+                       dest->value.d = src->value.d;
+                       break;
+               default:
+                       break;
+               }
+               out_data->values = g_slist_append(out_data->values, (void*)dest);
+       }
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_result_get_str_real(contacts_record_h record, unsigned int property_id,
+               char** out_str, bool copy )
+{
+       ctsvc_result_s* result = (ctsvc_result_s *)record;
+
+       GSList *cursor;
+
+       for(cursor = result->values;cursor;cursor=cursor->next){
+               ctsvc_result_value_s *data = cursor->data;
+               if (data->property_id == property_id) {
+                       if (data->type == CTSVC_VIEW_DATA_TYPE_STR) {
+                               *out_str = GET_STR(copy, data->value.s);
+                               return CONTACTS_ERROR_NONE;
+                       }
+                       else {
+                               CTS_ERR("use another get_type API, (type : %d)", data->type);
+                               return CONTACTS_ERROR_INVALID_PARAMETER;
+                       }
+               }
+       }
+
+       return CONTACTS_ERROR_NO_DATA;
+}
+
+static int __ctsvc_result_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_result_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_result_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_result_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_result_get_int(contacts_record_h record, unsigned int property_id, int* out_value )
+{
+       ctsvc_result_s* result = (ctsvc_result_s *)record;
+
+       GSList *cursor;
+       //TODO: check the value type of property_id is int
+       for(cursor = result->values;cursor;cursor=cursor->next){
+               ctsvc_result_value_s *data = cursor->data;
+               if (data->property_id == property_id) {
+                       if (data->type == CTSVC_VIEW_DATA_TYPE_INT) {
+                               *out_value = data->value.i;
+                               return CONTACTS_ERROR_NONE;
+                       }
+                       else {
+                               CTS_ERR("use another get_type API, (type : %d)", data->type);
+                               return CONTACTS_ERROR_INVALID_PARAMETER;
+                       }
+               }
+       }
+
+       return CONTACTS_ERROR_NO_DATA;
+}
+
+static int __ctsvc_result_set_int(contacts_record_h record, unsigned int property_id, int value )
+{
+       ctsvc_result_s* result = (ctsvc_result_s *)record;
+       GSList *cursor;
+       ctsvc_result_value_s *data;
+
+       // TODO: check the value type of property_id is int
+       for(cursor = result->values;cursor;cursor=cursor->next){
+               data = cursor->data;
+               if (data->property_id == property_id) {
+                       if (data->type == CTSVC_VIEW_DATA_TYPE_INT) {
+#ifdef _CONTACTS_IPC_SERVER
+#ifdef ENABLE_SIM_FEATURE
+
+                               if (property_id == CTSVC_PROPERTY_PHONELOG_SIM_SLOT_NO)
+                                       data->value.i = ctsvc_server_sim_get_sim_slot_no_by_info_id(value);
+                               else
+#endif // ENABLE_SIM_FEATURE
+#endif
+                               data->value.i = value;
+                               return CONTACTS_ERROR_NONE;
+                       }
+                       else {
+                               CTS_ERR("use another get_type API, (type : %d)", data->type);
+                               return CONTACTS_ERROR_INVALID_PARAMETER;
+                       }
+               }
+       }
+
+       data = calloc(1, sizeof(ctsvc_result_value_s));
+       RETVM_IF(NULL == data, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+
+       data->property_id = property_id;
+       data->type = CTSVC_VIEW_DATA_TYPE_INT;
+#ifdef _CONTACTS_IPC_SERVER
+#ifdef ENABLE_SIM_FEATURE
+       if (property_id == CTSVC_PROPERTY_PHONELOG_SIM_SLOT_NO)
+               data->value.i = ctsvc_server_sim_get_sim_slot_no_by_info_id(value);
+       else
+#endif // ENABLE_SIM_FEATURE
+#endif
+       data->value.i = value;
+       result->values = g_slist_append(result->values, (void*)data);
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_result_set_lli(contacts_record_h record, unsigned int property_id, long long int value )
+{
+       ctsvc_result_s* result = (ctsvc_result_s *)record;
+       GSList *cursor;
+       ctsvc_result_value_s *data;
+
+       // TODO: check the value type of property_id is int
+       for(cursor = result->values;cursor;cursor=cursor->next){
+               data = cursor->data;
+               if (data->property_id == property_id) {
+                       if (data->type == CTSVC_VIEW_DATA_TYPE_LLI) {
+                               data->value.l = value;
+                               return CONTACTS_ERROR_NONE;
+                       }
+                       else {
+                               CTS_ERR("use another get_type API, (type : %d)", data->type);
+                               return CONTACTS_ERROR_INVALID_PARAMETER;
+                       }
+               }
+       }
+
+       data = calloc(1, sizeof(ctsvc_result_value_s));
+       RETVM_IF(NULL == data, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+       data->property_id = property_id;
+       data->type = CTSVC_VIEW_DATA_TYPE_LLI;
+       data->value.l = value;
+       result->values = g_slist_append(result->values, (void*)data);
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_result_set_double(contacts_record_h record, unsigned int property_id, double value )
+{
+       ctsvc_result_s* result = (ctsvc_result_s *)record;
+       GSList *cursor;
+       ctsvc_result_value_s *data;
+
+       for(cursor = result->values;cursor;cursor=cursor->next){
+               data = cursor->data;
+               if (data->property_id == property_id) {
+                       if (data->type == CTSVC_VIEW_DATA_TYPE_DOUBLE) {
+                               data->value.d = value;
+                               return CONTACTS_ERROR_NONE;
+                       }
+                       else {
+                               CTS_ERR("use another get_type API, (type : %d)", data->type);
+                               return CONTACTS_ERROR_INVALID_PARAMETER;
+                       }
+               }
+       }
+
+       data = calloc(1, sizeof(ctsvc_result_value_s));
+       RETVM_IF(NULL == data, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+       data->property_id = property_id;
+       data->type = CTSVC_VIEW_DATA_TYPE_DOUBLE;
+       data->value.d = value;
+       result->values = g_slist_append(result->values, (void*)data);
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_result_set_bool(contacts_record_h record, unsigned int property_id, bool value )
+{
+       ctsvc_result_s* result = (ctsvc_result_s *)record;
+       GSList *cursor;
+       ctsvc_result_value_s *data;
+
+       // TODO: check the value type of property_id is int
+       for(cursor = result->values;cursor;cursor=cursor->next){
+               data = cursor->data;
+               if (data->property_id == property_id) {
+                       if (data->type == CTSVC_VIEW_DATA_TYPE_BOOL) {
+                               data->value.b = value;
+                               return CONTACTS_ERROR_NONE;
+                       }
+                       else {
+                               CTS_ERR("use another get_type API, (type : %d)", data->type);
+                               return CONTACTS_ERROR_INVALID_PARAMETER;
+                       }
+               }
+       }
+
+       data = calloc(1, sizeof(ctsvc_result_value_s));
+       RETVM_IF(NULL == data, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+
+       data->property_id = property_id;
+       data->type = CTSVC_VIEW_DATA_TYPE_BOOL;
+       data->value.i = value;
+       result->values = g_slist_append(result->values, (void*)data);
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_result_set_str(contacts_record_h record, unsigned int property_id, const char *str )
+{
+       ctsvc_result_s* result = (ctsvc_result_s *)record;
+       GSList *cursor;
+       ctsvc_result_value_s *data;
+       char *full_path = NULL;
+       int str_len;
+
+       // TODO: check the value type of property_id is int
+       for(cursor = result->values;cursor;cursor=cursor->next){
+               data = cursor->data;
+               if (data->property_id == property_id) {
+                       if (data->type == CTSVC_VIEW_DATA_TYPE_STR) {
+                               switch (property_id) {
+                               case CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL:
+                               case CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL:
+                                       if (str) {
+                                               str_len = strlen(CTSVC_CONTACT_IMG_FULL_LOCATION) + strlen(str) + 2;
+                                               full_path = calloc(1, str_len);
+                                               RETVM_IF(NULL == full_path, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+                                               snprintf(full_path, str_len, "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, str);
+                                       }
+                                       free(data->value.s);
+                                       data->value.s = full_path;
+                                       return CONTACTS_ERROR_NONE;
+                               default:
+                                       FREEandSTRDUP(data->value.s, str);
+                                       return CONTACTS_ERROR_NONE;
+                               }
+                       }
+                       else {
+                               CTS_ERR("use another get_type API, (type : %d)", data->type);
+                               return CONTACTS_ERROR_INVALID_PARAMETER;
+                       }
+               }
+       }
+
+       data = calloc(1, sizeof(ctsvc_result_value_s));
+       RETVM_IF(NULL == data, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+
+       data->property_id = property_id;
+       data->type = CTSVC_VIEW_DATA_TYPE_STR;
+       switch (property_id) {
+       case CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL:
+       case CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL:
+               if (str) {
+                       str_len = strlen(CTSVC_CONTACT_IMG_FULL_LOCATION) + strlen(str) + 2;
+                       full_path = calloc(1, str_len);
+                       if (NULL == full_path) {
+                               CTS_ERR("calloc() return NULL");
+                               free(data->value.s);
+                               free(data);
+                               return CONTACTS_ERROR_OUT_OF_MEMORY;
+                       }
+                       snprintf(full_path, str_len, "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, str);
+               }
+               free(data->value.s);
+               data->value.s = full_path;
+               break;
+       default:
+               data->value.s = SAFE_STRDUP(str);
+               break;
+       }
+
+       result->values = g_slist_append(result->values, (void*)data);
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_result_get_bool(contacts_record_h record, unsigned int property_id, bool* out_value )
+{
+       ctsvc_result_s* result = (ctsvc_result_s *)record;
+       GSList *cursor;
+       for(cursor = result->values;cursor;cursor=cursor->next){
+               ctsvc_result_value_s *data = cursor->data;
+               if (data->property_id == property_id) {
+                       if (data->type == CTSVC_VIEW_DATA_TYPE_BOOL) {
+                               *out_value = data->value.b;
+                               return CONTACTS_ERROR_NONE;
+                       }
+                       else {
+                               CTS_ERR("use another get_type API, (type : %d)", data->type);
+                               return CONTACTS_ERROR_INVALID_PARAMETER;
+                       }
+               }
+       }
+
+       return CONTACTS_ERROR_NO_DATA;
+}
+
+static int __ctsvc_result_get_lli(contacts_record_h record, unsigned int property_id, long long int* out_value )
+{
+       ctsvc_result_s* result = (ctsvc_result_s *)record;
+       GSList *cursor;
+       for(cursor = result->values;cursor;cursor=cursor->next){
+               ctsvc_result_value_s *data = cursor->data;
+               if (data->property_id == property_id) {
+                       if (data->type == CTSVC_VIEW_DATA_TYPE_LLI) {
+                               *out_value = data->value.l;
+                               return CONTACTS_ERROR_NONE;
+                               }
+                       else {
+                               CTS_ERR("use another get_type API, (type : %d)", data->type);
+                               return CONTACTS_ERROR_INVALID_PARAMETER;
+                       }
+               }
+       }
+
+       return CONTACTS_ERROR_NO_DATA;
+}
+
+static int __ctsvc_result_get_double(contacts_record_h record, unsigned int property_id, double* out_value )
+{
+       ctsvc_result_s* result = (ctsvc_result_s *)record;
+       GSList *cursor;
+       for(cursor = result->values;cursor;cursor=cursor->next){
+               ctsvc_result_value_s *data = cursor->data;
+               if (data->property_id == property_id) {
+                       if (data->type == CTSVC_VIEW_DATA_TYPE_DOUBLE) {
+                               *out_value = data->value.d;
+                               return CONTACTS_ERROR_NONE;
+                               }
+                       else {
+                               CTS_ERR("use another get_type API, (type : %d)", data->type);
+                               return CONTACTS_ERROR_INVALID_PARAMETER;
+                       }
+               }
+       }
+
+       return CONTACTS_ERROR_NO_DATA;
+}
+
diff --git a/common/ctsvc_record_sdn.c b/common/ctsvc_record_sdn.c
new file mode 100644 (file)
index 0000000..5b261ef
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_record.h"
+#include "ctsvc_view.h"
+
+static int __ctsvc_sdn_create(contacts_record_h* out_record);
+static int __ctsvc_sdn_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_sdn_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_sdn_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_sdn_get_str(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_sdn_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_sdn_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_sdn_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+
+ctsvc_record_plugin_cb_s sdn_plugin_cbs = {
+       .create = __ctsvc_sdn_create,
+       .destroy = __ctsvc_sdn_destroy,
+       .clone = __ctsvc_sdn_clone,
+       .get_str = __ctsvc_sdn_get_str,
+       .get_str_p = __ctsvc_sdn_get_str_p,
+       .get_int = __ctsvc_sdn_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_sdn_set_str,
+       .set_int = __ctsvc_sdn_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+static int __ctsvc_sdn_create(contacts_record_h* out_record)
+{
+       ctsvc_sdn_s *sdn;
+       sdn = (ctsvc_sdn_s*)calloc(1, sizeof(ctsvc_sdn_s));
+       RETVM_IF(NULL == sdn, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory calloc is failed");
+
+       *out_record = (contacts_record_h)sdn;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_sdn_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_sdn_s* sdn = (ctsvc_sdn_s*)record;
+       sdn->base.plugin_cbs = NULL;    // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(sdn->base.properties_flags);
+
+       free(sdn->name);
+       free(sdn->number);
+       free(sdn);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_sdn_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+    ctsvc_sdn_s *out_data = NULL;
+    ctsvc_sdn_s *src_data = NULL;
+
+    src_data = (ctsvc_sdn_s*)record;
+    out_data = calloc(1, sizeof(ctsvc_sdn_s));
+    RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                        "Out of memeory : calloc(ctsvc_sdn_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->name = SAFE_STRDUP(src_data->name);
+       out_data->number = SAFE_STRDUP(src_data->number);
+       out_data->sim_slot_no = src_data->sim_slot_no;
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_sdn_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_sdn_s* sdn = (ctsvc_sdn_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_SDN_ID:
+               *out = sdn->id;
+               break;
+       case CTSVC_PROPERTY_SDN_SIM_SLOT_NO:
+               *out = sdn->sim_slot_no;
+               break;
+       default:
+               CTS_ERR("This field(%d) is not supported in value(sdn)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_sdn_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_sdn_s* sdn = (ctsvc_sdn_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_SDN_NAME:
+               *out_str = GET_STR(copy, sdn->name);
+               break;
+       case CTSVC_PROPERTY_SDN_NUMBER:
+               *out_str = GET_STR(copy, sdn->number);
+               break;
+       default :
+               CTS_ERR("This field(%d) is not supported in value(sdn)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_sdn_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_sdn_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_sdn_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_sdn_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_sdn_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_sdn_s* sdn = (ctsvc_sdn_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_SDN_ID:
+               sdn->id = value;
+               break;
+       case CTSVC_PROPERTY_SDN_SIM_SLOT_NO:
+               sdn->sim_slot_no = value;
+               break;
+       default:
+               CTS_ERR("This field(%d) is not supported in value(sdn)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_sdn_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_sdn_s* sdn = (ctsvc_sdn_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_SDN_NAME:
+               FREEandSTRDUP(sdn->name, str);
+               break;
+       case CTSVC_PROPERTY_SDN_NUMBER:
+               FREEandSTRDUP(sdn->number, str);
+               break;
+       default :
+               CTS_ERR("This field(%d) is not supported in value(sdn)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/common/ctsvc_record_speeddial.c b/common/ctsvc_record_speeddial.c
new file mode 100644 (file)
index 0000000..10e7ee7
--- /dev/null
@@ -0,0 +1,221 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_record.h"
+#include "ctsvc_view.h"
+
+static int __ctsvc_speeddial_create(contacts_record_h* out_record);
+static int __ctsvc_speeddial_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_speeddial_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_speeddial_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_speeddial_get_str(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_speeddial_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str );
+static int __ctsvc_speeddial_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_speeddial_set_str(contacts_record_h record, unsigned int property_id, const char* str );
+
+
+ctsvc_record_plugin_cb_s speeddial_plugin_cbs = {
+       .create = __ctsvc_speeddial_create,
+       .destroy = __ctsvc_speeddial_destroy,
+       .clone = __ctsvc_speeddial_clone,
+       .get_str = __ctsvc_speeddial_get_str,
+       .get_str_p = __ctsvc_speeddial_get_str_p,
+       .get_int = __ctsvc_speeddial_get_int,
+       .get_bool = NULL,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = __ctsvc_speeddial_set_str,
+       .set_int = __ctsvc_speeddial_set_int,
+       .set_bool = NULL,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+static int __ctsvc_speeddial_create(contacts_record_h* out_record)
+{
+       ctsvc_speeddial_s *speeddial;
+       speeddial = (ctsvc_speeddial_s*)calloc(1, sizeof(ctsvc_speeddial_s));
+       RETVM_IF(NULL == speeddial, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory : calloc is failed");
+
+       *out_record = (contacts_record_h)speeddial;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_speeddial_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_speeddial_s* speeddial = (ctsvc_speeddial_s*)record;
+       speeddial->base.plugin_cbs = NULL;      // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(speeddial->base.properties_flags);
+
+       free(speeddial->display_name);
+       free(speeddial->image_thumbnail_path);
+       free(speeddial->label);
+       free(speeddial->number);
+       free(speeddial);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_speeddial_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+    ctsvc_speeddial_s *out_data = NULL;
+    ctsvc_speeddial_s *src_data = NULL;
+
+    src_data = (ctsvc_speeddial_s*)record;
+    out_data = calloc(1, sizeof(ctsvc_speeddial_s));
+    RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                        "Out of memeory : calloc(ctsvc_speeddial_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->dial_number = src_data->dial_number;
+       out_data->number_id = src_data->number_id;
+       out_data->person_id = src_data->person_id;
+       out_data->number_type = src_data->number_type;
+       out_data->display_name = SAFE_STRDUP(src_data->display_name);
+       out_data->image_thumbnail_path = SAFE_STRDUP(src_data->image_thumbnail_path);
+       out_data->label = SAFE_STRDUP(src_data->label);
+       out_data->number = SAFE_STRDUP(src_data->number);
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_speeddial_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_speeddial_s *speeddial = (ctsvc_speeddial_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_SPEEDDIAL_DIAL_NUMBER:
+               *out = speeddial->dial_number;
+               break;
+       case CTSVC_PROPERTY_SPEEDDIAL_NUMBER_ID:
+               *out = speeddial->number_id;
+               break;
+       case CTSVC_PROPERTY_SPEEDDIAL_NUMBER_TYPE:
+               *out = speeddial->number_type;
+               break;
+       case CTSVC_PROPERTY_SPEEDDIAL_PERSON_ID:
+               *out = speeddial->person_id;
+               break;
+       default:
+               CTS_ERR("This field(%d) is not supported in value(speeddial)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_speeddial_get_str_real(contacts_record_h record, unsigned int property_id, char** out_str, bool copy )
+{
+       ctsvc_speeddial_s *speeddial = (ctsvc_speeddial_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_SPEEDDIAL_DISPLAY_NAME:
+               *out_str = GET_STR(copy, speeddial->display_name);
+               break;
+       case CTSVC_PROPERTY_SPEEDDIAL_NUMBER:
+               *out_str = GET_STR(copy, speeddial->number);
+               break;
+       case CTSVC_PROPERTY_SPEEDDIAL_IMAGE_THUMBNAIL:
+               *out_str = GET_STR(copy, speeddial->image_thumbnail_path);
+               break;
+       case CTSVC_PROPERTY_SPEEDDIAL_NUMBER_LABEL:
+               *out_str = GET_STR(copy, speeddial->label);
+               break;
+       default :
+               CTS_ERR("This field(%d) is not supported in value(speeddial)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_speeddial_get_str_p(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_speeddial_get_str_real(record, property_id, out_str, false);
+}
+
+static int __ctsvc_speeddial_get_str(contacts_record_h record, unsigned int property_id, char** out_str)
+{
+       return __ctsvc_speeddial_get_str_real(record, property_id, out_str, true);
+}
+
+static int __ctsvc_speeddial_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_speeddial_s *speeddial = (ctsvc_speeddial_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_SPEEDDIAL_NUMBER_TYPE:
+               speeddial->number_type = value;
+               break;
+       case CTSVC_PROPERTY_SPEEDDIAL_PERSON_ID:
+               speeddial->person_id = value;
+               break;
+       case CTSVC_PROPERTY_SPEEDDIAL_DIAL_NUMBER:
+               RETVM_IF(speeddial->id > 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : property_id(%d) is a read-only value (speeddial)", property_id);
+               speeddial->dial_number = value;
+               break;
+       case CTSVC_PROPERTY_SPEEDDIAL_NUMBER_ID:
+               speeddial->number_id = value;
+               break;
+       default:
+               CTS_ERR("This field(%d) is not supported in value(speeddial)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_speeddial_set_str(contacts_record_h record, unsigned int property_id, const char* str )
+{
+       ctsvc_speeddial_s *speeddial = (ctsvc_speeddial_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_SPEEDDIAL_DISPLAY_NAME:
+               FREEandSTRDUP(speeddial->display_name, str);
+               break;
+       case CTSVC_PROPERTY_SPEEDDIAL_NUMBER:
+               FREEandSTRDUP(speeddial->number, str);
+               break;
+       case CTSVC_PROPERTY_SPEEDDIAL_IMAGE_THUMBNAIL:
+               FREEandSTRDUP(speeddial->image_thumbnail_path, str);
+               break;
+       case CTSVC_PROPERTY_SPEEDDIAL_NUMBER_LABEL:
+               FREEandSTRDUP(speeddial->label, str);
+               break;
+       default :
+               CTS_ERR("This field(%d) is not supported in value(speeddial)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
diff --git a/common/ctsvc_record_updated_info.c b/common/ctsvc_record_updated_info.c
new file mode 100755 (executable)
index 0000000..1378c2d
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <glib.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_record.h"
+#include "ctsvc_view.h"
+
+static int __ctsvc_updated_info_create(contacts_record_h* out_record);
+static int __ctsvc_updated_info_destroy(contacts_record_h record, bool delete_child);
+static int __ctsvc_updated_info_clone(contacts_record_h record, contacts_record_h *out_record);
+static int __ctsvc_updated_info_get_int(contacts_record_h record, unsigned int property_id, int *out);
+static int __ctsvc_updated_info_set_int(contacts_record_h record, unsigned int property_id, int value);
+static int __ctsvc_updated_info_get_bool(contacts_record_h record, unsigned int property_id, bool *out);
+static int __ctsvc_updated_info_set_bool(contacts_record_h record, unsigned int property_id, bool value);
+
+ctsvc_record_plugin_cb_s updated_info_plugin_cbs = {
+       .create = __ctsvc_updated_info_create,
+       .destroy = __ctsvc_updated_info_destroy,
+       .clone = __ctsvc_updated_info_clone,
+       .get_str = NULL,
+       .get_str_p = NULL,
+       .get_int = __ctsvc_updated_info_get_int,
+       .get_bool = __ctsvc_updated_info_get_bool,
+       .get_lli = NULL,
+       .get_double = NULL,
+       .set_str = NULL,
+       .set_int = __ctsvc_updated_info_set_int,
+       .set_bool = __ctsvc_updated_info_set_bool,
+       .set_lli = NULL,
+       .set_double = NULL,
+       .add_child_record = NULL,
+       .remove_child_record = NULL,
+       .get_child_record_count = NULL,
+       .get_child_record_at_p = NULL,
+       .clone_child_record_list = NULL,
+};
+
+static int __ctsvc_updated_info_create(contacts_record_h* out_record)
+{
+       ctsvc_updated_info_s *updated_info;
+       updated_info = (ctsvc_updated_info_s*)calloc(1, sizeof(ctsvc_updated_info_s));
+       RETVM_IF(NULL == updated_info, CONTACTS_ERROR_OUT_OF_MEMORY,
+                       "Out of memory calloc is failed");
+
+       *out_record = (contacts_record_h)updated_info;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_updated_info_destroy(contacts_record_h record, bool delete_child)
+{
+       ctsvc_updated_info_s* updated_info = (ctsvc_updated_info_s*)record;
+       updated_info->base.plugin_cbs = NULL;   // help to find double destroy bug (refer to the contacts_record_destroy)
+       free(updated_info->base.properties_flags);
+       free(updated_info);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_updated_info_clone(contacts_record_h record, contacts_record_h *out_record)
+{
+    ctsvc_updated_info_s *out_data = NULL;
+    ctsvc_updated_info_s *src_data = NULL;
+
+    src_data = (ctsvc_updated_info_s*)record;
+    out_data = calloc(1, sizeof(ctsvc_updated_info_s));
+    RETVM_IF(NULL == out_data, CONTACTS_ERROR_OUT_OF_MEMORY,
+                        "Out of memeory : calloc(ctsvc_updated_info_s) Failed(%d)", CONTACTS_ERROR_OUT_OF_MEMORY);
+
+       out_data->id = src_data->id;
+       out_data->changed_type = src_data->changed_type;
+       out_data->changed_ver = src_data->changed_ver;
+       out_data->addressbook_id = src_data->addressbook_id;
+
+       CTSVC_RECORD_COPY_BASE(&(out_data->base), &(src_data->base));
+
+       *out_record = (contacts_record_h)out_data;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_updated_info_get_int(contacts_record_h record, unsigned int property_id, int *out)
+{
+       ctsvc_updated_info_s* updated_info = (ctsvc_updated_info_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_UPDATE_INFO_ID :
+               *out = updated_info->id;
+               break;
+       case CTSVC_PROPERTY_UPDATE_INFO_ADDRESSBOOK_ID:
+               *out = updated_info->addressbook_id;
+               break;
+       case CTSVC_PROPERTY_UPDATE_INFO_TYPE:
+               *out = updated_info->changed_type;
+               break;
+       case CTSVC_PROPERTY_UPDATE_INFO_VERSION:
+               *out = updated_info->changed_ver;
+               break;
+       case CTSVC_PROPERTY_UPDATE_INFO_LAST_CHANGED_TYPE:
+               *out = updated_info->last_changed_type;
+               break;
+       default:
+               CTS_ERR("This field(%d) is not supported in value(updated_info)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_updated_info_set_int(contacts_record_h record, unsigned int property_id, int value)
+{
+       ctsvc_updated_info_s* updated_info = (ctsvc_updated_info_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_UPDATE_INFO_ID :
+               updated_info->id = value;
+               break;
+       case CTSVC_PROPERTY_UPDATE_INFO_ADDRESSBOOK_ID:
+               updated_info->addressbook_id = value;
+               break;
+       case CTSVC_PROPERTY_UPDATE_INFO_TYPE:
+               RETVM_IF(value < CONTACTS_CHANGE_INSERTED
+                                               || value > CONTACTS_CHANGE_DELETED,
+                               CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : update info type is in invalid range (%d)", value);
+               updated_info->changed_type = value;
+               break;
+       case CTSVC_PROPERTY_UPDATE_INFO_VERSION:
+               updated_info->changed_ver = value;
+               break;
+       case CTSVC_PROPERTY_UPDATE_INFO_LAST_CHANGED_TYPE:
+               updated_info->last_changed_type = value;
+               break;
+       default:
+               CTS_ERR("This field(%d) is not supported in value(updated_info)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_updated_info_get_bool(contacts_record_h record, unsigned int property_id, bool *out)
+{
+       ctsvc_updated_info_s* updated_info = (ctsvc_updated_info_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_UPDATE_INFO_IMAGE_CHANGED :
+               *out = updated_info->image_changed;
+               break;
+       default:
+               CTS_ERR("This field(%d) is not supported in value(updated_info)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_updated_info_set_bool(contacts_record_h record, unsigned int property_id, bool value)
+{
+       ctsvc_updated_info_s* updated_info = (ctsvc_updated_info_s*)record;
+
+       switch(property_id) {
+       case CTSVC_PROPERTY_UPDATE_INFO_IMAGE_CHANGED :
+               updated_info->image_changed = value;
+               break;
+       default:
+               CTS_ERR("This field(%d) is not supported in value(updated_info)", property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/common/ctsvc_sim.c b/common/ctsvc_sim.c
new file mode 100644 (file)
index 0000000..c35e62f
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_mutex.h"
+#include "ctsvc_socket.h"
+
+API int contacts_sim_import_all_contacts()
+{
+#ifndef ENABLE_SIM_FEATURE
+       return CONTACTS_ERROR_NOT_SUPPORTED;
+#endif // ENABLE_SIM_FEATURE
+
+       int ret;
+
+       ctsvc_mutex_lock(CTS_MUTEX_SOCKET_FD);
+       ret = ctsvc_request_sim_import(0);
+       ctsvc_mutex_unlock(CTS_MUTEX_SOCKET_FD);
+
+       return ret;
+}
+
+API int contacts_sim_get_initialization_status(bool *completed)
+{
+#ifndef ENABLE_SIM_FEATURE
+       return CONTACTS_ERROR_NOT_SUPPORTED;
+#endif // ENABLE_SIM_FEATURE
+
+       int ret;
+
+       RETVM_IF(completed == NULL, CONTACTS_ERROR_INVALID_PARAMETER,
+                                       "parameter is NULL");
+       ctsvc_mutex_lock(CTS_MUTEX_SOCKET_FD);
+       ret = ctsvc_request_sim_get_initialization_status(0, completed);
+       ctsvc_mutex_unlock(CTS_MUTEX_SOCKET_FD);
+
+       return ret;
+}
+
diff --git a/common/ctsvc_socket.c b/common/ctsvc_socket.c
new file mode 100644 (file)
index 0000000..53ecb81
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ *
+ * 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 <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_socket.h"
+#include "ctsvc_mutex.h"
+#include "ctsvc_inotify.h"
+
+static int __ctsvc_conn_refcnt = 0;
+static int __ctsvc_sockfd = -1;
+
+int ctsvc_socket_init(void)
+{
+       int ret;
+       struct sockaddr_un caddr;
+
+       if (0 < __ctsvc_conn_refcnt) {
+               __ctsvc_conn_refcnt++;
+               return  CONTACTS_ERROR_NONE;
+       }
+
+       bzero(&caddr, sizeof(caddr));
+       caddr.sun_family = AF_UNIX;
+       snprintf(caddr.sun_path, sizeof(caddr.sun_path), "%s", CTSVC_SOCKET_PATH);
+
+       __ctsvc_sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
+       RETVM_IF(-1 == __ctsvc_sockfd, CONTACTS_ERROR_IPC,
+                       "socket() Failed(errno = %d)", errno);
+
+       ret = connect(__ctsvc_sockfd, (struct sockaddr *)&caddr, sizeof(caddr));
+       if (-1 == ret) {
+               CTS_ERR("connect() Failed(errno = %d)", errno);
+               close(__ctsvc_sockfd);
+               __ctsvc_sockfd = -1;
+               return CONTACTS_ERROR_IPC;
+       }
+
+       __ctsvc_conn_refcnt++;
+       return CONTACTS_ERROR_NONE;
+}
+
+void ctsvc_socket_final(void)
+{
+       if (1 < __ctsvc_conn_refcnt) {
+               CTS_DBG("socket ref count : %d", __ctsvc_conn_refcnt);
+               __ctsvc_conn_refcnt--;
+               return;
+       }
+       else if (__ctsvc_conn_refcnt < 1) {
+               CTS_DBG("Please call connection API. socket ref count : %d", __ctsvc_conn_refcnt);
+               return;
+       }
+       __ctsvc_conn_refcnt--;
+
+       close(__ctsvc_sockfd);
+       __ctsvc_sockfd = -1;
+}
+
+static inline int __ctsvc_safe_write(int fd, const char *buf, int buf_size)
+{
+       int ret, writed=0;
+       while (buf_size) {
+               ret = write(fd, buf+writed, buf_size);
+               if (-1 == ret) {
+                       if (EINTR == errno)
+                               continue;
+                       else
+                               return ret;
+               }
+               writed += ret;
+               buf_size -= ret;
+       }
+       return writed;
+}
+
+static inline int __ctsvc_safe_read(int fd, char *buf, int buf_size)
+{
+       int ret, read_size=0;
+       while (buf_size) {
+               ret = read(fd, buf+read_size, buf_size);
+               if (-1 == ret) {
+                       if (EINTR == errno)
+                               continue;
+                       else
+                               return ret;
+               }
+               read_size += ret;
+               buf_size -= ret;
+       }
+       return read_size;
+}
+
+#ifdef ENABLE_SIM_FEATURE
+static int __ctsvc_socket_handle_return(int fd, ctsvc_socket_msg_s *msg)
+{
+       CTS_FN_CALL;
+       int ret;
+
+       ret = __ctsvc_safe_read(fd, (char *)msg, sizeof(ctsvc_socket_msg_s));
+       RETVM_IF(-1 == ret, CONTACTS_ERROR_IPC, "__ctsvc_safe_read() Failed(errno = %d)", errno);
+
+       WARN_IF(CTSVC_SOCKET_MSG_TYPE_REQUEST_RETURN_VALUE != msg->type,
+                       "Unknown Type(%d), ret=%d, attach_num= %d,"
+                       "attach1 = %d, attach2 = %d, attach3 = %d, attach4 = %d",
+                       msg->type, msg->val, msg->attach_num,
+                       msg->attach_sizes[0],msg->attach_sizes[1],msg->attach_sizes[2],
+                       msg->attach_sizes[3]);
+
+       RETVM_IF(CTSVC_SOCKET_MSG_REQUEST_MAX_ATTACH < msg->attach_num, CONTACTS_ERROR_IPC,
+                       "Invalid msg(attach_num = %d)", msg->attach_num);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static void __ctsvc_remove_invalid_msg(int fd, int size)
+{
+       int ret;
+       char dummy[CTSVC_SOCKET_MSG_SIZE] = {0};
+
+       while (size) {
+               if (sizeof(dummy) < size) {
+                       ret = read(fd, dummy, sizeof(dummy));
+                       if (-1 == ret) {
+                               if (EINTR == errno)
+                                       continue;
+                               else
+                                       return;
+                       }
+                       size -= ret;
+               }
+               else {
+                       ret = read(fd, dummy, size);
+                       if (-1 == ret) {
+                               if (EINTR == errno)
+                                       continue;
+                               else
+                                       return;
+                       }
+                       size -= ret;
+               }
+       }
+}
+
+int ctsvc_request_sim_import(int sim_slot_no)
+{
+       int i, ret;
+       ctsvc_socket_msg_s msg = {0};
+       char src[64] = {0};
+
+       RETVM_IF(-1 == __ctsvc_sockfd, CONTACTS_ERROR_IPC, "socket is not connected");
+
+       msg.type = CTSVC_SOCKET_MSG_TYPE_REQUEST_IMPORT_SIM;
+
+       snprintf(src, sizeof(src), "%d", sim_slot_no);
+       msg.attach_num = 1;
+       msg.attach_sizes[0] = strlen(src);
+
+       ret = __ctsvc_safe_write(__ctsvc_sockfd, (char *)&msg, sizeof(msg));
+       RETVM_IF(-1 == ret, CONTACTS_ERROR_IPC, "__ctsvc_safe_write() Failed(errno = %d)", errno);
+
+       ret = __ctsvc_safe_write(__ctsvc_sockfd, src, msg.attach_sizes[0]);
+       RETVM_IF(-1 == ret, CONTACTS_ERROR_IPC, "__ctsvc_safe_write() Failed(errno = %d)", errno);
+
+       ret = __ctsvc_socket_handle_return(__ctsvc_sockfd, &msg);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_socket_handle_return() Failed(%d)", ret);
+       CTS_DBG("attach_num = %d", msg.attach_num);
+
+       for (i=0;i<msg.attach_num;i++)
+               __ctsvc_remove_invalid_msg(__ctsvc_sockfd, msg.attach_sizes[i]);
+
+       return msg.val;
+}
+
+int ctsvc_request_sim_get_initialization_status(int sim_slot_no, bool *completed)
+{
+       int ret = 0;
+       ctsvc_socket_msg_s msg = {0};
+       char dest[CTSVC_SOCKET_MSG_SIZE] = {0};
+       char src[64] = {0};
+
+       RETVM_IF(-1 == __ctsvc_sockfd, CONTACTS_ERROR_IPC, "socket is not connected");
+
+       msg.type = CTSVC_SOCKET_MSG_TYPE_REQUEST_SIM_INIT_COMPLETE;
+
+       snprintf(src, sizeof(src), "%d", sim_slot_no);
+       msg.attach_num = 1;
+       msg.attach_sizes[0] = strlen(src);
+
+       ret = __ctsvc_safe_write(__ctsvc_sockfd, (char *)&msg, sizeof(msg));
+       RETVM_IF(-1 == ret, CONTACTS_ERROR_IPC, "__ctsvc_safe_write() Failed(errno = %d)", errno);
+
+       ret = __ctsvc_safe_write(__ctsvc_sockfd, src, msg.attach_sizes[0]);
+       RETVM_IF(-1 == ret, CONTACTS_ERROR_IPC, "__ctsvc_safe_write() Failed(errno = %d)", errno);
+
+       ret = __ctsvc_socket_handle_return(__ctsvc_sockfd, &msg);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_socket_handle_return() Failed(%d)", ret);
+       CTS_DBG("attach_num = %d", msg.attach_num);
+
+       ret = __ctsvc_safe_read(__ctsvc_sockfd, dest, msg.attach_sizes[0]);
+       RETVM_IF(-1 == ret, CONTACTS_ERROR_IPC, "__ctsvc_safe_read() Failed(errno = %d)", errno);
+
+       if(atoi(dest) ==0)
+               *completed = false;
+       else
+               *completed = true;
+
+       CTS_INFO("sim init complete : %d", *completed);
+
+       return msg.val;
+}
+
+#endif // ENABLE_SIM_FEATURE
diff --git a/common/ctsvc_socket.h b/common/ctsvc_socket.h
new file mode 100644 (file)
index 0000000..ad38a33
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 __TIZEN_SOCIAL_CTSVC_SOCKET_H__
+#define __TIZEN_SOCIAL_CTSVC_SOCKET_H__
+
+#include "contacts.h"
+
+#define CTSVC_SOCKET_PATH "/tmp/.contacts-svc.sock"
+#define CTSVC_SOCKET_MSG_SIZE 1024
+
+// for use current contacts-svc-helper daemon
+// Message type
+enum{
+       CTSVC_SOCKET_MSG_TYPE_REQUEST_RETURN_VALUE,
+       CTSVC_SOCKET_MSG_TYPE_REQUEST_IMPORT_SIM,
+       CTSVC_SOCKET_MSG_TYPE_REQUEST_SIM_INIT_COMPLETE,
+};
+
+#define CTSVC_SOCKET_MSG_REQUEST_MAX_ATTACH 5
+
+typedef struct{
+       int type;
+       int val;
+       int attach_num;
+       int attach_sizes[CTSVC_SOCKET_MSG_REQUEST_MAX_ATTACH];
+}ctsvc_socket_msg_s;
+
+#ifdef ENABLE_SIM_FEATURE
+int ctsvc_request_sim_import(int sim_slot_no);
+int ctsvc_request_sim_get_initialization_status(int sim_slot_no, bool* completed);
+#endif // ENABLE_SIM_FEATURE
+
+int ctsvc_socket_init(void);
+void ctsvc_socket_final(void);
+
+#endif /*  __TIZEN_SOCIAL_CTSVC_SOCKET_H__ */
+
diff --git a/common/ctsvc_struct.h b/common/ctsvc_struct.h
new file mode 100644 (file)
index 0000000..f69b654
--- /dev/null
@@ -0,0 +1,609 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 __TIZEN_SOCIAL_CTSVC_STRUCT_H__
+#define __TIZEN_SOCIAL_CTSVC_STRUCT_H__
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <string.h>
+
+#include "contacts_views.h"
+
+#define CTSVC_IMG_FULL_PATH_SIZE_MAX 1024              // current max length file path is 256
+#define CTSVC_IMG_FULL_LOCATION "/opt/usr/data/contacts-svc/img"
+#define CTSVC_CONTACT_IMG_FULL_LOCATION "/opt/usr/data/contacts-svc/img/contact"
+
+#define SAFE_STR(src) (src)?src:""
+#define SAFE_STRDUP(src) (src)?strdup(src):NULL
+#define SAFE_STRLEN(src) ((src)?strlen(src):0)
+#define FREEandSTRDUP(dest, src) \
+       do{ \
+               free(dest);\
+               if (src) dest = strdup(src);\
+               else dest = NULL; \
+       }while (0)
+#define GET_STR(copy, str)     (copy)?(SAFE_STRDUP(str)):(str)
+
+enum {
+       CTSVC_DATA_NAME = 1,
+       CTSVC_DATA_POSTAL = 2,
+       CTSVC_DATA_MESSENGER = 3,
+       CTSVC_DATA_URL = 4,
+       CTSVC_DATA_EVENT = 5,
+       CTSVC_DATA_COMPANY = 6,
+       CTSVC_DATA_NICKNAME = 7,
+       CTSVC_DATA_NUMBER = 8,
+       CTSVC_DATA_EMAIL = 9,
+       CTSVC_DATA_PROFILE = 10,
+       CTSVC_DATA_RELATIONSHIP = 11,
+       CTSVC_DATA_NOTE = 12,
+       CTSVC_DATA_IMAGE = 13,
+       CTSVC_DATA_EXTENSION = 100
+};
+
+enum {
+       CTSVC_PERMISSION_CONTACT_NONE = 0x0,
+       CTSVC_PERMISSION_CONTACT_READ = 0x1,
+       CTSVC_PERMISSION_CONTACT_WRITE = 0x2,
+       CTSVC_PERMISSION_PHONELOG_READ = 0x4,
+       CTSVC_PERMISSION_PHONELOG_WRITE = 0x8,
+};
+
+typedef enum {
+       CTSVC_RECORD_INVALID = -1,
+       CTSVC_RECORD_ADDRESSBOOK,
+       CTSVC_RECORD_GROUP,
+       CTSVC_RECORD_PERSON,
+       CTSVC_RECORD_CONTACT,
+       CTSVC_RECORD_MY_PROFILE,
+       CTSVC_RECORD_SIMPLE_CONTACT,
+       CTSVC_RECORD_NAME,
+       CTSVC_RECORD_COMPANY,
+       CTSVC_RECORD_NOTE,
+       CTSVC_RECORD_NUMBER,
+       CTSVC_RECORD_EMAIL,
+       CTSVC_RECORD_URL,
+       CTSVC_RECORD_EVENT,
+       CTSVC_RECORD_NICKNAME,
+       CTSVC_RECORD_ADDRESS,
+       CTSVC_RECORD_MESSENGER,
+       CTSVC_RECORD_GROUP_RELATION,
+       CTSVC_RECORD_ACTIVITY,
+       CTSVC_RECORD_ACTIVITY_PHOTO,
+       CTSVC_RECORD_PROFILE,
+       CTSVC_RECORD_RELATIONSHIP,
+       CTSVC_RECORD_IMAGE,
+       CTSVC_RECORD_EXTENSION,
+       CTSVC_RECORD_UPDATED_INFO,
+       CTSVC_RECORD_PHONELOG,
+       CTSVC_RECORD_SPEEDDIAL,
+       CTSVC_RECORD_SDN,
+       CTSVC_RECORD_RESULT,
+}ctsvc_record_type_e;
+
+typedef enum {
+       CTSVC_FILTER_BOOL,
+       CTSVC_FILTER_INT,
+       CTSVC_FILTER_LLI,
+       CTSVC_FILTER_STR,
+       CTSVC_FILTER_DOUBLE,
+       CTSVC_FILTER_COMPOSITE,
+}ctsvc_filter_type_e;
+
+typedef struct{
+       unsigned int property_id;
+       int property_type;
+       void* fields;
+}property_info_s;
+
+typedef int (*__ctsvc_record_create_cb)(contacts_record_h* out_record);
+typedef int (*__ctsvc_record_destroy_cb)(contacts_record_h record, bool delete_child );
+typedef int (*__ctsvc_record_clone_cb)(contacts_record_h record, contacts_record_h* out_record);
+
+typedef int (*__ctsvc_record_get_str_cb)(contacts_record_h record, unsigned int property_id,char** out_str);
+typedef int (*__ctsvc_record_get_str_p_cb)(contacts_record_h record, unsigned int property_id,char** out_str);
+typedef int (*__ctsvc_record_get_int_cb)(contacts_record_h record, unsigned int property_id, int* out_value);
+typedef int (*__ctsvc_record_get_bool_cb)(contacts_record_h record, unsigned int property_id, bool *value);
+typedef int (*__ctsvc_record_get_lli_cb)(contacts_record_h record, unsigned int property_id, long long int *value);
+typedef int (*__ctsvc_record_get_double_cb)(contacts_record_h record, unsigned int property_id, double *value);
+
+typedef int (*__ctsvc_record_set_str_cb)(contacts_record_h record, unsigned int property_id, const char* value);
+typedef int (*__ctsvc_record_set_int_cb)(contacts_record_h record, unsigned int property_id, int value);
+typedef int (*__ctsvc_record_set_bool_cb)(contacts_record_h record, unsigned int property_id, bool value);
+typedef int (*__ctsvc_record_set_lli_cb)(contacts_record_h record, unsigned int property_id, long long int value);
+typedef int (*__ctsvc_record_set_double_cb)(contacts_record_h record, unsigned int property_id, double value);
+
+typedef int (*__ctsvc_record_add_child_record_cb)(contacts_record_h record, unsigned int property_id, contacts_record_h child_record);
+typedef int (*__ctsvc_record_remove_child_record_cb)(contacts_record_h record, unsigned int property_id, contacts_record_h child_record);
+typedef int (*__ctsvc_record_get_child_record_count_cb)(contacts_record_h record, unsigned int property_id, int *count);
+typedef int (*__ctsvc_record_get_child_record_at_p_cb)(contacts_record_h record, unsigned int property_id, int index, contacts_record_h* out_record);
+typedef int (*__ctsvc_record_clone_child_record_list_cb)(contacts_record_h record, unsigned int property_id, contacts_list_h* out_list);
+
+typedef struct {
+       __ctsvc_record_create_cb create;
+       __ctsvc_record_destroy_cb destroy;
+       __ctsvc_record_clone_cb clone;
+       __ctsvc_record_get_str_cb get_str;
+       __ctsvc_record_get_str_p_cb get_str_p;
+       __ctsvc_record_get_int_cb get_int;
+       __ctsvc_record_get_bool_cb get_bool;
+       __ctsvc_record_get_lli_cb get_lli;
+       __ctsvc_record_get_double_cb get_double;
+       __ctsvc_record_set_str_cb set_str;
+       __ctsvc_record_set_int_cb set_int;
+       __ctsvc_record_set_bool_cb set_bool;
+       __ctsvc_record_set_lli_cb set_lli;
+       __ctsvc_record_set_double_cb set_double;
+       __ctsvc_record_add_child_record_cb add_child_record;
+       __ctsvc_record_remove_child_record_cb remove_child_record;
+       __ctsvc_record_get_child_record_count_cb get_child_record_count;
+       __ctsvc_record_get_child_record_at_p_cb get_child_record_at_p;
+       __ctsvc_record_clone_child_record_list_cb clone_child_record_list;
+}ctsvc_record_plugin_cb_s;
+
+typedef struct {
+       int r_type;
+       const ctsvc_record_plugin_cb_s *plugin_cbs;
+       const char* view_uri;
+       unsigned int property_max_count;
+       unsigned char* properties_flags;
+       unsigned char property_flag;
+}ctsvc_record_s;
+
+typedef struct  {
+       int filter_type;
+}ctsvc_filter_s;
+
+typedef struct {
+       int filter_type;
+       char *view_uri;
+       GSList *filter_ops;     //ctsvc_filter_operator_e op;
+       GSList *filters;        //ctsvc_filter_h l_filter;
+       property_info_s *properties;
+       unsigned int property_count;
+}ctsvc_composite_filter_s;
+
+typedef struct  {
+       int filter_type;
+       int property_id;
+       int match;
+       union {
+               bool b;
+               int i;
+               char *s;
+               long long int l;
+               double d;
+       }value;
+}ctsvc_attribute_filter_s;
+
+typedef struct  {
+       char* view_uri;
+       ctsvc_composite_filter_s *filter;
+       unsigned int *projection;
+       unsigned int projection_count;
+       unsigned int sort_property_id;
+       bool sort_asc;
+       property_info_s *properties;
+       unsigned int property_count;
+       bool distinct;
+}ctsvc_query_s;
+
+typedef struct {
+       int l_type;
+       int count;
+       GList *records;
+       GList *deleted_records;
+       GList *cursor;
+}ctsvc_list_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       char *name;
+       int account_id;
+       int mode;
+}ctsvc_addressbook_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       int addressbook_id;
+       bool is_read_only;
+       char *name;
+       char *extra_data;
+       char *ringtone_path;
+       char *vibration;
+       char *image_thumbnail_path;
+       char *message_alert;
+}ctsvc_group_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       bool is_favorite;
+       bool has_phonenumber;
+       bool has_email;
+       int person_id;
+       int name_contact_id;
+       char *display_name;
+       char *display_name_index;
+       char *image_thumbnail_path;
+       char *ringtone_path;
+       char *vibration;
+       char *message_alert;
+       char *status;
+       int link_count;
+       char *addressbook_ids;
+}ctsvc_person_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       bool is_favorite;
+       int changed_time;
+       bool has_phonenumber;
+       bool has_email;
+       int person_id;
+       int contact_id;
+       int addressbook_id;
+       char *image_thumbnail_path;
+       char *ringtone_path;
+       char *vibration;
+       char *message_alert;
+       char *display_name;
+       char *uid;
+       int display_source_type;
+}ctsvc_simple_contact_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       bool is_default;
+       int id;
+       int contact_id;
+       int language_type;
+       char *first;
+       char *last;
+       char *addition;
+       char *prefix;
+       char *suffix;
+       char *phonetic_first;
+       char *phonetic_middle;
+       char *phonetic_last;
+       char *lookup;
+       char *reverse_lookup;
+}ctsvc_name_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       bool is_default;
+       int id;
+       int contact_id;
+       int type;
+       char *label;
+       char *number;
+       char *cleaned;          // internally used
+       char *normalized;       // internally used
+       char *lookup;           // internally used : for min match
+}ctsvc_number_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       bool is_default;
+       int id;
+       int contact_id;
+       int type;
+       char *label;
+       char *email_addr;
+}ctsvc_email_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       int contact_id;
+       int type;
+       char *label;
+       char *url;
+}ctsvc_url_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       bool is_default;
+       int id;
+       int contact_id;
+       int type;
+       char *label;
+       char *pobox;
+       char *postalcode;
+       char *region;
+       char *locality;
+       char *street;
+       char *extended;
+       char *country;
+}ctsvc_address_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       int contact_id;
+       int type;
+       char *label;
+       int date;
+       bool is_leap_month;
+       int calendar_type;
+}ctsvc_event_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       int contact_id;
+       int type;
+       char *label;
+       char *im_id;
+}ctsvc_messenger_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       int contact_id;
+       int group_id;
+       char *group_name;
+}ctsvc_group_relation_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       int contact_id;
+       int type;
+       char *label;
+       char *nickname;
+}ctsvc_nickname_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       int contact_id;
+       char *uid;
+       char *text;
+       int  order;
+       char *service_operation;
+       char *mime;
+       char *app_id;
+       char *uri;
+       char *category;
+       char *extra_data;
+}ctsvc_profile_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       int contact_id;
+       int type;
+       char *label;
+       char *name;
+}ctsvc_relationship_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       bool is_vcard;
+       bool is_default;
+       int id;
+       int contact_id;
+       int type;
+       char *label;
+       char *path;
+}ctsvc_image_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       int contact_id;
+       char *note;
+}ctsvc_note_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       int contact_id;
+       char *source_name;
+       char *status;
+       int timestamp;
+       ctsvc_list_s* photos;
+       char *service_operation;
+       char *uri;
+}ctsvc_activity_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       int activity_id;
+       char *photo_url;
+       int     sort_index;
+}ctsvc_activity_photo_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       int contact_id;
+       bool is_default;
+       bool is_vcard;
+       int type;
+       char *label;
+       char *name;
+       char *department;
+       char *job_title;
+       char *role;
+       char *assistant_name;
+       char *logo;
+       char *location;
+       char *description;
+       char *phonetic_name;
+}ctsvc_company_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       char *address;
+       int person_id; /* person id */
+       int log_time;
+       int log_type;
+       int extra_data1; /* duration, message_id */
+       char *extra_data2; /*short message*/
+       int sim_slot_no;
+}ctsvc_phonelog_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       int contact_id;
+       int data1;
+       char *data2;
+       char *data3;
+       char *data4;
+       char *data5;
+       char *data6;
+       char *data7;
+       char *data8;
+       char *data9;
+       char *data10;
+       char *data11;
+       char *data12;
+}ctsvc_extension_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       bool is_favorite;
+       int id;
+       int person_id;
+       int changed_time;
+       int changed_ver;                // internally used, check when updating contact
+       int addressbook_id;
+       int link_mode;
+       bool has_phonenumber;
+       bool has_email;
+       char *display_name;
+       char *reverse_display_name;
+       int display_source_type;
+       int display_name_language;
+       int reverse_display_name_language;
+       char *sort_name;
+       char *reverse_sort_name;
+       char *sortkey;
+       char *reverse_sortkey;
+       char *uid;
+       char *image_thumbnail_path;
+       char *ringtone_path;
+       char *vibration;
+       char *message_alert;
+       ctsvc_list_s* name;
+       ctsvc_list_s* note;
+       ctsvc_list_s* company;
+       ctsvc_list_s* numbers;
+       ctsvc_list_s* emails;
+       ctsvc_list_s* grouprelations;
+       ctsvc_list_s* events;
+       ctsvc_list_s* messengers;
+       ctsvc_list_s* postal_addrs;
+       ctsvc_list_s* urls;
+       ctsvc_list_s* nicknames;
+       ctsvc_list_s* profiles;
+       ctsvc_list_s* relationships;
+       ctsvc_list_s* images;
+       ctsvc_list_s* extensions;
+}ctsvc_contact_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       int addressbook_id;
+       int changed_time;
+       char *display_name;
+       char *reverse_display_name;
+       char *uid;
+       char *image_thumbnail_path;
+       ctsvc_list_s* name;
+       ctsvc_list_s* note;
+       ctsvc_list_s* company;
+       ctsvc_list_s* numbers;
+       ctsvc_list_s* emails;
+       ctsvc_list_s* events;
+       ctsvc_list_s* messengers;
+       ctsvc_list_s* postal_addrs;
+       ctsvc_list_s* urls;
+       ctsvc_list_s* nicknames;
+       ctsvc_list_s* profiles;
+       ctsvc_list_s* relationships;
+       ctsvc_list_s* images;
+       ctsvc_list_s* extensions;
+}ctsvc_my_profile_s;
+
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       char *name;
+       char *number;
+       int sim_slot_no;
+}ctsvc_sdn_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int changed_type;
+       int id;
+       int changed_ver;
+       int addressbook_id;
+       bool image_changed;
+       int last_changed_type;  // it is used for _contacts_my_profile_updated_info
+}ctsvc_updated_info_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       int id;
+       int number_id;
+       int person_id;
+       char *display_name;
+       char *image_thumbnail_path;
+       int number_type;
+       char *label;
+       char *number;
+       int dial_number;
+}ctsvc_speeddial_s;
+
+typedef struct {
+       int property_id;
+       int type;
+       union {
+               bool b;
+               int i;
+               char *s;
+               long long int l;
+               double d;
+       }value;
+}ctsvc_result_value_s;
+
+typedef struct {
+       ctsvc_record_s base;
+       GSList *values;
+}ctsvc_result_s;
+
+
+#endif /* __TIZEN_SOCIAL_CTSVC_STRUCT_H__ */
diff --git a/common/ctsvc_vcard.c b/common/ctsvc_vcard.c
new file mode 100644 (file)
index 0000000..6494a53
--- /dev/null
@@ -0,0 +1,4500 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+#include <errno.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <unicode/ucnv.h>
+#include <unicode/ustring.h>
+
+#ifdef _CONTACTS_IPC_CLIENT
+#include <pims-ipc.h>
+#include "ctsvc_client_ipc.h"
+#endif
+
+#include "contacts.h"
+#include "ctsvc_vcard.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_record.h"
+#include "ctsvc_list.h"
+#include "ctsvc_localize_utils.h"
+
+#define DEFAULT_ADDRESS_BOOK_ID 0
+
+#define SMART_STRDUP(src) (src && *src)?strdup(src):NULL
+#define CTSVC_VCARD_PHOTO_MAX_SIZE 1024*1024
+#define CTSVC_VCARD_IMAGE_LOCATION "/opt/usr/data/contacts-svc/img/vcard"
+
+#define CTSVC_VCARD_APPEND_STR(buf, buf_size, len, str) do { \
+       if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, str, false)) < 0) { \
+               CTS_ERR("__ctsvc_vcard_append_str() Failed"); \
+               return CONTACTS_ERROR_OUT_OF_MEMORY; \
+       } \
+} while (0)
+
+#define CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, content) do { \
+       if ((len = __ctsvc_vcard_append_str(buf, buf_size, len, content, true)) < 0) { \
+               ERR("__ctsvc_vcard_append_str() Failed"); \
+               return CONTACTS_ERROR_OUT_OF_MEMORY; \
+       } \
+} while (0)
+
+
+#define CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, content) do { \
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";CHARSET=UTF-8"); \
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ":"); \
+       CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, content); \
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF); \
+} while (0)
+
+enum {
+       CTSVC_VCARD_VER_NONE,
+       CTSVC_VCARD_VER_2_1,
+       CTSVC_VCARD_VER_3_0,
+       CTSVC_VCARD_VER_4_0,
+};
+
+enum {
+       CTSVC_VCARD_VALUE_NONE,
+       CTSVC_VCARD_VALUE_FN,
+       CTSVC_VCARD_VALUE_N,
+       CTSVC_VCARD_VALUE_PHONETIC_FIRST_NAME,
+       CTSVC_VCARD_VALUE_PHONETIC_MIDDLE_NAME,
+       CTSVC_VCARD_VALUE_PHONETIC_LAST_NAME,
+       CTSVC_VCARD_VALUE_NICKNAME,
+       CTSVC_VCARD_VALUE_PHOTO,
+       CTSVC_VCARD_VALUE_BDAY,
+       CTSVC_VCARD_VALUE_X_ANNIVERSARY,
+       CTSVC_VCARD_VALUE_X_TIZEN_EVENT,
+       CTSVC_VCARD_VALUE_ADR,
+       CTSVC_VCARD_VALUE_TEL,
+       CTSVC_VCARD_VALUE_EMAIL,
+       CTSVC_VCARD_VALUE_TITLE,
+       CTSVC_VCARD_VALUE_ROLE,
+       CTSVC_VCARD_VALUE_LOGO,
+       CTSVC_VCARD_VALUE_ORG,
+       CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_LOCATION,
+       CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_DESCRIPTION,
+       CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_PHONETIC_NAME,
+       CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_ASSISTANT_NAME,
+       CTSVC_VCARD_VALUE_NOTE,
+       CTSVC_VCARD_VALUE_REV,
+       CTSVC_VCARD_VALUE_UID,
+       CTSVC_VCARD_VALUE_URL,
+       CTSVC_VCARD_VALUE_X_MSN,
+       CTSVC_VCARD_VALUE_X_YAHOO,
+       CTSVC_VCARD_VALUE_X_ICQ,
+       CTSVC_VCARD_VALUE_X_AIM,
+       CTSVC_VCARD_VALUE_X_JABBER,
+       CTSVC_VCARD_VALUE_X_SKYPE_USERNAME,
+       CTSVC_VCARD_VALUE_X_SKYPE,
+       CTSVC_VCARD_VALUE_X_QQ,
+       CTSVC_VCARD_VALUE_X_GOOGLE_TALK,
+       CTSVC_VCARD_VALUE_X_TIZEN_MESSENGER,
+       CTSVC_VCARD_VALUE_X_TIZEN_RELATIONSHIP,
+       CTSVC_VCARD_VALUE_END,
+       CTSVC_VCARD_VALUE_MAX
+};
+
+enum{
+       CTSVC_VCARD_IMG_NONE,
+       CTSVC_VCARD_IMG_PNG,            // Portable Network Graphics
+       // vcard  2.1 spec
+       CTSVC_VCARD_IMG_JPEG,   // ISO JPEG format
+       CTSVC_VCARD_IMG_GIF,            //Graphics Interchange Format
+       CTSVC_VCARD_IMG_TIFF,           // Tagged Image File Format
+       CTSVC_VCARD_IMG_CGM,            //ISO Computer Graphics Metafile
+       CTSVC_VCARD_IMG_WMF,    // MS Windows Metafile
+       CTSVC_VCARD_IMG_BMP,            // MS Windows Bitmap
+       CTSVC_VCARD_IMG_MET,            // IBM PM Metafile
+       CTSVC_VCARD_IMG_PMB,            // IBM PM Bitmap
+       CTSVC_VCARD_IMG_DIB,            // MS Windows DIB
+       CTSVC_VCARD_IMG_PICT,           // Apple Picture format
+       CTSVC_VCARD_IMG_PDF,            // Adobe Page Description Format
+       CTSVC_VCARD_IMG_PS,             // Adobe PostScript format
+       CTSVC_VCARD_IMG_QTIME,  // Apple QuickTime format
+       CTSVC_VCARD_IMG_MPEG,   // ISO MPEG format
+       CTSVC_VCARD_IMG_MPEG2,  // ISO MPEG version 2 format
+       CTSVC_VCARD_IMG_AVI,            // Intel AVI format
+};
+
+static const char *content_name[CTSVC_VCARD_VALUE_MAX] = {0};
+const char *CTSVC_CRLF = "\r\n";
+
+static void __ctsvc_vcard_initial(void)
+{
+       if (NULL == *content_name) {
+               //content_name[CTSVC_VCARD_VALUE_NAME] = "NAME"; /* not supported */
+               //content_name[CTSVC_VCARD_VALUE_PROFILE] = "PROFILE"; /* not supported */
+               //content_name[CTSVC_VCARD_VALUE_SOURCE] = "SOURCE"; /* not supported */
+               content_name[CTSVC_VCARD_VALUE_FN] = "FN";
+               content_name[CTSVC_VCARD_VALUE_N] = "N";
+               content_name[CTSVC_VCARD_VALUE_PHONETIC_FIRST_NAME] = "X-PHONETIC-FIRST-NAME";
+               content_name[CTSVC_VCARD_VALUE_PHONETIC_MIDDLE_NAME] = "X-PHONETIC-MIDDLE-NAME";
+               content_name[CTSVC_VCARD_VALUE_PHONETIC_LAST_NAME] = "X-PHONETIC-LAST-NAME";
+               content_name[CTSVC_VCARD_VALUE_NICKNAME] = "NICKNAME";
+               content_name[CTSVC_VCARD_VALUE_PHOTO] = "PHOTO";
+               content_name[CTSVC_VCARD_VALUE_BDAY] = "BDAY";
+               content_name[CTSVC_VCARD_VALUE_X_ANNIVERSARY] = "ANNIVERSARY";
+               content_name[CTSVC_VCARD_VALUE_X_TIZEN_EVENT] = "X-TIZEN-EVENT";
+               content_name[CTSVC_VCARD_VALUE_ADR] = "ADR";
+               //content_name[CTSVC_VCARD_VALUE_LABEL] = "LABEL"; /* not supported */
+               content_name[CTSVC_VCARD_VALUE_TEL] = "TEL";
+               content_name[CTSVC_VCARD_VALUE_EMAIL] = "EMAIL";
+               //content_name[CTSVC_VCARD_VALUE_MAILER] = "MAILER"; /* not supported */
+               //content_name[CTSVC_VCARD_VALUE_TZ] = "TZ"; /* not supported */
+               //content_name[CTSVC_VCARD_VALUE_GEO] = "GEO"; /* not supported */
+               content_name[CTSVC_VCARD_VALUE_TITLE] = "TITLE";
+               content_name[CTSVC_VCARD_VALUE_ROLE] = "ROLE";
+               content_name[CTSVC_VCARD_VALUE_LOGO] = "LOGO";
+               //content_name[CTSVC_VCARD_VALUE_AGENT] = "AGENT"; /* not supported */
+               content_name[CTSVC_VCARD_VALUE_ORG] = "ORG";
+               content_name[CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_LOCATION] = "X-TIZEN-COMPANY-LOCATION";
+               content_name[CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_DESCRIPTION] = "X-TIZEN-COMPANY-DESCRIPTION";
+               content_name[CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_PHONETIC_NAME] = "X-TIZEN-COMPANY-PHONETIC-NAME";
+               content_name[CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_ASSISTANT_NAME] = "X-TIZEN-COMPANY-ASSISTANT-NAME";
+               //content_name[CTSVC_VCARD_VALUE_CATEGORIES] = "CATEGORIES"; /* not supported */
+               content_name[CTSVC_VCARD_VALUE_NOTE] = "NOTE";
+               //content_name[CTSVC_VCARD_VALUE_PRODID] = "PRODID"; /* not supported */
+               content_name[CTSVC_VCARD_VALUE_REV] = "REV";
+               //content_name[CTSVC_VCARD_VALUE_SORT-STRING] = "SORT-STRING"; /* not supported */
+               content_name[CTSVC_VCARD_VALUE_UID] = "UID";
+               content_name[CTSVC_VCARD_VALUE_URL] = "URL";
+               //content_name[CTSVC_VCARD_VALUE_VERSION] = "VERSION"; /* not supported */
+               //content_name[CTSVC_VCARD_VALUE_CLASS] = "CLASS";         /* not supported */
+               //content_name[CTSVC_VCARD_VALUE_KEY] = "KEY"; /* not supported */
+               content_name[CTSVC_VCARD_VALUE_X_MSN] = "X-MSN";
+               content_name[CTSVC_VCARD_VALUE_X_YAHOO] = "X-YAHOO";
+               content_name[CTSVC_VCARD_VALUE_X_ICQ] = "X-ICQ";
+               content_name[CTSVC_VCARD_VALUE_X_AIM] = "X-AIM";
+               content_name[CTSVC_VCARD_VALUE_X_JABBER] = "X-JABBER";
+               content_name[CTSVC_VCARD_VALUE_X_SKYPE_USERNAME] = "X-SKYPE-USERNAME";
+               content_name[CTSVC_VCARD_VALUE_X_SKYPE] = "X-SKYPE";
+               content_name[CTSVC_VCARD_VALUE_X_QQ] = "X-QQ";
+               content_name[CTSVC_VCARD_VALUE_X_GOOGLE_TALK] = "X-GOOGLE-TALK";
+               content_name[CTSVC_VCARD_VALUE_X_TIZEN_MESSENGER] = "X-TIZEN-MESSENGER";
+               content_name[CTSVC_VCARD_VALUE_X_TIZEN_RELATIONSHIP] = "X-TIZEN-RELATIONSHIP";
+               //content_name[CTSVC_VCARD_VALUE_X_CHILDREN] = "X-CHILDREN";
+               content_name[CTSVC_VCARD_VALUE_END] = "END";
+       }
+};
+
+static int __ctsvc_vcard_append_str(char **buf, int *buf_size, int len, const char *str, bool need_conversion)
+{
+       int len_temp = 0;
+       char *tmp = NULL;
+       const char *safe_str = SAFE_STR(str);
+       int str_len = 0;
+       bool need_realloc = false;
+
+       str_len = strlen(safe_str);
+       while ((*buf_size-len) < (str_len+1)) {
+               *buf_size = *buf_size * 2;
+               need_realloc = true;
+       }
+
+       if (need_realloc) {
+               if (NULL == (tmp = realloc(*buf, *buf_size)))
+                       return -1;
+               else
+                       *buf = tmp;
+       }
+
+       if (need_conversion) {
+               const char *s = safe_str;
+               char *r = (char *)(*buf+len);
+
+               while (*s) {
+                       switch (*s) {
+                       case '\r':
+                               if (*(s+1) && '\n' == *(s+1)) {
+                                       s++;
+                                       *r = '\\';
+                                       r++;
+                                       *r = 'n';
+                               }
+                               else {
+                                       *r = *s;
+                               }
+                               break;
+                       case '\n':
+                               *r = '\\';
+                               r++;
+                               str_len++;
+                               if (*buf_size<str_len+len+1) {
+                                       *buf_size = *buf_size * 2;
+                                       if (NULL == (tmp = realloc(*buf, *buf_size)))
+                                               return -1;
+                                       else {
+                                               *buf = tmp;
+                                               r = (char *)(*buf+len+str_len);
+                                       }
+                               }
+                               *r = 'n';
+                               break;
+                       case ';':
+                       case ':':
+                       case ',':
+                       case '<':
+                       case '>':
+                       case '\\':
+                               *r = '\\';
+                               r++;
+                               str_len++;
+                               if (*buf_size<str_len+len+1) {
+                                       *buf_size = *buf_size * 2;
+                                       if (NULL == (tmp = realloc(*buf, *buf_size)))
+                                               return -1;
+                                       else {
+                                               *buf = tmp;
+                                               r = (char *)(*buf+len+str_len);
+                                       }
+                               }
+                               *r = *s;
+                               break;
+                       case 0xA1:
+                               if (*(s+1) && 0xAC == *(s+1)) { // en/em backslash
+                                       *r = '\\';
+                                       r++;
+                                       str_len++;
+                                       if (*buf_size<str_len+len+1) {
+                                               *buf_size = *buf_size * 2;
+                                               if (NULL == (tmp = realloc(*buf, *buf_size)))
+                                                       return -1;
+                                               else {
+                                                       *buf = tmp;
+                                                       r = (char *)(*buf+len+str_len);
+                                               }
+                                       }
+
+                                       *r = *s;
+                                       r++;
+                                       s++;
+                                       if (*buf_size<str_len+len+1) {
+                                               *buf_size = *buf_size * 2;
+                                               if (NULL == (tmp = realloc(*buf, *buf_size)))
+                                                       return -1;
+                                               else {
+                                                       *buf = tmp;
+                                                       r = (char *)(*buf+len+str_len);
+                                               }
+                                       }
+                                       *r = *s;
+                               }
+                               else {
+                                       *r = *s;
+                               }
+                               break;
+                       case 0x81:
+                               if (*(s+1) && 0x5F == *(s+1)) { // en/em backslash
+                                       *r = '\\';
+                                       r++;
+                                       str_len++;
+                                       if (*buf_size<str_len+len+1) {
+                                               *buf_size = *buf_size * 2;
+                                               if (NULL == (tmp = realloc(*buf, *buf_size)))
+                                                       return -1;
+                                               else {
+                                                       *buf = tmp;
+                                                       r = (char *)(*buf+len+str_len);
+                                               }
+                                       }
+
+                                       *r = *s;
+                                       r++;
+                                       s++;
+                                       if (*buf_size<str_len+len+1) {
+                                               *buf_size = *buf_size * 2;
+                                               if (NULL == (tmp = realloc(*buf, *buf_size)))
+                                                       return -1;
+                                               else {
+                                                       *buf = tmp;
+                                                       r = (char *)(*buf+len+str_len);
+                                               }
+                                       }
+                                       *r = *s;
+                               }
+                               else {
+                                       *r = *s;
+                               }
+                               break;
+                       default:
+                               *r = *s;
+                               break;
+                       }
+                       r++;
+                       s++;
+               }
+               len_temp = str_len;
+       }
+       else {
+               len_temp = snprintf(*buf+len, *buf_size-len+1, "%s", safe_str);
+       }
+       len += len_temp;
+       return len;
+}
+
+#define CTS_VCARD_FOLDING_LIMIT 75
+
+static inline int __ctsvc_vcard_add_folding(char **buf, int *buf_size, int buf_len)
+{
+       int char_len = 0;
+       char *buf_copy = NULL;
+       int len, result_len;
+       char *r;
+       const char *s;
+       bool content_start = false;
+       bool encode_64 = false;
+
+       buf_copy = calloc(1, *buf_size);
+       RETVM_IF(NULL == buf_copy, -1, "calloc() return NULL");
+
+       s = *buf;
+       r = buf_copy;
+       len = result_len = 0;
+
+       while (*s) {
+               if (*buf_size < result_len + 5) {
+                       char *tmp = NULL;
+                       *buf_size = *buf_size + 1000;
+                       if (NULL == (tmp = realloc(buf_copy, *buf_size))) {
+                               free(buf_copy);
+                               return -1;
+                       }
+                       else {
+                               buf_copy = tmp;
+                               r = (buf_copy + result_len);
+                       }
+               }
+
+               if (false == content_start) {
+                       if (':' == *s)
+                               content_start = true;
+                       else if (0 == strncmp(s, "ENCODING=BASE64", strlen("ENCODING=BASE64")))
+                               encode_64 = true;
+               }
+
+               if ('\r' == *s)
+                       len--;
+               else if ('\n' == *s) {
+                       len = -1;
+                       char_len = 0;
+                       content_start = false;
+                       encode_64 = false;
+               }
+
+               if (0 == char_len) {
+                       if (false == encode_64)
+                               char_len = ctsvc_check_utf8(*s);
+
+                       if (CTS_VCARD_FOLDING_LIMIT <= len + char_len) {
+                               *r = '\r';
+                               r++;
+                               *r = '\n';
+                               r++;
+                               *r = ' ';
+                               r++;
+                               len = 1;
+                               result_len += 3;
+                       }
+               }
+
+               if (char_len)
+                       char_len--;
+
+               *r = *s;
+               r++;
+               s++;
+               len++;
+               result_len++;
+       }
+       *r = '\0';
+       free(*buf);
+       *buf = buf_copy;
+       return result_len;
+}
+
+static inline int __ctsvc_vcard_append_name(ctsvc_list_s *names, char **buf, int *buf_size, int len)
+{
+       char display[1024] = {0};
+       GList *cursor = names->records;
+       ctsvc_name_s *name;
+
+       RETV_IF(NULL == cursor, len);
+
+       name = (ctsvc_name_s *)cursor->data;
+
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_N]);
+
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";CHARSET=UTF-8");
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ":");
+       CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, name->last);
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
+       CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, name->first);
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
+       CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, name->addition);
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
+       CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, name->prefix);
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
+       CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, name->suffix);
+
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
+
+       if (name->first && name->last) {
+               contacts_name_display_order_e order;
+               contacts_setting_get_name_display_order(&order);
+               if (CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST == order) {
+                       snprintf(display, sizeof(display), "%s %s", name->first, name->last);
+               }
+               else {
+                       //CONTACTS_NAME_DISPLAY_ORDER_LASTFIRST
+                       snprintf(display, sizeof(display), "%s, %s", name->last, name->first);
+               }
+       }
+       else
+               snprintf(display, sizeof(display), "%s%s", SAFE_STR(name->first), SAFE_STR(name->last));
+
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_FN]);
+       CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, display);
+
+       if (name->phonetic_first) {
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_PHONETIC_FIRST_NAME]);
+               CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, name->phonetic_first);
+       }
+
+       if (name->phonetic_middle) {
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_PHONETIC_MIDDLE_NAME]);
+               CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, name->phonetic_middle);
+       }
+
+
+       if (name->phonetic_last) {
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_PHONETIC_LAST_NAME]);
+               CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, name->phonetic_last);
+       }
+
+       return len;
+}
+
+static inline const char* __ctsvc_get_img_suffix(int type)
+{
+       switch (type)
+       {
+       case CTSVC_VCARD_IMG_TIFF:
+               return "tiff";
+       case CTSVC_VCARD_IMG_GIF:
+               return "gif";
+       case CTSVC_VCARD_IMG_PNG:
+               return "png";
+       case CTSVC_VCARD_IMG_CGM:
+               return "cgm";
+       case CTSVC_VCARD_IMG_WMF:
+               return "wmf";
+       case CTSVC_VCARD_IMG_BMP:
+               return "bmp";
+       case CTSVC_VCARD_IMG_MET:
+               return "met";
+       case CTSVC_VCARD_IMG_PMB:
+               return "pmb";
+       case CTSVC_VCARD_IMG_DIB:
+               return "dib";
+       case CTSVC_VCARD_IMG_PICT:
+               return "pict";
+       case CTSVC_VCARD_IMG_PDF:
+               return "pdf";
+       case CTSVC_VCARD_IMG_PS:
+               return "ps";
+       case CTSVC_VCARD_IMG_QTIME:
+               return "qtime";
+       case CTSVC_VCARD_IMG_MPEG:
+               return "mpeg";
+       case CTSVC_VCARD_IMG_MPEG2:
+               return "mpeg2";
+       case CTSVC_VCARD_IMG_AVI:
+               return "avi";
+       case CTSVC_VCARD_IMG_JPEG:
+       case CTSVC_VCARD_IMG_NONE:
+       default:
+               return "jpeg";
+       }
+}
+
+static inline int __ctsvc_vcard_get_image_type(char *val)
+{
+       char *temp, *result;
+       RETV_IF(NULL == val, CTSVC_VCARD_IMG_NONE);
+
+       temp = val;
+       while (*temp) {
+               *temp = tolower(*temp);
+               temp++;
+       }
+
+       result = strstr(val, "jpeg");
+       if (result) return CTSVC_VCARD_IMG_JPEG;
+
+       result = strstr(val, "jpg");
+       if (result) return CTSVC_VCARD_IMG_JPEG;
+
+       result = strstr(val, "png");
+       if (result) return CTSVC_VCARD_IMG_PNG;
+
+       result = strstr(val, "gif");
+       if (result) return CTSVC_VCARD_IMG_GIF;
+
+       result = strstr(val, "tiff");
+       if (result) return CTSVC_VCARD_IMG_TIFF;
+
+       result = strstr(val, "cgm");
+       if (result) return CTSVC_VCARD_IMG_CGM;
+
+       result = strstr(val, "wmf");
+       if (result) return CTSVC_VCARD_IMG_WMF;
+
+       result = strstr(val, "bmp");
+       if (result) return CTSVC_VCARD_IMG_BMP;
+
+       result = strstr(val, "met");
+       if (result) return CTSVC_VCARD_IMG_MET;
+
+       result = strstr(val, "pmb");
+       if (result) return CTSVC_VCARD_IMG_PMB;
+
+       result = strstr(val, "dib");
+       if (result) return CTSVC_VCARD_IMG_DIB;
+
+       result = strstr(val, "pict");
+       if (result) return CTSVC_VCARD_IMG_PICT;
+
+       result = strstr(val, "pdf");
+       if (result) return CTSVC_VCARD_IMG_PDF;
+
+       result = strstr(val, "ps");
+       if (result) return CTSVC_VCARD_IMG_PS;
+
+       result = strstr(val, "qtime");
+       if (result) return CTSVC_VCARD_IMG_QTIME;
+
+       result = strstr(val, "mpeg");
+       if (result) return CTSVC_VCARD_IMG_MPEG;
+
+       result = strstr(val, "mpeg2");
+       if (result) return CTSVC_VCARD_IMG_MPEG2;
+
+       result = strstr(val, "avi");
+       if (result) return CTSVC_VCARD_IMG_AVI;
+
+       return CTSVC_VCARD_IMG_NONE;
+}
+
+static inline const char* __ctsvc_get_image_type_str(int type)
+{
+       switch (type)
+       {
+       case CTSVC_VCARD_IMG_TIFF:
+               return "TIFF";
+       case CTSVC_VCARD_IMG_GIF:
+               return "GIF";
+       case CTSVC_VCARD_IMG_PNG:
+               return "PNG";
+       case CTSVC_VCARD_IMG_CGM:
+               return "CGM";
+       case CTSVC_VCARD_IMG_WMF:
+               return "WMF";
+       case CTSVC_VCARD_IMG_BMP:
+               return "BMP";
+       case CTSVC_VCARD_IMG_MET:
+               return "MET";
+       case CTSVC_VCARD_IMG_PMB:
+               return "PMB";
+       case CTSVC_VCARD_IMG_DIB:
+               return "DIB";
+       case CTSVC_VCARD_IMG_PICT:
+               return "PICT";
+       case CTSVC_VCARD_IMG_PDF:
+               return "PDF";
+       case CTSVC_VCARD_IMG_PS:
+               return "PS";
+       case CTSVC_VCARD_IMG_QTIME:
+               return "QTIME";
+       case CTSVC_VCARD_IMG_MPEG:
+               return "MPEG";
+       case CTSVC_VCARD_IMG_MPEG2:
+               return "MPEG2";
+       case CTSVC_VCARD_IMG_AVI:
+               return "AVI";
+       case CTSVC_VCARD_IMG_JPEG:
+       default:
+               return "JPEG";
+       }
+}
+
+static inline int __ctsvc_vcard_put_company_logo(const char *path, char **buf, int *buf_size, int len)
+{
+       int ret, fd, type;
+       gsize read_len;
+       char *suffix;
+       gchar *buf_image;
+       guchar *image = calloc(1, CTSVC_VCARD_PHOTO_MAX_SIZE);
+       RETVM_IF(NULL == image, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+
+       suffix = strrchr(path, '.');
+       type = __ctsvc_vcard_get_image_type(suffix);
+
+       fd = open(path, O_RDONLY);
+       if (fd < 0) {
+               free(image);
+               CTS_ERR("System : Open Failed(%d)", errno);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       read_len = 0;
+       while ((ret = read(fd, image+read_len, sizeof(image)-read_len))) {
+               if (-1 == ret) {
+                       if (EINTR == errno)
+                               continue;
+                       else
+                               break;
+               }
+               read_len += ret;
+       }
+       close(fd);
+       if (ret < 0) {
+               free(image);
+               CTS_ERR("System : read() Failed(%d)", errno);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       buf_image = g_base64_encode(image, read_len);
+       free(image);
+       if (buf_image) {
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_LOGO]);
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";ENCODING=BASE64;TYPE=");
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, __ctsvc_get_image_type_str(type));
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ":");
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, buf_image);
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
+               g_free(buf_image);
+       }
+       return len;
+}
+
+static bool __ctsvc_vcard_is_valid_custom_label(char *label)
+{
+       char *src = label;
+       RETV_IF(NULL == label || '\0' == *label, false);
+
+       while (*src) {
+               char c = src[0];
+               RETV_IF(1 != ctsvc_check_utf8(c), false);
+               if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') ||
+                               ('0' <= c && c <= '9') || c == '-') {
+                       src++;
+                       continue;
+               }
+               return false;
+       }
+       return true;
+}
+
+static inline int __ctsvc_vcard_put_company_type(int type, char *label, char **buf, int* buf_size, int len)
+{
+       if (type == CONTACTS_COMPANY_TYPE_WORK) {
+               CTSVC_VCARD_APPEND_STR(buf,buf_size,len,";TYPE=WORK");
+       }
+
+       else if (type == CONTACTS_COMPANY_TYPE_CUSTOM) {
+               if (__ctsvc_vcard_is_valid_custom_label(label)) {
+                       CTSVC_VCARD_APPEND_STR(buf,buf_size,len,";TYPE=X-");
+                       CTSVC_VCARD_APPEND_STR(buf,buf_size,len, label);
+               }
+       }
+       return len;
+}
+
+static inline int __ctsvc_vcard_append_company(ctsvc_list_s *company_list, char **buf, int *buf_size, int len)
+{
+       GList *cursor;
+       ctsvc_company_s *company;
+
+       for (cursor=company_list->records;cursor;cursor=cursor->next) {
+
+               company = (ctsvc_company_s *)cursor->data;
+
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_ORG]);
+
+               len = __ctsvc_vcard_put_company_type(company->type, SAFE_STR(company->label), buf, buf_size, len);
+               RETV_IF(len < 0, CONTACTS_ERROR_OUT_OF_MEMORY);
+
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";CHARSET=UTF-8");
+               CTSVC_VCARD_APPEND_STR(buf,buf_size,len,":");
+               CTSVC_VCARD_APPEND_CONTENT_STR(buf,buf_size,len,company->name);
+               if (company->department) {
+                       CTSVC_VCARD_APPEND_STR(buf,buf_size,len,";");
+                       CTSVC_VCARD_APPEND_CONTENT_STR(buf,buf_size,len,company->department);
+               }
+
+               CTSVC_VCARD_APPEND_STR(buf,buf_size,len,CTSVC_CRLF);
+
+               if (company->job_title) {
+                       CTSVC_VCARD_APPEND_STR(buf,buf_size,len,content_name[CTSVC_VCARD_VALUE_TITLE]);
+                       CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, company->job_title);
+               }
+
+               if (company->role) {
+                       CTSVC_VCARD_APPEND_STR(buf,buf_size,len,content_name[CTSVC_VCARD_VALUE_ROLE]);
+                       CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, company->role);
+               }
+
+               if (company->location) {
+                       CTSVC_VCARD_APPEND_STR(buf,buf_size,len,content_name[CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_LOCATION]);
+                       CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, company->location);
+               }
+
+               if (company->description) {
+                       CTSVC_VCARD_APPEND_STR(buf,buf_size,len,content_name[CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_DESCRIPTION]);
+                       CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, company->description);
+               }
+
+               if (company->phonetic_name) {
+                       CTSVC_VCARD_APPEND_STR(buf,buf_size,len,content_name[CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_PHONETIC_NAME]);
+                       CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, company->phonetic_name);
+               }
+
+               if (company->assistant_name) {
+                       CTSVC_VCARD_APPEND_STR(buf,buf_size,len,content_name[CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_ASSISTANT_NAME]);
+                       CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, company->assistant_name);
+               }
+
+               if (company->logo) {
+                       len = __ctsvc_vcard_put_company_logo(company->logo, buf, buf_size, len);
+                       RETV_IF(len < 0, CONTACTS_ERROR_OUT_OF_MEMORY);
+               }
+       }
+
+       return len;
+}
+
+static inline int __ctsvc_vcard_append_note(ctsvc_list_s *note_list, char **buf, int *buf_size, int len)
+{
+       GList *cursor;
+       ctsvc_note_s *note;
+
+       for (cursor=note_list->records;cursor;cursor=cursor->next) {
+               note = (ctsvc_note_s *)cursor->data;
+               if (note->note) {
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_NOTE]);
+                       CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, note->note);
+               }
+       }
+
+       return len;
+}
+
+static inline int __ctsvc_vcard_2_put_postal_type(int type, char *dest, int dest_size)
+{
+       int ret_len = 0;
+
+       if (type & CONTACTS_ADDRESS_TYPE_DOM)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "DOM");
+       if (type & CONTACTS_ADDRESS_TYPE_INTL)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "INTL");
+       if (type & CONTACTS_ADDRESS_TYPE_HOME)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "HOME");
+       if (type & CONTACTS_ADDRESS_TYPE_WORK)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "WORK");
+       if (type & CONTACTS_ADDRESS_TYPE_POSTAL)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "POSTAL");
+       if (type & CONTACTS_ADDRESS_TYPE_PARCEL)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "PARCEL");
+
+       return ret_len;
+}
+
+static inline int __ctsvc_vcard_put_postal_type(int type, char *label, char **buf, int *buf_size, int len)
+{
+       char *type_str = NULL;
+       if (type == CONTACTS_ADDRESS_TYPE_DOM)
+               type_str = "DOM";
+       else if (type == CONTACTS_ADDRESS_TYPE_INTL)
+               type_str = "INTL";
+       else if (type == CONTACTS_ADDRESS_TYPE_HOME)
+               type_str = "HOME";
+       else if (type == CONTACTS_ADDRESS_TYPE_WORK)
+               type_str = "WORK";
+       else if (type == CONTACTS_ADDRESS_TYPE_POSTAL)
+               type_str = "POSTAL";
+       else if (type == CONTACTS_ADDRESS_TYPE_PARCEL)
+               type_str = "PARCEL";
+
+       if (type == CONTACTS_ADDRESS_TYPE_CUSTOM) {
+               if (__ctsvc_vcard_is_valid_custom_label(label)) {
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-");
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, label);
+               }
+               return len;
+       }
+
+       if (type_str) {
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=");
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, type_str);
+       }
+       return len;
+}
+
+static inline int __ctsvc_vcard_append_postals(ctsvc_list_s *address_list, char **buf, int* buf_size, int len)
+{
+       GList *cursor;
+       ctsvc_address_s *address;
+
+       for (cursor = address_list->records;cursor;cursor=cursor->next) {
+               address = cursor->data;
+               if (address) {
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_ADR]);
+
+                       len = __ctsvc_vcard_put_postal_type(address->type, SAFE_STR(address->label), buf, buf_size, len);
+                       RETV_IF(len < 0, CONTACTS_ERROR_OUT_OF_MEMORY);
+
+                       if (address->is_default) {
+                               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";PREF");
+                       }
+
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";CHARSET=UTF-8");
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ":");
+                       CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, address->pobox);
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
+                       CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, address->extended);
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
+                       CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, address->street);
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
+                       CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, address->locality);
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
+                       CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, address->region);
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
+                       CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, address->postalcode);
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";");
+                       CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, address->country);
+
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
+               }
+       }
+
+       return len;
+}
+
+static inline int __ctsvc_vcard_append_nicknames(ctsvc_list_s *nickname_list, char **buf, int* buf_size, int len)
+{
+       bool first;
+       GList *cursor;
+       ctsvc_nickname_s *nickname;
+
+       first = true;
+       for (cursor=nickname_list->records;cursor;cursor=cursor->next) {
+               nickname = cursor->data;
+               if (nickname->nickname && *nickname->nickname) {
+                       if (first) {
+                               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_NICKNAME]);
+                               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";CHARSET=UTF-8");
+                               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ":");
+                               CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, nickname->nickname);
+                               first = false;
+                       }
+                       else {
+                               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ",");
+                               CTSVC_VCARD_APPEND_CONTENT_STR(buf, buf_size, len, nickname->nickname);
+                       }
+               }
+       }
+       if (!first)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
+
+       return len;
+}
+
+static inline int __ctsvc_vcard_2_put_number_type(int type, char *dest, int dest_size)
+{
+       int ret_len = 0;
+       if (type & CONTACTS_NUMBER_TYPE_HOME)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "HOME");
+       if (type & CONTACTS_NUMBER_TYPE_MSG)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "MSG");
+       if (type & CONTACTS_NUMBER_TYPE_WORK)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "WORK");
+       if (type & CONTACTS_NUMBER_TYPE_VOICE)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "VOICE");
+       if (type & CONTACTS_NUMBER_TYPE_FAX)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "FAX");
+       if (type & CONTACTS_NUMBER_TYPE_VOICE)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "VOICE");
+       if (type & CONTACTS_NUMBER_TYPE_CELL)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "CELL");
+       if (type & CONTACTS_NUMBER_TYPE_VIDEO)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "VIDEO");
+       if (type & CONTACTS_NUMBER_TYPE_PAGER)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "PAGER");
+       if (type & CONTACTS_NUMBER_TYPE_BBS)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "BBS");
+       if (type & CONTACTS_NUMBER_TYPE_MODEM)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "MODEM");
+       if (type & CONTACTS_NUMBER_TYPE_CAR)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "CAR");
+       if (type & CONTACTS_NUMBER_TYPE_ISDN)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "ISDN");
+       if (type & CONTACTS_NUMBER_TYPE_PCS)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "PCS");
+
+       return ret_len;
+}
+
+static inline int __ctsvc_vcard_put_number_type(int type, char *label, char **buf, int *buf_size, int len)
+{
+       if (type & CONTACTS_NUMBER_TYPE_HOME)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=HOME");
+       if (type & CONTACTS_NUMBER_TYPE_MSG)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=MSG");
+       if (type & CONTACTS_NUMBER_TYPE_WORK)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=WORK");
+       if (type & CONTACTS_NUMBER_TYPE_VOICE)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=VOICE");
+       if (type & CONTACTS_NUMBER_TYPE_FAX)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=FAX");
+       if (type & CONTACTS_NUMBER_TYPE_CELL)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=CELL");
+       if (type & CONTACTS_NUMBER_TYPE_VIDEO)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=VIDEO");
+       if (type & CONTACTS_NUMBER_TYPE_PAGER)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=PAGER");
+       if (type & CONTACTS_NUMBER_TYPE_BBS)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=BBS");
+       if (type & CONTACTS_NUMBER_TYPE_MODEM)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=MODEM");
+       if (type & CONTACTS_NUMBER_TYPE_CAR)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=CAR");
+       if (type & CONTACTS_NUMBER_TYPE_ISDN)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=ISDN");
+       if (type & CONTACTS_NUMBER_TYPE_PCS)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=PCS");
+       if (type & CONTACTS_NUMBER_TYPE_ASSISTANT)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-ASSISTANT");
+       if (type & CONTACTS_NUMBER_TYPE_RADIO)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-RADIO");
+       if (type & CONTACTS_NUMBER_TYPE_COMPANY_MAIN)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-COMPANY-MAIN");
+       if (type & CONTACTS_NUMBER_TYPE_MAIN)
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-MAIN");
+       if (type == CONTACTS_NUMBER_TYPE_CUSTOM) {
+               if (__ctsvc_vcard_is_valid_custom_label(label)) {
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-");
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, label);
+               }
+               return len;
+       }
+       return len;
+}
+
+static int __ctsvc_vcard_check_utf8(char c)
+{
+       if ((c & 0xff) < (128 & 0xff))
+               return 1;
+       else if ((c & (char)0xe0) == (char)0xc0)
+               return 2;
+       else if ((c & (char)0xf0) == (char)0xe0)
+               return 3;
+       else if ((c & (char)0xf8) == (char)0xf0)
+               return 4;
+       else if ((c & (char)0xfc) == (char)0xf8)
+               return 5;
+       else if ((c & (char)0xfe) == (char)0xfc)
+               return 6;
+       else
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static void __ctsvc_vcard_get_clean_number_for_export(char *str, char *dest)
+{
+       int char_len = 0;
+       char *s= SAFE_STR(str);
+       char *r = NULL;
+
+       r = dest;
+
+       while (*s) {
+               char_len = __ctsvc_vcard_check_utf8(*s);
+               if (3 == char_len) {
+                       if (*s == 0xef) {
+                               if (*(s+1) == 0xbc) {
+                                       if (0x90 <= *(s+2) && *(s+2) <= 0x99) {                         // ef bc 90 : '0' ~ ef bc 99 : '9'
+                                               *r = '0' + (*(s+2) - 0x90);
+                                               r++;
+                                               s+=3;
+                                       }
+                                       else if (0x8b == *(s+2)) {                                                              // ef bc 8b : '+'
+                                               *r = '+';
+                                               r++;
+                                               s+=3;
+                                       }
+                                       else if (0x8a == *(s+2)) {                                                              // ef bc 8a : '*'
+                                               *r = '*';
+                                               r++;
+                                               s+=3;
+                                       }
+                                       else if (0x83 == *(s+2)) {                                                              // ef bc 83 : '#'
+                                               *r = '#';
+                                               r++;
+                                               s+=3;
+                                       }
+                                       else if (0x8c == *(s+2)) {                                                              // ef bc 8c : ','
+                                               *r = 'p';
+                                               r++;
+                                               s+=3;
+                                       }
+                                       else if (0x9b == *(s+2)) {                                                              // ef bc 9b : ';'
+                                               *r = 'w';
+                                               r++;
+                                               s+=3;
+                                       }
+                                       else {
+                                               s+=char_len;
+                                       }
+                               }
+                               else {
+                                       s+=char_len;
+                               }
+                       }
+                       else {
+                               s+=char_len;
+                       }
+               }
+               else if (1 == char_len) {
+                       switch (*s) {
+                               case '/':
+                               case 'N':
+                               case '.':
+                               case '0' ... '9':
+                               case '#':
+                               case '*':
+                               case '(':
+                               case ')':
+                               case '+':
+                                       *r = *s;
+                                       r++;
+                                       s++;
+                                       break;
+                               case ',':
+                               case 'p':
+                               case 'P':
+                                       *r = 'p';
+                                       r++;
+                                       s++;
+                                       break;
+                               case ';':
+                               case 'w':
+                               case 'W':
+                                       *r = 'w';
+                                       r++;
+                                       s++;
+                                       break;
+                               default:
+                                       s++;
+                                       break;
+                       }
+               }
+               else {
+                       s+=char_len;
+               }
+       }
+       *r = '\0';
+       return;
+}
+
+static inline int __ctsvc_vcard_append_numbers(ctsvc_list_s *number_list, char **buf, int* buf_size, int len)
+{
+       GList *cursor;
+       ctsvc_number_s *number;
+
+       for (cursor=number_list->records;cursor;cursor=cursor->next) {
+               number = cursor->data;
+               if (number->number) {
+                       char clean_number[strlen(number->number)+1];
+                       clean_number[0] = '\0';
+                       CTSVC_VCARD_APPEND_STR(buf,buf_size,len,content_name[CTSVC_VCARD_VALUE_TEL]);
+
+                       len = __ctsvc_vcard_put_number_type(number->type, SAFE_STR(number->label), buf, buf_size, len);
+                       RETV_IF(len < 0, CONTACTS_ERROR_OUT_OF_MEMORY);
+
+                       if (number->is_default) {
+                               CTSVC_VCARD_APPEND_STR(buf,buf_size,len,";PREF");
+                       }
+
+                       __ctsvc_vcard_get_clean_number_for_export(number->number, clean_number);
+                       if (*clean_number) {
+                               CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, clean_number);
+                       }
+               }
+       }
+       return len;
+}
+
+static inline int __ctsvc_vcard_2_put_email_type(int type, char *dest, int dest_size)
+{
+       int ret_len = 0;
+
+       if (CONTACTS_EMAIL_TYPE_HOME & type)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "HOME");
+       if (CONTACTS_EMAIL_TYPE_WORK & type)
+               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "WORK");
+
+       return ret_len;
+}
+
+static inline int __ctsvc_vcard_put_email_type(int type, char *label, char **buf, int *buf_size, int len)
+{
+       char *type_str = NULL;
+       if (CONTACTS_EMAIL_TYPE_HOME == type)
+               type_str = "HOME";
+       else if (CONTACTS_EMAIL_TYPE_WORK == type)
+               type_str = "WORK";
+       else if (CONTACTS_EMAIL_TYPE_MOBILE == type)
+               type_str = "CELL";
+       else if (CONTACTS_EMAIL_TYPE_CUSTOM == type) {
+               if (__ctsvc_vcard_is_valid_custom_label(label)) {
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-");
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, label);
+               }
+               return len;
+       }
+
+       if (type_str) {
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=");
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, type_str);
+       }
+       return len;
+}
+
+static inline int __ctsvc_vcard_append_emails(ctsvc_list_s *email_list, char **buf, int *buf_size, int len)
+{
+       GList *cursor;
+       ctsvc_email_s *email;
+
+       for (cursor=email_list->records;cursor;cursor=cursor->next) {
+               email = cursor->data;
+               if (email->email_addr) {
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_EMAIL]);
+
+                       len = __ctsvc_vcard_put_email_type(email->type, SAFE_STR(email->label), buf, buf_size, len);
+                       RETV_IF(len < 0, CONTACTS_ERROR_OUT_OF_MEMORY);
+
+                       if (email->is_default) {
+                               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";PREF");
+                       }
+                       CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, email->email_addr);
+               }
+       }
+       return len;
+}
+
+static inline int __ctsvc_vcard_put_url_type(int type, char *label, char **buf, int *buf_size, int len)
+{
+       char *type_str = NULL;
+
+       if (CONTACTS_URL_TYPE_HOME == type)
+               type_str = "HOME";
+       else if (CONTACTS_URL_TYPE_WORK == type)
+               type_str = "WORK";
+       else if (CONTACTS_URL_TYPE_CUSTOM == type) {
+               if (__ctsvc_vcard_is_valid_custom_label(label)) {
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-");
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, label);
+               }
+               return len;
+       }
+       if (type_str) {
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=");
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, type_str);
+       }
+       return len;
+}
+
+static inline int __ctsvc_vcard_append_webs(ctsvc_list_s *url_list, char **buf, int *buf_size, int len)
+{
+       GList *cursor;
+       ctsvc_url_s *url;
+
+       for (cursor=url_list->records;cursor;cursor=cursor->next) {
+               url = cursor->data;
+
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_URL]);
+
+               len = __ctsvc_vcard_put_url_type(url->type, SAFE_STR(url->label), buf, buf_size, len);
+               RETV_IF(len < 0, CONTACTS_ERROR_OUT_OF_MEMORY);
+
+               CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, url->url);
+       }
+
+       return len;
+}
+
+#define VCARD_INIT_LENGTH 1024
+#define VCARD_ITEM_LENGTH 1024
+
+static inline int __ctsvc_vcard_append_events(ctsvc_list_s *event_list, char **buf, int *buf_size, int len)
+{
+       GList *cursor;
+       ctsvc_event_s *data;
+       char event[VCARD_ITEM_LENGTH] = {0};
+
+       for (cursor=event_list->records;cursor;cursor=cursor->next) {
+               data = cursor->data;
+               if (!data->date) continue;
+
+               event[0] = '\0';
+               if (CONTACTS_EVENT_TYPE_BIRTH == data->type) {
+                       snprintf(event, sizeof(event), "%s:%d-%02d-%02d%s",
+                                       content_name[CTSVC_VCARD_VALUE_BDAY],
+                                       data->date/10000, (data->date%10000)/100, data->date%100,
+                                       CTSVC_CRLF);
+               }
+               else if (CONTACTS_EVENT_TYPE_ANNIVERSARY == data->type) {
+                       snprintf(event, sizeof(event), "%s;TYPE=ANNIVERSARY:%d-%02d-%02d%s",
+                                       content_name[CTSVC_VCARD_VALUE_X_TIZEN_EVENT],
+                                       data->date/10000, (data->date%10000)/100, data->date%100,
+                                       CTSVC_CRLF);
+               }
+               else if (CONTACTS_EVENT_TYPE_CUSTOM == data->type) {
+                       if (__ctsvc_vcard_is_valid_custom_label(data->label)) {
+                               snprintf(event, sizeof(event), "%s;TYPE=X-%s:%d-%02d-%02d%s",
+                                               content_name[CTSVC_VCARD_VALUE_X_TIZEN_EVENT],
+                                               SAFE_STR(data->label),
+                                               data->date/10000, (data->date%10000)/100, data->date%100,
+                                               CTSVC_CRLF);
+                       }
+                       else {
+                               snprintf(event, sizeof(event), "%s:%d-%02d-%02d%s",
+                                               content_name[CTSVC_VCARD_VALUE_X_TIZEN_EVENT],
+                                               data->date/10000, (data->date%10000)/100, data->date%100,
+                                               CTSVC_CRLF);
+                       }
+               }
+               else {
+                       snprintf(event, sizeof(event), "%s:%d-%02d-%02d%s",
+                                       content_name[CTSVC_VCARD_VALUE_X_TIZEN_EVENT],
+                                       data->date/10000, (data->date%10000)/100, data->date%100,
+                                       CTSVC_CRLF);
+               }
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, event);
+       }
+
+       return len;
+}
+
+static inline int __ctsvc_vcard_append_messengers(ctsvc_list_s *messenger_list, char **buf, int *buf_size, int len)
+{
+       GList *cursor;
+       ctsvc_messenger_s *messenger;
+       const char *content_name_messenger = NULL;
+       const char *content_name_x_type = NULL;
+
+       for (cursor=messenger_list->records;cursor;cursor=cursor->next) {
+               messenger = cursor->data;
+
+               content_name_messenger = NULL;
+               content_name_x_type = NULL;
+
+               if (messenger->im_id && *messenger->im_id) {
+                       switch (messenger->type) {
+                       case CONTACTS_MESSENGER_TYPE_WLM:
+                               content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_MSN];
+                               break;
+                       case CONTACTS_MESSENGER_TYPE_YAHOO:
+                               content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_YAHOO];
+                               break;
+                       case CONTACTS_MESSENGER_TYPE_ICQ:
+                               content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_ICQ];
+                               break;
+                       case CONTACTS_MESSENGER_TYPE_AIM:
+                               content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_AIM];
+                               break;
+                       case CONTACTS_MESSENGER_TYPE_JABBER:
+                               content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_JABBER];
+                               break;
+                       case CONTACTS_MESSENGER_TYPE_SKYPE:
+                               content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_SKYPE_USERNAME];
+                               break;
+                       case CONTACTS_MESSENGER_TYPE_QQ:
+                               content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_QQ];
+                               break;
+                       case CONTACTS_MESSENGER_TYPE_GOOGLE:
+                               content_name_messenger = content_name[CTSVC_VCARD_VALUE_X_GOOGLE_TALK];
+                               break;
+                       case CONTACTS_MESSENGER_TYPE_FACEBOOK:
+                               content_name_x_type = "FACEBOOK";
+                               break;
+                       case CONTACTS_MESSENGER_TYPE_IRC:
+                               content_name_x_type = "IRC";
+                               break;
+                       case CONTACTS_MESSENGER_TYPE_CUSTOM:
+                               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_X_TIZEN_MESSENGER]);
+                               if (__ctsvc_vcard_is_valid_custom_label(messenger->label)) {
+                                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-");
+                                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, messenger->label);
+                               }
+                               CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, messenger->im_id);
+                               break;
+                       default:
+                               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_X_TIZEN_MESSENGER]);
+                               CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, messenger->im_id);
+                               break;
+                       }
+
+                       if (content_name_messenger) {
+                               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name_messenger);
+                               CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, messenger->im_id);
+                       }
+                       else if(content_name_x_type) {
+                               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_X_TIZEN_MESSENGER]);
+                               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=");
+                               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name_x_type);
+                               CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, messenger->im_id);
+                       }
+               }
+       }
+       return len;
+}
+
+static inline int __ctsvc_vcard_put_relationship_type(int type, char *label, char **buf, int* buf_size, int len)
+{
+       const char *type_str = NULL;
+
+       switch (type) {
+       case CONTACTS_RELATIONSHIP_TYPE_ASSISTANT:
+               type_str = "ASSISTANT";
+               break;
+       case CONTACTS_RELATIONSHIP_TYPE_BROTHER:
+               type_str = "BROTHER";
+               break;
+       case CONTACTS_RELATIONSHIP_TYPE_CHILD:
+               type_str = "CHILD";
+               break;
+       case CONTACTS_RELATIONSHIP_TYPE_DOMESTIC_PARTNER:
+               type_str = "DOMESTIC_PARTNER";
+               break;
+       case CONTACTS_RELATIONSHIP_TYPE_FATHER:
+               type_str = "FATHER";
+               break;
+       case CONTACTS_RELATIONSHIP_TYPE_FRIEND:
+               type_str = "FRIEND";
+               break;
+       case CONTACTS_RELATIONSHIP_TYPE_MANAGER:
+               type_str = "MANAGER";
+               break;
+       case CONTACTS_RELATIONSHIP_TYPE_MOTHER:
+               type_str = "MOTHER";
+               break;
+       case CONTACTS_RELATIONSHIP_TYPE_PARENT:
+               type_str = "PARENT";
+               break;
+       case CONTACTS_RELATIONSHIP_TYPE_PARTNER:
+               type_str = "PARTNER";
+               break;
+       case CONTACTS_RELATIONSHIP_TYPE_REFERRED_BY:
+               type_str = "REFERRED_BY";
+               break;
+       case CONTACTS_RELATIONSHIP_TYPE_RELATIVE:
+               type_str = "RELATIVE";
+               break;
+       case CONTACTS_RELATIONSHIP_TYPE_SISTER:
+               type_str = "SISTER";
+               break;
+       case CONTACTS_RELATIONSHIP_TYPE_SPOUSE:
+               type_str = "SPOUSE";
+               break;
+       case CONTACTS_RELATIONSHIP_TYPE_CUSTOM:
+               if (__ctsvc_vcard_is_valid_custom_label(label)) {
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=X-");
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, label);
+               }
+               return len;
+       }
+
+       if (type_str) {
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";TYPE=");
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, type_str);
+       }
+
+       return len;
+}
+
+static inline int __ctsvc_vcard_append_relationships(ctsvc_list_s *relationship_list, char **buf, int *buf_size, int len)
+{
+       GList *cursor;
+       ctsvc_relationship_s *relationship;
+
+       for (cursor=relationship_list->records;cursor;cursor=cursor->next) {
+               relationship = cursor->data;
+
+               if (relationship->name) {
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, "X-TIZEN-RELATIONSHIP");
+
+                       len = __ctsvc_vcard_put_relationship_type(relationship->type, SAFE_STR(relationship->label), buf, buf_size, len);
+                       RETV_IF(len < 0, CONTACTS_ERROR_OUT_OF_MEMORY);
+                       CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, relationship->name);
+               }
+       }
+
+       return len;
+}
+
+static inline int __ctsvc_vcard_put_photo(ctsvc_list_s *image_list, char **buf, int *buf_size, int len)
+{
+       int ret = 0, fd, type;
+       gsize read_len;
+       char *suffix;
+       gchar *buf_image;
+
+       guchar *image = NULL;
+       GList *cursor;
+       ctsvc_image_s *data;
+
+       for (cursor=image_list->records;cursor;cursor=cursor->next) {
+               data = cursor->data;
+               if (!data->path) continue;
+
+               suffix = strrchr(data->path, '.');
+               type = __ctsvc_vcard_get_image_type(suffix);
+
+               fd = open(data->path, O_RDONLY);
+               if (fd < 0) {
+                       CTS_ERR("System : Open Failed(%d)", errno);
+                       return CONTACTS_ERROR_SYSTEM;
+               }
+
+               image = calloc(1, CTSVC_VCARD_PHOTO_MAX_SIZE);
+               if (NULL == image) {
+                       CTS_ERR("calloc() return NULL");
+                       close(fd);
+                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+               }
+               read_len = 0;
+               while ((ret = read(fd, image+read_len, sizeof(image)-read_len))) {
+                       if (-1 == ret) {
+                               if (EINTR == errno)
+                                       continue;
+                               else
+                                       break;
+                       }
+                       read_len += ret;
+               }
+               close(fd);
+               if (ret < 0) {
+                       free(image);
+                       CTS_ERR("System : read() Failed(%d)", errno);
+                       return CONTACTS_ERROR_SYSTEM;
+               }
+
+               buf_image = g_base64_encode(image, read_len);
+               free(image);
+               if (buf_image) {
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_PHOTO]);
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ";ENCODING=BASE64;TYPE=");
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, __ctsvc_get_image_type_str(type));
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, ":");
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, buf_image);
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
+                       g_free(buf_image);
+               }
+       }
+       return len;
+}
+
+static inline int __ctsvc_vcard_append_contact(ctsvc_contact_s *contact, char **buf, int *buf_size, int len)
+{
+       if (contact->name) {
+               len = __ctsvc_vcard_append_name(contact->name, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (contact->company) {
+               len = __ctsvc_vcard_append_company(contact->company, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (contact->note) {
+               len = __ctsvc_vcard_append_note(contact->note, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (contact->postal_addrs) {
+               len = __ctsvc_vcard_append_postals(contact->postal_addrs, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (contact->numbers) {
+               len = __ctsvc_vcard_append_numbers(contact->numbers, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (contact->emails) {
+               len = __ctsvc_vcard_append_emails(contact->emails, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (contact->nicknames) {
+               len = __ctsvc_vcard_append_nicknames(contact->nicknames, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (contact->urls) {
+               len = __ctsvc_vcard_append_webs(contact->urls, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (contact->events) {
+               len = __ctsvc_vcard_append_events(contact->events, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (contact->images) {
+               len = __ctsvc_vcard_put_photo(contact->images, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (contact->messengers) {
+               len = __ctsvc_vcard_append_messengers(contact->messengers, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (contact->relationships) {
+               len = __ctsvc_vcard_append_relationships(contact->relationships, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+
+       if (contact->uid && DEFAULT_ADDRESS_BOOK_ID == contact->addressbook_id) {
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_UID]);
+               CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, contact->uid);
+       }
+
+       if (contact->changed_time) {
+               struct tm ts;
+               gmtime_r((time_t *)&contact->changed_time, &ts);
+               char temp[VCARD_ITEM_LENGTH] = {0};
+               snprintf(temp, sizeof(temp), "%s:%04d-%02d-%02dT%02d:%02d:%02dZ%s",
+                               content_name[CTSVC_VCARD_VALUE_REV],
+                               1900+ts.tm_year, 1+ts.tm_mon, ts.tm_mday,
+                               ts.tm_hour, ts.tm_min, ts.tm_sec,
+                               CTSVC_CRLF);
+
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, temp);
+       }
+#if 0
+       ctsvc_list_s* profile;
+#endif
+       return len;
+}
+
+static inline int __ctsvc_vcard_append_my_profile(ctsvc_my_profile_s *my_profile, char **buf, int *buf_size, int len)
+{
+       if (my_profile->name) {
+               len = __ctsvc_vcard_append_name(my_profile->name, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (my_profile->company) {
+               len = __ctsvc_vcard_append_company(my_profile->company, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (my_profile->note) {
+               len = __ctsvc_vcard_append_note(my_profile->note, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (my_profile->postal_addrs) {
+               len = __ctsvc_vcard_append_postals(my_profile->postal_addrs, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (my_profile->numbers) {
+               len = __ctsvc_vcard_append_numbers(my_profile->numbers, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (my_profile->emails) {
+               len = __ctsvc_vcard_append_emails(my_profile->emails, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (my_profile->nicknames) {
+               len = __ctsvc_vcard_append_nicknames(my_profile->nicknames, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (my_profile->urls) {
+               len = __ctsvc_vcard_append_webs(my_profile->urls, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (my_profile->events) {
+               len = __ctsvc_vcard_append_events(my_profile->events, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (my_profile->images) {
+               len = __ctsvc_vcard_put_photo(my_profile->images, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (my_profile->messengers) {
+               len = __ctsvc_vcard_append_messengers(my_profile->messengers, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+       if (my_profile->relationships) {
+               len = __ctsvc_vcard_append_relationships(my_profile->relationships, buf, buf_size, len);
+               RETV_IF(len < 0, len);
+       }
+
+       if (my_profile->uid && DEFAULT_ADDRESS_BOOK_ID == my_profile->addressbook_id) {
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_UID]);
+               CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, my_profile->uid);
+       }
+
+       if (my_profile->changed_time) {
+               struct tm ts;
+               gmtime_r((time_t *)&my_profile->changed_time, &ts);
+               char temp[VCARD_ITEM_LENGTH] = {0};
+               snprintf(temp, sizeof(temp), "%s:%04d-%02d-%02dT%02d:%02d:%02dZ%s",
+                               content_name[CTSVC_VCARD_VALUE_REV],
+                               1900+ts.tm_year, 1+ts.tm_mon, ts.tm_mday,
+                               ts.tm_hour, ts.tm_min, ts.tm_sec,
+                               CTSVC_CRLF);
+
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, temp);
+       }
+
+#if 0
+               ctsvc_list_s* profile;
+#endif
+       return len;
+}
+
+static inline int __ctsvc_vcard_append_start_vcard_3_0(char **buf, int *buf_size, int len)
+{
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, "BEGIN:VCARD");
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, "VERSION:3.0");
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
+       return len;
+}
+
+static inline int __ctsvc_vcard_append_end_vcard(char **buf, int *buf_size, int len)
+{
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, "END:VCARD");
+       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, CTSVC_CRLF);
+       return len;
+}
+
+static int __ctsvc_vcard_make(ctsvc_contact_s *contact, char **vcard_stream)
+{
+       char *buf = NULL;
+       int buf_size = VCARD_INIT_LENGTH;
+       int len = 0;
+
+       __ctsvc_vcard_initial();
+
+       buf = calloc(1, buf_size);
+       RETVM_IF(NULL == buf, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+
+       len = __ctsvc_vcard_append_start_vcard_3_0(&buf, &buf_size, len);
+       if (len < 0) {
+               free(buf);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       len = __ctsvc_vcard_append_contact(contact, &buf, &buf_size, len);
+       if (len < 0) {
+               free(buf);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       len = __ctsvc_vcard_append_end_vcard(&buf, &buf_size, len);
+       if (len < 0) {
+               free(buf);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       len = __ctsvc_vcard_add_folding(&buf, &buf_size, len);
+       if (len < 0) {
+               free(buf);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       *vcard_stream = buf;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_vcard_make_from_my_profile(ctsvc_my_profile_s *my_profile, char **vcard_stream)
+{
+       char *buf = NULL;
+       int buf_size = VCARD_INIT_LENGTH;
+       int len = 0;
+
+       __ctsvc_vcard_initial();
+
+       buf = calloc(1, buf_size);
+       RETVM_IF(NULL == buf, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+
+       len = __ctsvc_vcard_append_start_vcard_3_0(&buf, &buf_size, len);
+       if (len < 0) {
+               free(buf);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       len = __ctsvc_vcard_append_my_profile(my_profile, &buf, &buf_size, len);
+       if (len < 0) {
+               free(buf);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       len = __ctsvc_vcard_append_end_vcard(&buf, &buf_size, len);
+       if (len < 0) {
+               free(buf);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       len = __ctsvc_vcard_add_folding(&buf, &buf_size, len);
+       if (len < 0) {
+               free(buf);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       *vcard_stream = buf;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_vcard_make_from_contact(contacts_record_h record, char **vcard_stream)
+{
+       ctsvc_contact_s *contact;
+       RETV_IF(NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER);
+       *vcard_stream = NULL;
+
+       RETVM_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER,
+               "Invalid parameter : contact(%p), vcard_stream(%p)", record, vcard_stream);
+
+       contact = (ctsvc_contact_s*)record;
+       RETVM_IF(CTSVC_RECORD_CONTACT != contact->base.r_type, CONTACTS_ERROR_INVALID_PARAMETER,
+               "Invalid parameter : The record is not conatct record (type : %d)", contact->base.r_type);
+
+       return __ctsvc_vcard_make(contact, vcard_stream);
+}
+
+API int contacts_vcard_make_from_my_profile(contacts_record_h record, char **vcard_stream)
+{
+       ctsvc_my_profile_s *my_profile;
+       RETV_IF(NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER);
+       *vcard_stream = NULL;
+
+       RETVM_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER,
+               "Invalid parameter : my_profile(%p), vcard_stream(%p)", record, vcard_stream);
+
+       my_profile = (ctsvc_my_profile_s*)record;
+       RETVM_IF(CTSVC_RECORD_MY_PROFILE != my_profile->base.r_type, CONTACTS_ERROR_INVALID_PARAMETER,
+               "Invalid parameter : The record is not conatct record (type : %d)", my_profile->base.r_type);
+
+       return __ctsvc_vcard_make_from_my_profile(my_profile, vcard_stream);
+}
+
+
+static int __ctsvc_vcard_append_person(ctsvc_person_s *person, ctsvc_list_s *list_contacts, char **buf, int *buf_size, int len)
+{
+       int changed_time = 0;
+       ctsvc_contact_s *contact;
+       GList *cursor = NULL;
+
+       for(cursor=list_contacts->records;cursor;cursor=cursor->next) {
+               contact = (ctsvc_contact_s *)cursor->data;
+               if (contact && contact->id == person->name_contact_id && contact->name) {
+                       len = __ctsvc_vcard_append_name(contact->name, buf, buf_size, len);
+                       RETV_IF(len < 0, len);
+               }
+       }
+
+       for(cursor=list_contacts->records;cursor;cursor=cursor->next) {
+               contact = (ctsvc_contact_s *)cursor->data;
+               if (contact && contact->company && contact->company->cursor) {
+                       len = __ctsvc_vcard_append_company(contact->company, buf, buf_size, len);
+                       RETV_IF(len < 0, len);
+               }
+       }
+
+       for(cursor=list_contacts->records;cursor;cursor=cursor->next) {
+               contact = (ctsvc_contact_s *)cursor->data;
+               if (contact && contact->note && contact->note->cursor) {
+                       len = __ctsvc_vcard_append_note(contact->note, buf, buf_size, len);
+                       RETV_IF(len < 0, len);
+               }
+       }
+       for(cursor=list_contacts->records;cursor;cursor=cursor->next) {
+               contact = (ctsvc_contact_s *)cursor->data;
+               if (contact && contact->postal_addrs && contact->postal_addrs->cursor) {
+                       len = __ctsvc_vcard_append_postals(contact->postal_addrs, buf, buf_size, len);
+                       RETV_IF(len < 0, len);
+               }
+       }
+       for(cursor=list_contacts->records;cursor;cursor=cursor->next) {
+               contact = (ctsvc_contact_s *)cursor->data;
+               if (contact && contact->numbers && contact->numbers->cursor) {
+                       len = __ctsvc_vcard_append_numbers(contact->numbers, buf, buf_size, len);
+                       RETV_IF(len < 0, len);
+               }
+       }
+
+       for(cursor=list_contacts->records;cursor;cursor=cursor->next) {
+               contact = (ctsvc_contact_s *)cursor->data;
+               if (contact && contact->emails && contact->emails->cursor) {
+                       len = __ctsvc_vcard_append_emails(contact->emails, buf, buf_size, len);
+                       RETV_IF(len < 0, len);
+               }
+       }
+
+       for(cursor=list_contacts->records;cursor;cursor=cursor->next) {
+               contact = (ctsvc_contact_s *)cursor->data;
+               if (contact && contact->nicknames && contact->nicknames->cursor) {
+                       len = __ctsvc_vcard_append_nicknames(contact->nicknames, buf, buf_size, len);
+                       RETV_IF(len < 0, len);
+               }
+       }
+       for(cursor=list_contacts->records;cursor;cursor=cursor->next) {
+               contact = (ctsvc_contact_s *)cursor->data;
+               if (contact && contact->urls && contact->urls->cursor) {
+                       len = __ctsvc_vcard_append_webs(contact->urls, buf, buf_size, len);
+                       RETV_IF(len < 0, len);
+               }
+       }
+
+       for(cursor=list_contacts->records;cursor;cursor=cursor->next) {
+               contact = (ctsvc_contact_s *)cursor->data;
+               if (contact && contact->events && contact->events->cursor) {
+                       len = __ctsvc_vcard_append_events(contact->events, buf, buf_size, len);
+                       RETV_IF(len < 0, len);
+               }
+       }
+       for(cursor=list_contacts->records;cursor;cursor=cursor->next) {
+               contact = (ctsvc_contact_s *)cursor->data;
+               if (contact && contact->images && contact->images->cursor) {
+                       len = __ctsvc_vcard_put_photo(contact->images, buf, buf_size, len);
+                       RETV_IF(len < 0, len);
+               }
+       }
+       for(cursor=list_contacts->records;cursor;cursor=cursor->next) {
+               contact = (ctsvc_contact_s *)cursor->data;
+               if (contact && contact->messengers && contact->messengers->cursor) {
+                       len = __ctsvc_vcard_append_messengers(contact->messengers, buf, buf_size, len);
+                       RETV_IF(len < 0, len);
+               }
+       }
+
+       for(cursor=list_contacts->records;cursor;cursor=cursor->next) {
+               contact = (ctsvc_contact_s *)cursor->data;
+               if (contact && contact->relationships && contact->relationships->cursor) {
+                       len = __ctsvc_vcard_append_relationships(contact->relationships, buf, buf_size, len);
+                       RETV_IF(len < 0, len);
+               }
+       }
+
+       for(cursor=list_contacts->records;cursor;cursor=cursor->next) {
+               contact = (ctsvc_contact_s *)cursor->data;
+               if (contact && contact->uid && DEFAULT_ADDRESS_BOOK_ID == contact->addressbook_id) {
+                       CTSVC_VCARD_APPEND_STR(buf, buf_size, len, content_name[CTSVC_VCARD_VALUE_UID]);
+                       CTSVC_VCARD_APPEND_CONTENT(buf, buf_size, len, contact->uid);
+               }
+       }
+       for(cursor=list_contacts->records;cursor;cursor=cursor->next) {
+               contact = (ctsvc_contact_s *)cursor->data;
+               if (contact && changed_time < contact->changed_time)
+                       changed_time = contact->changed_time;
+       }
+
+       if (changed_time) {
+               struct tm ts;
+               gmtime_r((time_t *)&changed_time, &ts);
+               char temp[VCARD_ITEM_LENGTH] = {0};
+               snprintf(temp, sizeof(temp), "%s:%04d-%02d-%02dT%02d:%02d:%02dZ%s",
+                               content_name[CTSVC_VCARD_VALUE_REV],
+                               1900+ts.tm_year, 1+ts.tm_mon, ts.tm_mday,
+                               ts.tm_hour, ts.tm_min, ts.tm_sec,
+                               CTSVC_CRLF);
+
+               CTSVC_VCARD_APPEND_STR(buf, buf_size, len, temp);
+       }
+
+#if 0
+       ctsvc_list_s* profile;
+#endif
+       return len;
+}
+
+static int __ctsvc_vcard_make_from_person(ctsvc_person_s *person, ctsvc_list_s *list_contacts,
+               char **vcard_stream)
+{
+       char *buf = NULL;
+       int buf_size = VCARD_INIT_LENGTH;
+       int len = 0;
+
+       RETV_IF(NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER);
+       *vcard_stream = NULL;
+
+       __ctsvc_vcard_initial();
+
+       buf = calloc(1, buf_size);
+       RETVM_IF(NULL == buf, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+
+       len = __ctsvc_vcard_append_start_vcard_3_0(&buf, &buf_size, len);
+       if (len < 0) {
+               free(buf);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       len = __ctsvc_vcard_append_person(person, list_contacts, &buf, &buf_size, len);
+       if (len < 0) {
+               free(buf);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       len = __ctsvc_vcard_append_end_vcard(&buf, &buf_size, len);
+       if (len < 0) {
+               free(buf);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       len = __ctsvc_vcard_add_folding(&buf, &buf_size, len);
+       if (len < 0) {
+               free(buf);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       *vcard_stream = buf;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_vcard_make_from_person(contacts_record_h record, char **vcard_stream)
+{
+       int ret;
+       ctsvc_person_s *person;
+       contacts_query_h query = NULL;
+       contacts_filter_h filter = NULL;
+       contacts_list_h list = NULL;
+
+       RETVM_IF(NULL == record || NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER,
+               "Invalid parameter : person(%p), vcard_stream(%p)", record, vcard_stream);
+       *vcard_stream = NULL;
+
+       person = (ctsvc_person_s *)record;
+
+       RETVM_IF(CTSVC_RECORD_PERSON != person->base.r_type, CONTACTS_ERROR_INVALID_PARAMETER,
+               "Invalid parameter : The record is not conatct record (type : %d)", person->base.r_type);
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = contacts_filter_create(_contacts_contact._uri, &filter))) break;
+               if (CONTACTS_ERROR_NONE != (ret = contacts_filter_add_int(filter, _contacts_contact.person_id, CONTACTS_MATCH_EQUAL, person->person_id))) break;
+               if (CONTACTS_ERROR_NONE != (ret = contacts_query_create(_contacts_contact._uri, &query))) break;
+               if (CONTACTS_ERROR_NONE != (ret = contacts_query_set_filter(query, filter))) break;
+               if (CONTACTS_ERROR_NONE != (ret = contacts_db_get_records_with_query(query, 0, 0, &list))) break;
+               if (CONTACTS_ERROR_NONE != (ret = __ctsvc_vcard_make_from_person(person, (ctsvc_list_s *)list, vcard_stream))) break;
+       } while (0);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "__ctsvc_vcard_make_from_person() Failed(%d)", ret);
+       contacts_query_destroy(query);
+       contacts_filter_destroy(filter);
+       contacts_list_destroy(list, true);
+       return ret;
+}
+
+////////////////////////////////////////////////////////////////////////////
+static inline char* __ctsvc_vcard_remove_empty_line(char *src)
+{
+       while (*src) {
+               if ('\n' != *src && '\r' != *src)
+                       break;
+               src++;
+       }
+       return src;
+}
+
+static char* __ctsvc_vcard_check_word(char *src, const char *word)
+{
+       bool start = false;
+
+       RETVM_IF(NULL == src, NULL, "The src is NULL.");
+
+       src = __ctsvc_vcard_remove_empty_line(src);
+
+       while (*src) {
+               switch (*src) {
+               case ' ':
+               case ':':
+               case ';':
+                       src++;
+                       break;
+               default:
+                       start = true;
+                       break;
+               }
+               if (start) break;
+       }
+
+       while (*src == *word) {
+               src++;
+               word++;
+
+               if ('\0' == *src || '\0' == *word)
+                       break;
+       }
+
+       if ('\0' == *word)
+               return src;
+       else
+               return NULL;
+}
+
+static int __ctsvc_vcard_check_content_type(char **vcard)
+{
+       int i;
+       char *new_start;
+
+       for (i=CTSVC_VCARD_VALUE_NONE+1;i<CTSVC_VCARD_VALUE_MAX;i++) {
+               new_start = __ctsvc_vcard_check_word(*vcard, content_name[i]);
+               if (new_start && (':' == *new_start || ';' == *new_start))
+                       break;
+       }
+
+       if (CTSVC_VCARD_VALUE_MAX == i)
+               return CTSVC_VCARD_VALUE_NONE;
+       else {
+               *vcard = new_start;
+               return i;
+       }
+}
+
+static inline char* __ctsvc_vcard_pass_unsupported(char *vcard)
+{
+       while (*vcard) {
+               if ('\n' == *vcard)
+                       return (vcard + 1);
+               vcard++;
+       }
+
+       return NULL;
+}
+
+static char* __ctsvc_strtok(char *val, char c)
+{
+       char *before = NULL;
+       while (*val) {
+               if (*val == c && (NULL == before || *before != '\\')) {
+                       *val = '\0';
+                       return (val+1);
+               }
+               before = val;
+               val++;
+       }
+       return val;
+}
+
+static inline bool __ctsvc_vcard_check_base64_encoded(char *src)
+{
+       int ret;
+       char *tmp = src;
+
+       while (*tmp) {
+               if ('B' == *tmp) {
+                       ret = strncmp(tmp, "BASE64", sizeof("BASE64") - 1);
+                       if (!ret)
+                               return true;
+               } else if (':' == *tmp || '\r' == *tmp) {
+                       break;
+               }
+               tmp++;
+       }
+       return false;
+}
+
+static inline int __ctsvc_vcard_check_quoted(char *src, int max, int *quoted)
+{
+       int ret;
+       if (TRUE == *quoted)
+               return TRUE;
+
+       while (*src && max) {
+               if ('Q' == *src) {
+                       ret = strncmp(src, "QUOTED-PRINTABLE", sizeof("QUOTED-PRINTABLE") - 1);
+                       if (!ret) {
+                               *quoted = TRUE;
+                               return TRUE;
+                       }
+               }else if (':' == *src) {
+                       break;
+               }
+               src++;
+               max--;
+       }
+       return FALSE;
+}
+
+static inline int __ctsvc_vcard_remove_folding(char *folded_src)
+{
+       char *result = folded_src;
+
+       RETV_IF(NULL == folded_src, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       while (*folded_src) {
+               if ('\r' == *folded_src && '\n' == *(folded_src+1) && ' ' == *(folded_src+2))
+                       folded_src += 3;
+               else if ('\n' == *folded_src && ' ' == *(folded_src+1))
+                       folded_src += 2;
+
+               if ('\0' == *folded_src)
+                       break;
+
+               *result = *folded_src;
+               result++;
+               folded_src++;
+       }
+       *result = '\0';
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_vcard_hex_to_dec(char hex)
+{
+       switch (hex) {
+       case '0' ... '9':
+               return hex - '0';
+       case 'a' ... 'f':
+               return hex - 'a' + 10;
+       case 'A' ... 'F':
+               return hex - 'A' + 10;
+       default:
+               return -1;
+       }
+}
+static inline int __ctsvc_vcard_decode_quoted_val(char *val)
+{
+       char *src, *dest;
+       int pre;
+
+       src = strchr(val, ':');
+       if (NULL == src)
+               src = val;
+
+       dest = src;
+       while (*src) {
+               if ('=' == *src) {
+                       pre = __ctsvc_vcard_hex_to_dec(*(src+1));
+                       if (0 <= pre) {
+                               *dest = (char)((pre << 4) + __ctsvc_vcard_hex_to_dec(*(src+2)));
+                               dest++;
+                               src += 2;
+                       } else {
+                               if ('\r' == *(src+1) && '\n' == *(src+2))
+                                       src += 2;
+                       }
+               } else {
+                       *dest = *src;
+                       dest++;
+               }
+               src++;
+       }
+
+       *dest = '\0';
+       return dest - val;
+}
+
+static inline char* __ctsvc_vcard_translate_charset(char *src, int len)
+{
+       int ret;
+       char *val = src;
+
+       while (*val) {
+               if ('C' == *val) {
+                       ret = strncmp(val, "CHARSET", sizeof("CHARSET") - 1);
+                       if (!ret) {
+                               val += sizeof("CHARSET");
+                               break;
+                       }
+               }
+               else if (':' == *val) {
+                       return NULL;
+               }
+               val++;
+       }
+
+       if (*val) {
+               UChar *temp;
+               UConverter *conv;
+               UErrorCode err = U_ZERO_ERROR;
+               int dest_size = 0;
+               int temp_size = 0;
+               int src_len, i = 0;
+               char enc[32] = {0}, *dest;
+
+               while (';' != *val && ':' != *val) {
+                       enc[i++] = *val++;
+               }
+               enc[i] = '\0';
+               if (0 == strcasecmp("UTF-8", enc))
+                       return NULL;
+
+               while (':' != *val)
+                       val++;
+
+               src_len = len - (val - src);
+
+               temp_size = (src_len+1) * sizeof(UChar);
+               temp = malloc(temp_size);
+               RETVM_IF(NULL == temp, NULL, "malloc() return NULL");
+               conv = ucnv_open(enc, &err);
+               WARN_IF(U_FAILURE(err), "ucnv_open() Failed(%d), enc=%s", err, enc);
+               ucnv_toUChars(conv, temp, temp_size, val, src_len, &err);
+               WARN_IF(U_FAILURE(err), "ucnv_toUChars() Failed(%d), enc=%s", err, enc);
+               ucnv_close(conv);
+
+               dest_size = temp_size*2;
+               dest = malloc(dest_size);
+               if (NULL == dest) {
+                       CTS_ERR("malloc() return NULL");
+                       ucnv_close(conv);
+                       free(temp);
+                       return NULL;
+               }
+               conv = ucnv_open("UTF-8", &err);
+               WARN_IF(U_FAILURE(err), "ucnv_open() Failed(%d), enc=%s", err, enc);
+               ucnv_fromUChars(conv, dest, dest_size, temp, u_strlen(temp), &err);
+               WARN_IF(U_FAILURE(err), "ucnv_fromUChars() Failed(%d), enc=%s", err, enc);
+               ucnv_close(conv);
+               free(temp);
+
+               return dest;
+       }
+       return NULL;
+}
+
+static void __ctsvc_vcard_get_prefix(char **prefix, char *src)
+{
+       char *temp = strchr(src, ':');
+       if (temp) {
+               int len = (int)temp - (int)src;
+               *prefix = calloc(len+1, sizeof(char));
+               RETM_IF(NULL == *prefix, "calloc() return NULL");
+               snprintf(*prefix, len+1, "%s", src);
+       }
+       else {
+               *prefix = NULL;
+       }
+}
+
+static char* __ctsvc_vcard_get_val(int ver, char *src, char **prefix, char **dest)
+{
+       int quoted;
+       bool start = false;
+       char *cursor;
+
+       RETVM_IF(NULL == src, NULL, "Invalid parameter : The src is NULL.");
+       RETVM_IF(NULL == dest, NULL, "sInvalid parameter : The dest is NULL.");
+
+       while (*src) {
+               switch (*src) {
+               case '\n':
+                       return NULL;
+               case '\r':
+               case ' ':
+                       src++;
+                       break;
+               default:
+                       start = true;
+                       break;
+               }
+               if (start) break;
+       }
+
+       quoted = FALSE;
+       cursor = src;
+       if (CTSVC_VCARD_VER_2_1 == ver) {
+               while (*cursor) {
+                       if ('=' == *cursor && __ctsvc_vcard_check_quoted(src, cursor - src, &quoted)) {
+                               if ('\r' == *(cursor+1) && '\n' == *(cursor+2))
+                                       cursor += 2;
+                       } else {
+                               if ('\r' == *cursor && '\n' == *(cursor+1) && ' ' != *(cursor+2))
+                                       break;
+                               if ('\n' == *cursor && ' ' != *(cursor+1))
+                                       break;
+                       }
+
+                       cursor++;
+               }
+       }
+       else {
+               while (*cursor) {
+                       if ('\r' == *cursor && '\n' == *(cursor+1) && ' ' != *(cursor+2))
+                               break;
+
+                       if ('\n' == *cursor && ' ' != *(cursor+1))
+                               break;
+
+                       cursor++;
+               }
+       }
+
+       if (src == cursor) {
+               *dest = NULL;
+               return NULL;
+       }
+       else {
+               int len = 0;
+               char temp = *cursor;
+               char *new_dest;
+
+               if (prefix)
+                       __ctsvc_vcard_get_prefix(prefix, src);
+
+               *cursor = '\0';
+               *dest = strdup(src);
+               RETVM_IF(NULL == *dest, NULL, "strdup() return NULL");
+               if (CTSVC_VCARD_VER_2_1 != ver)
+                       __ctsvc_vcard_remove_folding(*dest);
+
+               if (__ctsvc_vcard_check_quoted(*dest, -1, &quoted))
+                       len = __ctsvc_vcard_decode_quoted_val(*dest);
+               if (0 == len)
+                       len = strlen(*dest);
+               new_dest = __ctsvc_vcard_translate_charset(*dest, len);
+               if (new_dest) {
+                       free(*dest);
+                       *dest = new_dest;
+               }
+               *cursor = temp;
+               return (cursor + 1);
+       }
+}
+
+static inline char* __ctsvc_get_content_value(char *val)
+{
+       char *temp;
+
+       temp = strchr(val, ':');
+       if (temp)
+               temp++;
+       else
+               temp = val;
+
+       RETVM_IF('\0' == *(temp) || '\r' == *(temp) || '\n' == *(temp),
+               NULL, "Invalid vcard content");
+
+       return temp;
+}
+
+static char* __ctsvc_vcard_remove_escape_char(char *str)
+{
+       char *s = SAFE_STR(str);
+       char *r = s;
+       while (*s) {
+               if (*s == '\\' && *(s+1)) {
+                       char *n = (char*)(s+1);
+                       switch (*n) {
+                       case 'n':
+                       case 'N':
+                               *r = '\n';
+                               s++;
+                               break;
+                       case ';':
+                       case ':':
+                       case ',':
+                       case '<':
+                       case '>':
+                       case '\\':
+                               *r = *n;
+                               s++;
+                               break;
+                       case 0xA1: // en/em backslash
+                               if (*(n+1) && 0xAC == *(n+1)) {
+                                       *r = *n;
+                                       r++;
+                                       *r = *(n+1);
+                                       s+=2;
+                               }
+                               break;
+                       case 0x81:  // en/em backslash
+                               if (*(n+1) && 0x5F == *(n+1)) {
+                                       *r = *n;
+                                       r++;
+                                       *r = *(n+1);
+                                       s+=2;
+                               }
+                               break;
+                       default:
+                               *r = *s;
+                               break;
+                       }
+                       r++;
+                       s++;
+               }
+               else {
+                       *r = *s;
+                       r++;
+                       s++;
+               }
+       }
+       *r = '\0';
+       return str;
+}
+
+static inline int __ctsvc_vcard_get_display_name(ctsvc_list_s *name_list, char *val)
+{
+       int ret;
+       int count;
+       char *temp;
+       char *first_name = NULL;
+       char *last_name = NULL;
+       contacts_record_h name;
+
+       temp = __ctsvc_get_content_value(val);
+       RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : vcard");
+
+       contacts_list_get_count((contacts_list_h)name_list, &count);
+       if (count <= 0) {
+               ret = contacts_record_create(_contacts_name._uri, &name);
+               RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret);
+               contacts_list_add((contacts_list_h)name_list, name);
+       }
+       else {
+               contacts_list_get_current_record_p((contacts_list_h)name_list, &name);
+       }
+
+       ret = contacts_record_get_str_p(name, _contacts_name.first, &first_name);
+       WARN_IF(ret != CONTACTS_ERROR_NONE, "contacts_record_get_str_p is failed(%d)", ret);
+       ret = contacts_record_get_str_p(name, _contacts_name.last, &last_name);
+       WARN_IF(ret != CONTACTS_ERROR_NONE, "contacts_record_get_str_p is failed(%d)", ret);
+
+       if ((NULL == first_name || '\0' == *first_name) && (NULL == last_name || '\0' == *last_name)) {
+               ret = contacts_record_set_str(name, _contacts_name.first, __ctsvc_vcard_remove_escape_char(temp));
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+#define CTS_GET_MULTIPLE_COMPONENT(dest, src, src_temp, separator) \
+src_temp = src; \
+separator = false; \
+while (src_temp && *src_temp) { \
+       if (*src_temp == ';') { \
+               separator = true; \
+               *src_temp = '\0'; \
+               src = __ctsvc_vcard_remove_escape_char(src); \
+               dest = SMART_STRDUP(src); \
+               src = src_temp+1; \
+               break; \
+       } \
+       else if (*src_temp == '\\') {\
+               src_temp+=2; \
+               continue; \
+       } \
+       src_temp++; \
+} \
+if (false == separator && src && *src) { \
+       src = __ctsvc_vcard_remove_escape_char(src); \
+       dest = SMART_STRDUP(src); \
+       break; \
+}
+
+static inline int __ctsvc_vcard_get_name(ctsvc_list_s *name_list, char *val)
+{
+       int ret;
+       int count;
+       char *start;
+       contacts_record_h name;
+
+       start = __ctsvc_get_content_value(val);
+       RETV_IF(NULL == start, CONTACTS_ERROR_NO_DATA);
+
+       contacts_list_get_count((contacts_list_h)name_list, &count);
+       if (count <= 0) {
+               ret = contacts_record_create(_contacts_name._uri, &name);
+               RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret);
+               contacts_list_add((contacts_list_h)name_list, name);
+       }
+       else {
+               contacts_list_get_current_record_p((contacts_list_h)name_list, &name);
+       }
+
+       ret = contacts_record_set_str(name, _contacts_name.first, NULL); // remove FN
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+
+       while (true) {
+               bool separator = false;
+               char *start_temp;
+
+               CTS_GET_MULTIPLE_COMPONENT(((ctsvc_name_s*)name)->last, start, start_temp, separator);
+               CTS_GET_MULTIPLE_COMPONENT(((ctsvc_name_s*)name)->first, start, start_temp, separator);
+               CTS_GET_MULTIPLE_COMPONENT(((ctsvc_name_s*)name)->addition, start, start_temp, separator);
+               CTS_GET_MULTIPLE_COMPONENT(((ctsvc_name_s*)name)->prefix, start, start_temp, separator);
+               CTS_GET_MULTIPLE_COMPONENT(((ctsvc_name_s*)name)->suffix, start, start_temp, separator);
+
+               CTS_ERR("invalid name type");
+               break;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_vcard_get_phonetic_name(ctsvc_list_s *name_list, int type, char *val)
+{
+       int ret;
+       int count;
+       char *start;
+       const char separator = ';';
+       contacts_record_h name;
+
+       start = __ctsvc_get_content_value(val);
+       RETV_IF(NULL == start, CONTACTS_ERROR_NO_DATA);
+
+       contacts_list_get_count((contacts_list_h)name_list, &count);
+       if (count <= 0) {
+               ret = contacts_record_create(_contacts_name._uri, &name);
+               RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret);
+               contacts_list_add((contacts_list_h)name_list, name);
+       }
+       else {
+               contacts_list_get_current_record_p((contacts_list_h)name_list, &name);
+       }
+
+       __ctsvc_strtok(start, separator);
+       if (CTSVC_VCARD_VALUE_PHONETIC_FIRST_NAME == type) {
+               ret = contacts_record_set_str(name, _contacts_name.phonetic_first, __ctsvc_vcard_remove_escape_char(start));
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+       }
+       else if (CTSVC_VCARD_VALUE_PHONETIC_MIDDLE_NAME == type) {
+               ret = contacts_record_set_str(name, _contacts_name.phonetic_middle, __ctsvc_vcard_remove_escape_char(start));
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+       }
+       else if (CTSVC_VCARD_VALUE_PHONETIC_LAST_NAME == type) {
+               ret = contacts_record_set_str(name, _contacts_name.phonetic_last, __ctsvc_vcard_remove_escape_char(start));
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_vcard_get_nickname(ctsvc_list_s *nickname_list, char *val)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       char *temp;
+       char *start;
+       const char *separator = ",";
+
+       start = __ctsvc_get_content_value(val);
+       RETV_IF(NULL == start, CONTACTS_ERROR_NO_DATA);
+
+       temp = strtok(start, separator);
+       while (temp) {
+               if ('\0' == *temp) continue;
+
+               contacts_record_h nickname = NULL;
+               ret = contacts_record_create(_contacts_nickname._uri, &nickname);
+               if (ret < CONTACTS_ERROR_NONE) {
+                       GList *cursor = NULL;
+                       CTS_ERR("contacts_record_create is failed(%d)", ret);
+                       for(cursor = nickname_list->records;cursor;cursor=cursor->next)
+                               contacts_record_destroy((contacts_record_h)(cursor->data), true);
+                       g_list_free(nickname_list->records);
+                       nickname_list->records = NULL;
+                       nickname_list->cursor = NULL;
+                       nickname_list->count = 0;
+                       return ret;
+               }
+               ret = contacts_record_set_str(nickname, _contacts_nickname.name, __ctsvc_vcard_remove_escape_char(start));
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+               contacts_list_add((contacts_list_h)nickname_list, nickname);
+
+               temp = strtok(NULL, separator);
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_vcard_get_photo(contacts_record_h contact, ctsvc_list_s *image_list, char *prefix, char *val)
+{
+       int ret, type, fd;
+       gsize size;
+       guchar *buf;
+       char *temp;
+       char dest[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+       contacts_record_h image;
+       struct timeval tv;
+
+       temp = strchr(val , ':');
+       RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : val is invalid");
+
+       *temp = '\0';
+
+       type = __ctsvc_vcard_get_image_type(prefix);
+
+       buf = g_base64_decode(temp+1, &size);
+       if (0 == size) {
+               g_free(buf);
+               return CONTACTS_ERROR_NONE;
+       }
+       RETVM_IF(NULL == buf, CONTACTS_ERROR_OUT_OF_MEMORY, "g_base64_decode() return NULL");
+
+       gettimeofday(&tv, NULL);
+       ret = snprintf(dest, sizeof(dest), "%s/vcard-image-%ld%ld.%s",
+                       CTSVC_VCARD_IMAGE_LOCATION, tv.tv_sec, tv.tv_usec, __ctsvc_get_img_suffix(type));
+
+       fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0660);
+       RETVM_IF(fd < 0, CONTACTS_ERROR_SYSTEM, "System : open Failed(%d)", errno);
+
+       while (0 < size) {
+               ret = write(fd, buf, size);
+               if (ret <= 0) {
+                       if (EINTR == errno)
+                               continue;
+                       else {
+                               CTS_ERR("write() Failed(%d)", errno);
+                               close(fd);
+                               if (ENOSPC == errno)
+                                       return CONTACTS_ERROR_FILE_NO_SPACE;            // No space
+                               else
+                                       return CONTACTS_ERROR_SYSTEM;           // IO error
+                       }
+               }
+               size -= ret;
+       }
+
+       close(fd);
+       g_free(buf);
+
+       ret = contacts_record_create(_contacts_image._uri, &image);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret);
+
+       ret = contacts_record_set_str(image, _contacts_image.path, dest);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+       ((ctsvc_image_s *)image)->is_vcard = true;
+
+       contacts_list_add((contacts_list_h)image_list, image);
+
+       // _contacts_contact.image_thumbnail_path is a read-only property
+       ((ctsvc_contact_s *)contact)->image_thumbnail_path = strdup(dest);
+
+       return CONTACTS_ERROR_NONE;
+
+}
+
+static inline void __ctsvc_vcard_get_event_type(contacts_record_h event, char *val)
+{
+       int type = CONTACTS_EVENT_TYPE_OTHER;
+       char *temp, *result, *last = NULL;
+       char *lower, *lower_temp;
+
+       temp = strtok_r(val, ";", &last);
+       while (temp) {
+               lower = strdup(temp);
+               if (NULL == lower) {
+                       CTS_ERR("strdup() return NULL");
+                       break;
+               }
+               lower_temp = lower;
+               while (*lower_temp) {
+                       *lower_temp = tolower(*lower_temp);
+                       lower_temp++;
+               }
+               if (strstr(lower, "anniversary"))
+                       type = CONTACTS_EVENT_TYPE_ANNIVERSARY;
+               else if (NULL != (result = strstr(lower, "x-"))) {
+                       int ret;
+                       type = CONTACTS_EVENT_TYPE_CUSTOM;
+                       ret = contacts_record_set_str(event, _contacts_event.label, temp+(result-lower)+2);
+                       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+               }
+
+               free(lower);
+               temp = strtok_r(NULL, ";", &last);
+       }
+       contacts_record_set_int(event, _contacts_event.type, type);
+}
+
+
+static inline int __ctsvc_vcard_get_event(ctsvc_list_s *event_list, int type, char *prefix, char *val)
+{
+       int ret;
+       contacts_record_h event;
+       char *dest, *src, *temp;
+
+       temp = __ctsvc_get_content_value(val);
+       if (NULL == temp) {
+               CTS_ERR("Invalid parameter : vcard");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       dest = src = val;
+       while (*src) {
+               if ('0' <= *src && *src <= '9') {
+                       *dest = *src;
+                       dest++;
+               }
+               src++;
+               if (8 <= dest - val)
+                       break;
+       }
+       *dest = '\0';
+       if ('\0' == *val) {
+               CTS_ERR("Invalid parameter : val(%d)", val);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = contacts_record_create(_contacts_event._uri, &event);
+       if (ret < CONTACTS_ERROR_NONE) {
+               CTS_ERR("contacts_record_create is failed(%d)", ret);
+               return ret;
+       }
+
+       contacts_record_set_int(event, _contacts_event.date, atoi(val));
+
+       if (CTSVC_VCARD_VALUE_BDAY == type)
+               contacts_record_set_int(event, _contacts_event.type, CONTACTS_EVENT_TYPE_BIRTH);
+       else if (CTSVC_VCARD_VALUE_X_ANNIVERSARY == type)
+               contacts_record_set_int(event, _contacts_event.type, CONTACTS_EVENT_TYPE_ANNIVERSARY);
+       else if (CTSVC_VCARD_VALUE_X_TIZEN_EVENT == type) {
+               __ctsvc_vcard_get_event_type(event, prefix);
+       }
+       contacts_list_add((contacts_list_h)event_list, event);
+       return CONTACTS_ERROR_NONE;
+}
+
+
+static inline void __ctsvc_vcard_get_company_type(contacts_record_h company, char *val)
+{
+       char *temp, *result, *last = NULL;
+       char *lower, *lower_temp;
+       int type = CONTACTS_COMPANY_TYPE_OTHER;
+
+       temp = strtok_r(val, ";", &last);
+       while (temp) {
+               lower = strdup(temp);
+               if (NULL == lower) {
+                       CTS_ERR("strdup() return NULL");
+                       break;
+               }
+               lower_temp = lower;
+               while (*lower_temp) {
+                       *lower_temp = tolower(*lower_temp);
+                       lower_temp++;
+               }
+
+               result = strstr(lower, "work");
+               if (result)
+                       type = CONTACTS_COMPANY_TYPE_WORK;
+
+               result = strstr(lower, "x-");
+               if (result) {
+                       int ret;
+                       type = CONTACTS_COMPANY_TYPE_CUSTOM;
+                       ret = contacts_record_set_str(company, _contacts_company.label, temp+(result-lower)+2);
+                       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+               }
+
+               free(lower);
+               temp = strtok_r(NULL, ";", &last);
+       }
+       contacts_record_set_int(company, _contacts_company.type, type);
+}
+
+static contacts_record_h __ctsvc_vcard_get_company_empty_record(ctsvc_list_s *company_list, int property_id)
+{
+       int ret;
+       contacts_record_h record_temp = NULL;
+       contacts_record_h record = NULL;
+       contacts_list_h list = (contacts_list_h)company_list;
+
+       contacts_list_last(list);
+       while (CONTACTS_ERROR_NONE == contacts_list_get_current_record_p(list, &record_temp)) {
+               char *value = NULL;
+               ret = contacts_record_get_str_p(record_temp, property_id, &value);
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_get_str_p() Fail(%d)", ret);
+               if (NULL == value) {
+                       record = record_temp;
+                       break;
+               }
+               contacts_list_prev(list);
+       }
+
+       return record;
+}
+
+static inline int __ctsvc_vcard_get_company_value(ctsvc_list_s *company_list, int property_id, char *val)
+{
+       int ret;
+       char *value;
+       contacts_record_h company;
+
+       company = __ctsvc_vcard_get_company_empty_record(company_list, property_id);
+       if (NULL == company) {
+               int ret = contacts_record_create(_contacts_company._uri, &company);
+               RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret);
+               contacts_list_add((contacts_list_h)company_list, company);
+       }
+
+       value = __ctsvc_get_content_value(val);
+       RETV_IF(NULL == value, CONTACTS_ERROR_NO_DATA);
+
+       ret = contacts_record_set_str(company, property_id, __ctsvc_vcard_remove_escape_char(value));
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_vcard_get_company(ctsvc_list_s *company_list, char *prefix, char *val)
+{
+       char *start, *depart;
+       const char separator = ';';
+       contacts_record_h company;
+
+       company = __ctsvc_vcard_get_company_empty_record(company_list, _contacts_company.name);
+       if (NULL == company) {
+               int ret = contacts_record_create(_contacts_company._uri, &company);
+               RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret);
+               contacts_list_add((contacts_list_h)company_list, company);
+       }
+
+       start = __ctsvc_get_content_value(val);
+       RETV_IF(NULL == start, CONTACTS_ERROR_NO_DATA);
+
+       depart = __ctsvc_strtok(start, separator);
+       contacts_record_set_str(company, _contacts_company.name, __ctsvc_vcard_remove_escape_char(start));
+
+       if (depart) {
+               int ret;
+               __ctsvc_strtok(depart, separator);
+               ret = contacts_record_set_str(company, _contacts_company.department, __ctsvc_vcard_remove_escape_char(depart));
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+       }
+
+       __ctsvc_vcard_get_company_type(company, prefix);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_vcard_get_company_logo(ctsvc_list_s *company_list, char *prefix, char *val)
+{
+       int ret, type, fd;
+       gsize size;
+       guchar *buf;
+       char dest[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+       char *temp;
+       contacts_record_h company;
+       struct timeval tv;
+
+       company = __ctsvc_vcard_get_company_empty_record(company_list, _contacts_company.logo);
+       if (NULL == company) {
+               ret = contacts_record_create(_contacts_company._uri, &company);
+               RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret);
+               contacts_list_add((contacts_list_h)company_list, company);
+       }
+
+       temp = strchr(val , ':');
+       RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : val is invalid");
+
+       *temp = '\0';
+       type = __ctsvc_vcard_get_image_type(prefix);
+
+       buf = g_base64_decode(temp+1, &size);
+       if (0 == size) {
+               g_free(buf);
+               return CONTACTS_ERROR_NONE;
+       }
+       RETVM_IF(NULL == buf, CONTACTS_ERROR_OUT_OF_MEMORY, "g_base64_decode() return NULL");
+
+       gettimeofday(&tv, NULL);
+       ret = snprintf(dest, sizeof(dest), "%s/%d-%ld%ld-logo.%s", CTSVC_VCARD_IMAGE_LOCATION,
+                       getpid(), tv.tv_sec, tv.tv_usec, __ctsvc_get_img_suffix(type));
+
+       fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0660);
+       RETVM_IF(fd < 0, CONTACTS_ERROR_SYSTEM, "System : open Failed(%d)", errno);
+
+       while (0 < size) {
+               ret = write(fd, buf, size);
+               if (ret <= 0) {
+                       if (EINTR == errno)
+                               continue;
+                       else {
+                               CTS_ERR("write() Failed(%d)", errno);
+                               close(fd);
+                               if (ENOSPC == errno)
+                                       return CONTACTS_ERROR_FILE_NO_SPACE;            // No space
+                               else
+                                       return CONTACTS_ERROR_SYSTEM;           // IO error
+                       }
+               }
+               size -= ret;
+       }
+
+       close(fd);
+       g_free(buf);
+
+       ((ctsvc_company_s *)company)->is_vcard = true;
+       contacts_record_set_str(company, _contacts_company.logo, dest);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_vcard_get_note(ctsvc_list_s *note_list, char *val)
+{
+       int ret;
+       char *temp;
+       contacts_record_h note;
+
+       ret = contacts_record_create(_contacts_note._uri, &note);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret);
+       contacts_list_add((contacts_list_h)note_list, note);
+
+       temp = __ctsvc_get_content_value(val);
+       RETV_IF(NULL == temp, CONTACTS_ERROR_NO_DATA);
+
+       ret = contacts_record_set_str(note, _contacts_note.note, __ctsvc_vcard_remove_escape_char(temp));
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_vcard_get_time(char *val)
+{
+       int i;
+       char tmp[10] = {0};
+       struct tm ts = {0};
+
+       i = 0;
+       while (*val && (*val < '0' || '9' < *val)) val++;
+       while (*val) {
+               tmp[i++] = *val;
+               val++;
+               if (4<=i || *val < '0' || '9' < *val) break;
+       }
+       tmp[i] = 0;
+       ts.tm_year = atoi(tmp)-1900;
+
+       i = 0;
+       while (*val && (*val < '0' || '9' < *val)) val++;
+       while (*val) {
+               tmp[i++] = *val;
+               val++;
+               if (2<=i || *val < '0' || '9' < *val) break;
+       }
+       tmp[i] = 0;
+       ts.tm_mon = atoi(tmp)-1;
+
+       i = 0;
+       while (*val && (*val < '0' || '9' < *val)) val++;
+       while (*val) {
+               tmp[i++] = *val;
+               val++;
+               if (2<=i || *val < '0' || '9' < *val) break;
+       }
+       tmp[i] = 0;
+       ts.tm_mday = atoi(tmp);
+
+       i = 0;
+       while (*val && (*val < '0' || '9' < *val)) val++;
+       while (*val) {
+               tmp[i++] = *val;
+               val++;
+               if (2<=i || *val < '0' || '9' < *val) break;
+       }
+       tmp[i] = 0;
+       ts.tm_hour = atoi(tmp);
+
+       i = 0;
+       while (*val && (*val < '0' || '9' < *val)) val++;
+       while (*val) {
+               tmp[i++] = *val;
+               val++;
+               if (2<=i || *val < '0' || '9' < *val) break;
+       }
+       tmp[i] = 0;
+       ts.tm_min = atoi(tmp);
+
+       i = 0;
+       while (*val && (*val < '0' || '9' < *val)) val++;
+       while (*val) {
+               tmp[i++] = *val;
+               val++;
+               if (2<=i || *val < '0' || '9' < *val) break;
+       }
+       tmp[i] = 0;
+       ts.tm_sec = atoi(tmp);
+
+       return (int)mktime(&ts);
+}
+
+static inline void __ctsvc_vcard_get_url_type(contacts_record_h url, char *val)
+{
+       char *temp, *result, *last = NULL;
+       char *lower, *lower_temp;
+       int type = CONTACTS_URL_TYPE_OTHER;
+
+       temp = strtok_r(val, ";", &last);
+       while (temp) {
+               lower = strdup(temp);
+               if (NULL == lower) {
+                       CTS_ERR("strdup() return NULL");
+                       break;
+               }
+               lower_temp = lower;
+               while (*lower_temp) {
+                       *lower_temp = tolower(*lower_temp);
+                       lower_temp++;
+               }
+               result = strstr(lower, "home");
+               if (result) type = CONTACTS_URL_TYPE_HOME;
+               result = strstr(lower, "work");
+               if (result) type = CONTACTS_URL_TYPE_WORK;
+               result = strstr(lower, "x-");
+               if (result) {
+                       int ret;
+                       type = CONTACTS_URL_TYPE_CUSTOM;
+                       ret = contacts_record_set_str(url, _contacts_url.label, temp+(result-lower)+2);
+                       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+               }
+
+               free(lower);
+               temp = strtok_r(NULL, ";", &last);
+       }
+       contacts_record_set_int(url, _contacts_url.type, type);
+}
+
+static inline int __ctsvc_vcard_get_url(ctsvc_list_s* url_list, char *prefix, char *val)
+{
+       int ret;
+       contacts_record_h url;
+       char *temp;
+
+       temp = __ctsvc_get_content_value(val);
+       RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : vcard");
+
+       ret = contacts_record_create(_contacts_url._uri, &url);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret);
+
+       ret = contacts_record_set_str(url, _contacts_url.url, __ctsvc_vcard_remove_escape_char(temp));
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+       __ctsvc_vcard_get_url_type(url, prefix);
+       contacts_list_add((contacts_list_h)url_list, url);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline bool __ctsvc_vcard_get_number_type(contacts_record_h number, char *val)
+{
+       char *temp, *result, *last = NULL;
+       char *lower, *lower_temp;
+       int type = CONTACTS_NUMBER_TYPE_OTHER;
+       bool pref = false;
+
+       temp = strtok_r(val, ";", &last);
+       while (temp) {
+               lower = strdup(temp);
+               if (NULL == lower) {
+                       CTS_ERR("strdup() return NULL");
+                       break;
+               }
+               lower_temp = lower;
+               while (*lower_temp) {
+                       *lower_temp = tolower(*lower_temp);
+                       lower_temp++;
+               }
+               result = strstr(lower, "home");
+               if (result) type |= CONTACTS_NUMBER_TYPE_HOME;
+               result = strstr(lower, "msg");
+               if (result) type |= CONTACTS_NUMBER_TYPE_MSG;
+               result = strstr(lower, "work");
+               if (result) type |= CONTACTS_NUMBER_TYPE_WORK;
+               result = strstr(lower, "pref");
+               if (result) pref = true;
+               result = strstr(lower, "voice");
+               if (result) type |= CONTACTS_NUMBER_TYPE_VOICE;
+               result = strstr(lower, "fax");
+               if (result) type |= CONTACTS_NUMBER_TYPE_FAX;
+               result = strstr(lower, "cell");
+               if (result) type |= CONTACTS_NUMBER_TYPE_CELL;
+               result = strstr(lower, "video");
+               if (result) type |= CONTACTS_NUMBER_TYPE_VIDEO;
+               result = strstr(lower, "pager");
+               if (result) type |= CONTACTS_NUMBER_TYPE_PAGER;
+               result = strstr(lower, "bbs");
+               if (result) type |= CONTACTS_NUMBER_TYPE_BBS;
+               result = strstr(lower, "modem");
+               if (result) type |= CONTACTS_NUMBER_TYPE_MODEM;
+               result = strstr(lower, "car");
+               if (result) type |= CONTACTS_NUMBER_TYPE_CAR;
+               result = strstr(lower, "isdn");
+               if (result) type |= CONTACTS_NUMBER_TYPE_ISDN;
+               result = strstr(lower, "pcs");
+               if (result) type |= CONTACTS_NUMBER_TYPE_PCS;
+               result = strstr(lower, "x-");
+               if (result) {
+                       if (strstr(lower, "x-assistant"))
+                               type |= CONTACTS_NUMBER_TYPE_ASSISTANT;
+                       else if (strstr(lower, "x-radio"))
+                               type |= CONTACTS_NUMBER_TYPE_RADIO;
+                       else if (strstr(lower, "x-company-main"))
+                               type |= CONTACTS_NUMBER_TYPE_COMPANY_MAIN;
+                       else if (strstr(lower, "x-main"))
+                               type |= CONTACTS_NUMBER_TYPE_MAIN;
+                       else {
+                               int ret;
+                               type = CONTACTS_NUMBER_TYPE_CUSTOM;
+                               ret = contacts_record_set_str(number, _contacts_number.label, temp+(result-lower)+2);
+                               WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+
+                       }
+               }
+
+               free(lower);
+               temp = strtok_r(NULL, ";", &last);
+       }
+       contacts_record_set_int(number, _contacts_number.type, type);
+
+       return pref;
+}
+
+static char* __ctsvc_vcard_get_clean_number_for_import(char *str)
+{
+       int char_len = 0;
+       char *s = SAFE_STR(str);
+       char *r = s;
+       while (*s) {
+               char_len = __ctsvc_vcard_check_utf8(*s);
+               if (3 == char_len) {
+                       if (*s == 0xef) {
+                               if (*(s+1) == 0xbc) {
+                                       if (0x90 <= *(s+2) && *(s+2) <= 0x99) {                         // ef bc 90 : '0' ~ ef bc 99 : '9'
+                                               *r = '0' + (*(s+2) - 0x90);
+                                               r++;
+                                               s+=3;
+                                       }
+                                       else if (0x8b == *(s+2)) {                                                              // ef bc 8b : '+'
+                                               *r = '+';
+                                               r++;
+                                               s+=3;
+                                       }
+                                       else if (0x8a == *(s+2)) {                                                              // ef bc 8a : '*'
+                                               *r = '*';
+                                               r++;
+                                               s+=3;
+                                       }
+                                       else if (0x83 == *(s+2)) {                                                              // ef bc 83 : '#'
+                                               *r = '#';
+                                               r++;
+                                               s+=3;
+                                       }
+                                       else if (0xb0 == *(s+2) || 0x8c == *(s+2)) {            // ef bc b0 : 'P', ef bc 8c : ','
+                                               *r = ',';
+                                               r++;
+                                               s+=3;
+                                       }
+                                       else if (0xb7 == *(s+2) || 0x9b == *(s+2)) {            // ef bc b7 : 'W', ef bc 9b : ';'
+                                               *r = ';';
+                                               r++;
+                                               s+=3;
+                                       }
+                                       else {
+                                               s+=char_len;
+                                       }
+                               }
+                               else if (*(s+1) == 0xbd) {
+                                       if (0x90 == *(s+2)) {
+                                               *r = ',';
+                                               r++;
+                                               s+=3;
+                                       }
+                                       else if (0x97 == *(s+2)) {
+                                               *r = ';';
+                                               r++;
+                                               s+=3;
+                                       }
+                               }
+                               else {
+                                       s+=char_len;
+                               }
+                       }
+                       else {
+                               s+=char_len;
+                       }
+               }
+               else if (1 == char_len) {
+                       switch (*s) {
+                               case '/':
+                               case 'N':
+                               case '.':
+                               case '0' ... '9':
+                               case '#':
+                               case '*':
+                               case '(':
+                               case ')':
+                               case ',':
+                               case ';':
+                               case '+':
+                                       *r = *s;
+                                       r++;
+                                       s++;
+                                       break;
+                               case 'p':
+                               case 'P':
+                                       *r = ',';
+                                       r++;
+                                       s++;
+                                       break;
+                               case 'w':
+                               case 'W':
+                                       *r = ';';
+                                       r++;
+                                       s++;
+                                       break;
+                               default:
+                                       s++;
+                                       break;
+                       }
+               }
+               else {
+                       s+=char_len;
+               }
+       }
+       *r = '\0';
+       return str;
+}
+
+static inline int __ctsvc_vcard_get_number(ctsvc_list_s *numbers, char *prefix, char *val)
+{
+       bool is_default;
+       int ret;
+       char *temp;
+       contacts_record_h number;
+
+       temp = __ctsvc_get_content_value(val);
+       RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : vcard");
+
+       ret = contacts_record_create(_contacts_number._uri, &number);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret);
+
+       temp = __ctsvc_vcard_remove_escape_char(temp);
+       ret = contacts_record_set_str(number, _contacts_number.number, __ctsvc_vcard_get_clean_number_for_import(temp));
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+
+       is_default = __ctsvc_vcard_get_number_type(number, prefix);
+               contacts_record_set_bool(number, _contacts_number.is_default, is_default);
+       contacts_list_add((contacts_list_h)numbers, number);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline bool __ctsvc_vcard_get_email_type(contacts_record_h email, char *val)
+{
+       char *temp, *result, *last = NULL;
+       char *lower, *lower_temp;
+       int type = CONTACTS_EMAIL_TYPE_OTHER;
+       bool pref = false;
+
+       temp = strtok_r(val, ";", &last);
+       while (temp) {
+               lower = strdup(temp);
+               if (NULL == lower) {
+                       CTS_ERR("strdup() return NULL");
+                       break;
+               }
+               lower_temp = lower;
+               while (*lower_temp) {
+                       *lower_temp = tolower(*lower_temp);
+                       lower_temp++;
+               }
+               if (strstr(lower, "pref"))
+                       pref = true;
+               if (strstr(lower, "home"))
+                       type = CONTACTS_EMAIL_TYPE_HOME;
+               else if (strstr(lower, "work"))
+                       type = CONTACTS_EMAIL_TYPE_WORK;
+               else if (strstr(lower, "cell"))
+                       type = CONTACTS_EMAIL_TYPE_MOBILE;
+               else if (NULL != (result = strstr(lower, "x-"))) {
+                       int ret;
+                       type = CONTACTS_EMAIL_TYPE_CUSTOM;
+                       ret = contacts_record_set_str(email, _contacts_email.label, temp+(result-lower)+2);
+                       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+               }
+
+               free(lower);
+               temp = strtok_r(NULL, ";", &last);
+       }
+       contacts_record_set_int(email, _contacts_email.type, type);
+
+       return pref;
+}
+
+static inline int __ctsvc_vcard_get_email(ctsvc_list_s* emails, char *prefix, char *val)
+{
+       bool is_default;
+       int ret;
+       char *temp;
+       contacts_record_h email;
+
+       temp = __ctsvc_get_content_value(val);
+       RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : vcard");
+
+       ret = contacts_record_create(_contacts_email._uri, &email);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret);
+
+       ret = contacts_record_set_str(email, _contacts_email.email, __ctsvc_vcard_remove_escape_char(temp));
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+       is_default = __ctsvc_vcard_get_email_type(email, prefix);
+               contacts_record_set_bool(email, _contacts_email.is_default, is_default);
+       contacts_list_add((contacts_list_h)emails, email);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline bool __ctsvc_vcard_get_postal_type(contacts_record_h address, char *val)
+{
+       char *temp, *result, *last = NULL;
+       char *lower, *lower_temp;
+       int type = CONTACTS_ADDRESS_TYPE_OTHER;
+       bool pref = false;
+
+       temp = strtok_r(val, ";", &last);
+       while (temp) {
+               lower = strdup(temp);
+               if (NULL == lower) {
+                       CTS_ERR("strdup() return NULL");
+                       break;
+               }
+               lower_temp = lower;
+               while (*lower_temp) {
+                       *lower_temp = tolower(*lower_temp);
+                       lower_temp++;
+               }
+               result = strstr(lower, "dom");
+               if (result) type |= CONTACTS_ADDRESS_TYPE_DOM;
+               result = strstr(lower, "intl");
+               if (result) type |= CONTACTS_ADDRESS_TYPE_INTL;
+               result = strstr(lower, "address");
+               if (result) type |= CONTACTS_ADDRESS_TYPE_POSTAL;
+               result = strstr(lower, "parcel");
+               if (result) type |= CONTACTS_ADDRESS_TYPE_PARCEL;
+               result = strstr(lower, "home");
+               if (result) type |= CONTACTS_ADDRESS_TYPE_HOME;
+               result = strstr(lower, "work");
+               if (result) type |= CONTACTS_ADDRESS_TYPE_WORK;
+               result = strstr(lower, "x-");
+               if (result) {
+                       int ret;
+                       type = CONTACTS_ADDRESS_TYPE_CUSTOM;
+                       ret = contacts_record_set_str(address, _contacts_address.label, temp+(result-lower)+2);
+                       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+               }
+               result = strstr(val, "pref");
+               if (result) pref = true;
+
+               free(lower);
+               temp = strtok_r(NULL, ";", &last);
+       }
+
+       contacts_record_set_int(address, _contacts_address.type, type);
+
+       return pref;
+}
+
+static inline int __ctsvc_vcard_get_address(ctsvc_list_s *address_list, char *prefix, char *val)
+{
+       char *text;
+       char *text_temp;
+       contacts_record_h address;
+
+       contacts_record_create(_contacts_address._uri, &address);
+       if (address) {
+
+               text = strchr(val, ':');
+               if (text) {
+                       text++;
+                       *(text-1) = '\0';
+               }
+               else
+                       text = val;
+
+               while (true) {
+                       bool separator = false;
+
+                       CTS_GET_MULTIPLE_COMPONENT(((ctsvc_address_s*)address)->pobox, text, text_temp, separator);
+                       CTS_GET_MULTIPLE_COMPONENT(((ctsvc_address_s*)address)->extended, text, text_temp, separator);
+                       CTS_GET_MULTIPLE_COMPONENT(((ctsvc_address_s*)address)->street, text, text_temp, separator);
+                       CTS_GET_MULTIPLE_COMPONENT(((ctsvc_address_s*)address)->locality, text, text_temp, separator);
+                       CTS_GET_MULTIPLE_COMPONENT(((ctsvc_address_s*)address)->region, text, text_temp, separator);
+                       CTS_GET_MULTIPLE_COMPONENT(((ctsvc_address_s*)address)->postalcode, text, text_temp, separator);
+                       CTS_GET_MULTIPLE_COMPONENT(((ctsvc_address_s*)address)->country, text, text_temp, separator);
+
+                       CTS_ERR("invalid ADR type");
+                       break;
+               }
+
+               if (((ctsvc_address_s*)address)->pobox || ((ctsvc_address_s*)address)->extended
+                               || ((ctsvc_address_s*)address)->street || ((ctsvc_address_s*)address)->locality
+                               || ((ctsvc_address_s*)address)->region || ((ctsvc_address_s*)address)->postalcode
+                               || ((ctsvc_address_s*)address)->country) {
+                       contacts_record_set_bool(address, _contacts_address.is_default, __ctsvc_vcard_get_postal_type(address, prefix));
+               } else {
+                       CTS_ERR("Invalid vcard");
+                       contacts_record_destroy(address, true);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               contacts_list_add((contacts_list_h)address_list, address);
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline void __ctsvc_vcard_get_messenger_type(contacts_record_h messenger, char *val)
+{
+       char *temp, *result, *last = NULL;
+       char *lower, *lower_temp;
+       int type = CONTACTS_MESSENGER_TYPE_OTHER;
+
+       temp = strtok_r(val, ";", &last);
+       while (temp) {
+               lower = strdup(temp);
+               if (NULL == lower) {
+                       CTS_ERR("strdup() return NULL");
+                       break;
+               }
+               lower_temp = lower;
+               while (*lower_temp) {
+                       *lower_temp = tolower(*lower_temp);
+                       lower_temp++;
+               }
+               result = strstr(lower, "facebook");
+               if (result) type = CONTACTS_MESSENGER_TYPE_FACEBOOK;
+               result = strstr(lower, "irc");
+               if (result) type = CONTACTS_MESSENGER_TYPE_IRC;
+               result = strstr(lower, "x-");
+               if (result) {
+                       int ret;
+                       type = CONTACTS_MESSENGER_TYPE_CUSTOM;
+                       ret = contacts_record_set_str(messenger, _contacts_messenger.label, temp+(result-lower)+2);
+                       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+               }
+               free(lower);
+               temp = strtok_r(NULL, ";", &last);
+       }
+       contacts_record_set_int(messenger, _contacts_messenger.type, type);
+}
+
+static inline int __ctsvc_vcard_get_messenger(ctsvc_list_s* messenger_list, int type, char *prefix, char *val)
+{
+       int ret;
+       contacts_record_h messenger;
+       char *temp;
+
+       temp = __ctsvc_get_content_value(val);
+       RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : vcard");
+
+       ret = contacts_record_create(_contacts_messenger._uri, &messenger);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret);
+
+       ret = contacts_record_set_str(messenger, _contacts_messenger.im_id, __ctsvc_vcard_remove_escape_char(temp));
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+
+       switch (type) {
+       case CTSVC_VCARD_VALUE_X_MSN:
+               contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_WLM);
+               break;
+       case CTSVC_VCARD_VALUE_X_YAHOO:
+               contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_YAHOO);
+               break;
+       case CTSVC_VCARD_VALUE_X_ICQ:
+               contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_ICQ);
+               break;
+       case CTSVC_VCARD_VALUE_X_AIM:
+               contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_AIM);
+               break;
+       case CTSVC_VCARD_VALUE_X_JABBER:
+               contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_JABBER);
+               break;
+       case CTSVC_VCARD_VALUE_X_SKYPE_USERNAME:
+       case CTSVC_VCARD_VALUE_X_SKYPE:
+               contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_SKYPE);
+               break;
+       case CTSVC_VCARD_VALUE_X_QQ:
+               contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_QQ);
+               break;
+       case CTSVC_VCARD_VALUE_X_GOOGLE_TALK:
+               contacts_record_set_int(messenger, _contacts_messenger.type, CONTACTS_MESSENGER_TYPE_GOOGLE);
+               break;
+       case CTSVC_VCARD_VALUE_X_TIZEN_MESSENGER:
+               __ctsvc_vcard_get_messenger_type(messenger, prefix);
+               break;
+       }
+       contacts_list_add((contacts_list_h)messenger_list, messenger);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline void __ctsvc_vcard_get_relationship_type(contacts_record_h relationship, char *val)
+{
+       char *temp, *result, *last = NULL;
+       char *lower, *lower_temp;
+       int type = CONTACTS_RELATIONSHIP_TYPE_OTHER;
+
+       temp = strtok_r(val, ";", &last);
+       while (temp) {
+               lower = strdup(temp);
+               if (NULL == lower) {
+                       CTS_ERR("strdup() return NULL");
+                       break;
+               }
+               lower_temp = lower;
+               while (*lower_temp) {
+                       *lower_temp = tolower(*lower_temp);
+                       lower_temp++;
+               }
+               if (strstr(lower, "assistant"))
+                       type = CONTACTS_RELATIONSHIP_TYPE_ASSISTANT;
+               else if (strstr(lower, "brother"))
+                       type = CONTACTS_RELATIONSHIP_TYPE_BROTHER;
+               else if (strstr(lower, "child"))
+                       type = CONTACTS_RELATIONSHIP_TYPE_CHILD;
+               else if (strstr(lower, "domestic_partner"))
+                       type = CONTACTS_RELATIONSHIP_TYPE_DOMESTIC_PARTNER;
+               else if (strstr(lower, "father"))
+                       type = CONTACTS_RELATIONSHIP_TYPE_FATHER;
+               else if (strstr(lower, "friend"))
+                       type = CONTACTS_RELATIONSHIP_TYPE_FRIEND;
+               else if (strstr(lower, "manager"))
+                       type = CONTACTS_RELATIONSHIP_TYPE_MANAGER;
+               else if (strstr(lower, "mother"))
+                       type = CONTACTS_RELATIONSHIP_TYPE_MOTHER;
+               else if (strstr(lower, "parent"))
+                       type = CONTACTS_RELATIONSHIP_TYPE_PARENT;
+               else if (strstr(lower, "partner"))
+                       type = CONTACTS_RELATIONSHIP_TYPE_PARTNER;
+               else if (strstr(lower, "referred_by"))
+                       type = CONTACTS_RELATIONSHIP_TYPE_REFERRED_BY;
+               else if (strstr(lower, "relative"))
+                       type = CONTACTS_RELATIONSHIP_TYPE_RELATIVE;
+               else if (strstr(lower, "sister"))
+                       type = CONTACTS_RELATIONSHIP_TYPE_SISTER;
+               else if (strstr(lower, "spouse"))
+                       type = CONTACTS_RELATIONSHIP_TYPE_SPOUSE;
+               else if (NULL != (result = strstr(lower, "x-"))) {
+                       int ret;
+                       type = CONTACTS_RELATIONSHIP_TYPE_CUSTOM;
+                       ret = contacts_record_set_str(relationship, _contacts_relationship.label, temp+(result-lower)+2);
+                       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+               }
+               free(lower);
+               temp = strtok_r(NULL, ";", &last);
+       }
+       contacts_record_set_int(relationship, _contacts_relationship.type, type);
+}
+
+
+static inline int __ctsvc_vcard_get_relationship(ctsvc_list_s* relationship_list, int type, char *prefix, char *val)
+{
+       int ret;
+       char *temp;
+       contacts_record_h relationship;
+
+       temp = __ctsvc_get_content_value(val);
+       RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : vcard");
+
+       ret = contacts_record_create(_contacts_relationship._uri, &relationship);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret);
+
+       ret = contacts_record_set_str(relationship, _contacts_relationship.name, __ctsvc_vcard_remove_escape_char(temp));
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+       __ctsvc_vcard_get_relationship_type(relationship, prefix);
+       contacts_list_add((contacts_list_h)relationship_list, relationship);
+
+       return CONTACTS_ERROR_NONE;
+
+}
+
+static char* __ctsvc_vcard_decode_base64_val(char *val)
+{
+       gsize size = 0;
+       guchar *decoded_str;
+       char *src;
+       char *dest = NULL;
+
+       src = strchr(val, ':');
+       if (NULL == src)
+               src = val;
+       else
+               src++;
+
+       decoded_str = g_base64_decode(src, &size);
+       RETVM_IF(NULL == decoded_str, NULL, "g_base64_decode() return NULL");
+
+       dest = calloc((src-val)+size+1, sizeof(char));
+       RETVM_IF(NULL == dest, NULL, "calloc() return NULL");
+
+       snprintf(dest, (src-val)+1, "%s", val);
+       snprintf(dest+(src-val), size+1, "%s", decoded_str);
+       g_free(decoded_str);
+
+       return dest;
+}
+
+static inline int __ctsvc_vcard_get_contact(int ver, char *vcard, contacts_record_h *record)
+{
+       int ret;
+       int type;
+       char *cursor, *new_start, *val, *prefix;
+       ctsvc_contact_s *contact = (ctsvc_contact_s*)*record;
+
+       cursor = vcard;
+       while (cursor) {
+               val = NULL;
+               prefix = NULL;
+
+               bool base64_encoded = false;
+               type = __ctsvc_vcard_check_content_type(&cursor);
+               if (CTSVC_VCARD_VALUE_NONE == type) {
+                       new_start = __ctsvc_vcard_pass_unsupported(cursor);
+                       if (new_start) {
+                               cursor = new_start;
+                               continue;
+                       }
+                       else
+                               break;
+               }
+
+               if (CTSVC_VCARD_VALUE_PHOTO != type && CTSVC_VCARD_VALUE_LOGO != type)
+                       base64_encoded = __ctsvc_vcard_check_base64_encoded(cursor);
+
+               new_start = __ctsvc_vcard_get_val(ver, cursor, &prefix, &val);
+               if (NULL == new_start) {
+                       free(prefix);
+                       free(val);
+                       continue;
+               }
+
+               if (NULL == val) {
+                       cursor = new_start;
+                       free(prefix);
+                       free(val);
+                       continue;
+               }
+
+               if (base64_encoded) {
+                       char *temp = __ctsvc_vcard_decode_base64_val(val);
+                       free(val);
+                       val = temp;
+                       if (NULL == val) {
+                               CTS_ERR("__ctsvc_vcard_decode_base64_val() return NULL");
+                               cursor = new_start;
+                               free(prefix);
+                               continue;
+                       }
+               }
+
+               switch (type) {
+               case CTSVC_VCARD_VALUE_FN:
+                       __ctsvc_vcard_get_display_name(contact->name, val);
+                       break;
+               case CTSVC_VCARD_VALUE_N:
+                       __ctsvc_vcard_get_name(contact->name, val);
+                       break;
+               case CTSVC_VCARD_VALUE_PHONETIC_FIRST_NAME:
+               case CTSVC_VCARD_VALUE_PHONETIC_MIDDLE_NAME:
+               case CTSVC_VCARD_VALUE_PHONETIC_LAST_NAME:
+                       __ctsvc_vcard_get_phonetic_name(contact->name, type, val);
+                       break;
+               case CTSVC_VCARD_VALUE_NICKNAME:
+                       __ctsvc_vcard_get_nickname(contact->nicknames, val);
+                       break;
+               case CTSVC_VCARD_VALUE_PHOTO:
+                       __ctsvc_vcard_get_photo(*record, contact->images, prefix, val);
+                       break;
+               case CTSVC_VCARD_VALUE_BDAY:
+               case CTSVC_VCARD_VALUE_X_ANNIVERSARY:
+               case CTSVC_VCARD_VALUE_X_TIZEN_EVENT:
+                       __ctsvc_vcard_get_event(contact->events, type, prefix, val);
+                       break;
+               case CTSVC_VCARD_VALUE_ADR:
+                       __ctsvc_vcard_get_address(contact->postal_addrs, prefix, val);
+                       break;
+               case CTSVC_VCARD_VALUE_TEL:
+                       __ctsvc_vcard_get_number(contact->numbers, prefix, val);
+                       break;
+               case CTSVC_VCARD_VALUE_EMAIL:
+                       __ctsvc_vcard_get_email(contact->emails, prefix, val);
+                       break;
+               case CTSVC_VCARD_VALUE_TITLE:
+                       __ctsvc_vcard_get_company_value(contact->company, _contacts_company.job_title, val);
+                       break;
+               case CTSVC_VCARD_VALUE_ROLE:
+                       __ctsvc_vcard_get_company_value(contact->company, _contacts_company.role, val);
+                       break;
+               case CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_LOCATION:
+                       __ctsvc_vcard_get_company_value(contact->company, _contacts_company.location, val);
+                       break;
+               case CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_DESCRIPTION:
+                       __ctsvc_vcard_get_company_value(contact->company, _contacts_company.description, val);
+                       break;
+               case CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_PHONETIC_NAME:
+                       __ctsvc_vcard_get_company_value(contact->company, _contacts_company.phonetic_name, val);
+                       break;
+               case CTSVC_VCARD_VALUE_X_TIZEN_COMPANY_ASSISTANT_NAME:
+                       __ctsvc_vcard_get_company_value(contact->company, _contacts_company.assistant_name, val);
+                       break;
+               case CTSVC_VCARD_VALUE_LOGO:
+                       __ctsvc_vcard_get_company_logo(contact->company, prefix, val);
+                       break;
+               case CTSVC_VCARD_VALUE_ORG:
+                       __ctsvc_vcard_get_company(contact->company, prefix, val);
+                       break;
+               case CTSVC_VCARD_VALUE_NOTE:
+                       __ctsvc_vcard_get_note(contact->note, val);
+                       break;
+               case CTSVC_VCARD_VALUE_REV:
+                       if (*val)
+                               contact->changed_time = __ctsvc_vcard_get_time(val);
+                       break;
+               case CTSVC_VCARD_VALUE_UID:
+                       ret = contacts_record_set_str((contacts_record_h)contact, _contacts_contact.uid, __ctsvc_vcard_remove_escape_char(val));
+                       WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_set_str() Fail(%d)", ret);
+                       break;
+               case CTSVC_VCARD_VALUE_URL:
+                       __ctsvc_vcard_get_url(contact->urls, prefix, val);
+                       break;
+               case CTSVC_VCARD_VALUE_X_MSN:
+               case CTSVC_VCARD_VALUE_X_YAHOO:
+               case CTSVC_VCARD_VALUE_X_ICQ:
+               case CTSVC_VCARD_VALUE_X_AIM:
+               case CTSVC_VCARD_VALUE_X_JABBER:
+               case CTSVC_VCARD_VALUE_X_SKYPE_USERNAME:
+               case CTSVC_VCARD_VALUE_X_SKYPE:
+               case CTSVC_VCARD_VALUE_X_QQ:
+               case CTSVC_VCARD_VALUE_X_GOOGLE_TALK:
+               case CTSVC_VCARD_VALUE_X_TIZEN_MESSENGER:
+                       __ctsvc_vcard_get_messenger(contact->messengers, type, prefix, val);
+                       break;
+
+               case CTSVC_VCARD_VALUE_X_TIZEN_RELATIONSHIP:
+                       __ctsvc_vcard_get_relationship(contact->relationships, type, prefix, val);
+                       break;
+               case CTSVC_VCARD_VALUE_END:
+                       free(val);
+                       free(prefix);
+                       return CONTACTS_ERROR_NONE;
+               default:
+                       CTS_ERR("Invalid parameter : __ctsvc_vcard_check_content_type() Failed(%d)", type);
+                       free(val);
+                       free(prefix);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               free(val);
+               free(prefix);
+               cursor = new_start;
+       }
+
+       CTS_ERR("Invalid vcard");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static inline int __ctsvc_vcard_check_version(const char *src)
+{
+       bool start = false;
+       const char *ver3 = "3.0";
+
+       while (*src) {
+               switch (*src) {
+               case '\n':
+               case '\r':
+                       return CTSVC_VCARD_VER_2_1;
+               case ' ':
+                       src++;
+                       break;
+               default:
+                       start = true;
+                       break;
+               }
+               if (start) break;
+       }
+
+       if (0 == strcmp(src, ver3))
+               return CTSVC_VCARD_VER_3_0;
+       else
+               return CTSVC_VCARD_VER_2_1;
+}
+
+static inline void __ctsvc_vcard_make_contact_display_name(ctsvc_contact_s *contact)
+{
+       ctsvc_name_s *name = NULL;
+
+       free(contact->display_name);
+       contact->display_name = NULL;
+
+       free(contact->reverse_display_name);
+       contact->reverse_display_name = NULL;
+
+       if (contact->name->count > 0 && contact->name->records != NULL && contact->name->records->data != NULL) {
+               name = (ctsvc_name_s *)contact->name->records->data;
+       }
+
+       if (name && ( name->first || name->last || name->prefix || name->addition || name->suffix)) {
+               int reverse_lang_type = -1;
+               char *display = NULL;
+               char *reverse_display = NULL;
+               int len, display_len;
+               int temp_display_len;
+               char *temp_display = NULL;
+               contacts_name_display_order_e name_display_order = CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST;
+
+               ///////////////////////////////////////////////
+               // Make reverse display name (Last name first)
+               // Default         : Prefix Last, First Middle(addition), Suffix
+               // Korean, Chinese : Prefix LastFirstMiddleSuffix
+               // Japanese        : Prefix Last Middle First Suffix
+               // reverse sort name does not include prefix
+               //    But, if there is only prefix, reverse sort_name is prefix
+               //////////////////////////////////////////////
+               temp_display_len = SAFE_STRLEN(name->first)
+                                               + SAFE_STRLEN(name->addition)
+                                               + SAFE_STRLEN(name->last)
+                                               + SAFE_STRLEN(name->suffix);
+               if (0 < temp_display_len) {
+                       temp_display_len += 7;
+                       temp_display = calloc(1, temp_display_len);
+                       RETM_IF(NULL == temp_display, "calloc() return NULL");
+                       len=0;
+
+                       if (name->last) {
+                               len += snprintf(temp_display + len, temp_display_len - len, "%s", name->last);
+
+                               if (reverse_lang_type < 0) {
+                                       reverse_lang_type = ctsvc_check_language_type(temp_display);
+                               }
+
+                               if (reverse_lang_type != CTSVC_LANG_KOREAN &&
+                                               reverse_lang_type != CTSVC_LANG_CHINESE &&
+                                               reverse_lang_type != CTSVC_LANG_JAPANESE) {
+                                       if (name->first || name->addition)
+                                               len += snprintf(temp_display + len, temp_display_len - len, ",");
+                               }
+                       }
+
+                       if (reverse_lang_type < 0) {
+                               if (*temp_display) {
+                                       reverse_lang_type = ctsvc_check_language_type(temp_display);
+                               }
+                               else if (name->first) {
+                                       reverse_lang_type = ctsvc_check_language_type(name->first);
+                               }
+                               else if (name->addition) {
+                                       reverse_lang_type = ctsvc_check_language_type(name->addition);
+                               }
+                       }
+
+                       if(reverse_lang_type == CTSVC_LANG_JAPANESE) {
+                               // make temp_display name Prefix - Last - Middle - First - Suffix
+                               if(name->addition) {
+                                       if (*temp_display)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", name->addition);
+                               }
+
+                               if(name->first) {
+                                       if (*temp_display)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", name->first);
+                               }
+                       }
+                       else {
+                               // make temp_display name Prefix - Last - First -Middle - Suffix
+                               if (name->first) {
+                                       if (*temp_display) {
+                                               if (reverse_lang_type < 0) {
+                                                       reverse_lang_type = ctsvc_check_language_type(temp_display);
+                                               }
+
+                                               if (reverse_lang_type != CTSVC_LANG_KOREAN &&
+                                                               reverse_lang_type != CTSVC_LANG_CHINESE)
+                                                       len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       }
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", name->first);
+                               }
+
+                               if (name->addition) {
+                                       if (*temp_display) {
+                                               if (reverse_lang_type < 0) {
+                                                       reverse_lang_type = ctsvc_check_language_type(temp_display);
+                                               }
+
+                                               if (reverse_lang_type != CTSVC_LANG_KOREAN &&
+                                                               reverse_lang_type != CTSVC_LANG_CHINESE)
+                                                       len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       }
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", name->addition);
+                               }
+                       }
+
+                       if (name->suffix) {
+                               if (*temp_display) {
+                                       if (reverse_lang_type < 0) {
+                                               reverse_lang_type = ctsvc_check_language_type(temp_display);
+                                       }
+
+                                       if (reverse_lang_type == CTSVC_LANG_JAPANESE)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       else if (reverse_lang_type != CTSVC_LANG_KOREAN &&
+                                                                       reverse_lang_type != CTSVC_LANG_CHINESE)
+                                               len += snprintf(temp_display + len, temp_display_len - len, ", ");
+                               }
+                               len += snprintf(temp_display + len, temp_display_len - len, "%s", name->suffix);
+                       }
+               }
+
+               if(name->prefix && temp_display) {
+                       display_len = SAFE_STRLEN(name->prefix) + temp_display_len + 2;
+                       reverse_display = calloc(1, display_len);
+                       if (NULL == reverse_display) {
+                               CTS_ERR("calloc() return NULL");
+                               free(temp_display);
+                               return;
+                       }
+                       snprintf(reverse_display, display_len, "%s %s", name->prefix, temp_display);
+                       free(temp_display);
+               }
+               else if (temp_display) {
+                       reverse_display = temp_display;
+               }
+               else if (name->prefix) {
+                       reverse_display = strdup(name->prefix);
+               }
+
+               ///////////////////////////////////////////////
+               // Make display name (First name first)
+               // Default         : Prefix First Middle Last, Suffix
+               // Korean, Chinese : Prefix LastFirstMiddleSuffix (Same as reverse display name)
+               // Japanese        : Prefix First Middle Last Suffix
+               // sort name does not include prefix
+               //    But, if there is only prefix, sort_name is prefix
+               //////////////////////////////////////////////
+
+               if (reverse_lang_type == CTSVC_LANG_KOREAN ||
+                       reverse_lang_type == CTSVC_LANG_CHINESE) {
+                       display = strdup(reverse_display);
+                       if (NULL == display) {
+                               free(reverse_display);
+                               CTS_ERR("strdup() return NULL");
+                               return;
+                       }
+               }
+               else {
+                       int lang_type = -1;
+                       temp_display = NULL;
+                       temp_display_len = SAFE_STRLEN(name->first)
+                                                               + SAFE_STRLEN(name->addition)
+                                                               + SAFE_STRLEN(name->last)
+                                                               + SAFE_STRLEN(name->suffix);
+                       if (0 < temp_display_len) {
+                               temp_display_len += 6;
+                               // make reverse_temp_display_name
+                               temp_display = calloc(1, temp_display_len);
+                               if (NULL == temp_display) {
+                                       CTS_ERR("calloc() return NULL");
+                                       free(reverse_display);
+                                       return;
+                               }
+                               len = 0;
+
+                               if (name->first) {
+                                       if (*temp_display)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", name->first);
+                               }
+
+                               if (name->addition) {
+                                       if (*temp_display)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", name->addition);
+                               }
+
+                               if (name->last) {
+                                       if (*temp_display)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", name->last);
+                               }
+
+                               if(name->suffix) {
+                                       if (*temp_display) {
+                                               lang_type = ctsvc_check_language_type(temp_display);
+                                               if (lang_type == CTSVC_LANG_JAPANESE)
+                                                       len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                               else
+                                                       len += snprintf(temp_display + len, temp_display_len - len, ", ");
+                                       }
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", name->suffix);
+                               }
+                       }
+
+                       if(name->prefix && temp_display) {
+                               display_len = SAFE_STRLEN(name->prefix) + temp_display_len + 2;
+                               display = calloc(1, display_len);
+                               if (NULL == display) {
+                                       CTS_ERR("calloc() return NULL");
+                                       free(temp_display);
+                                       free(reverse_display);
+                                       return;
+                               }
+                               snprintf(display, display_len, "%s %s", name->prefix, temp_display);
+                               free(temp_display);
+                       }
+                       else if (temp_display) {
+                               display = temp_display;
+                       }
+                       else if (name->prefix) {
+                               display = strdup(name->prefix);
+                               if (NULL == display) {
+                                       CTS_ERR("strdup() return NULL");
+                                       free(temp_display);
+                                       free(reverse_display);
+                                       return;
+                               }
+                       }
+               }
+
+               contacts_setting_get_name_display_order(&name_display_order);
+               if (CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST == name_display_order) {
+                       contact->display_name = display;
+                       free(reverse_display);
+               }
+               else {
+                       contact->display_name = reverse_display;
+                       free(display);
+               }
+
+               contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME;
+       }
+       else {
+               GList *cur;
+               bool set_display_name = false;
+               if (contact->company && contact->company->records) {
+                       for (cur=contact->company->records;cur;cur=cur->next) {
+                               ctsvc_company_s *company = (ctsvc_company_s *)cur->data;
+                               if (company && company->name) {
+                                       set_display_name = true;
+                                       contact->display_name = SAFE_STRDUP(company->name);
+                                       contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_COMPANY;
+                                       break;
+                               }
+                       }
+               }
+
+               if (!set_display_name &&
+                               contact->nicknames && contact->nicknames->records) {
+                       for (cur=contact->nicknames->records;cur;cur=cur->next) {
+                               ctsvc_nickname_s *nickname = (ctsvc_nickname_s *)cur->data;
+                               if (nickname && nickname->nickname) {
+                                       set_display_name = true;
+                                       contact->display_name = SAFE_STRDUP(nickname->nickname);
+                                       contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NICKNAME;
+                                       break;
+                               }
+                       }
+               }
+
+               if (!set_display_name &&
+                               contact->numbers && contact->numbers->records) {
+                       for (cur=contact->numbers->records;cur;cur=cur->next) {
+                               ctsvc_number_s *number = (ctsvc_number_s *)cur->data;
+                               if (number && number->number) {
+                                       set_display_name = true;
+                                       contact->display_name = SAFE_STRDUP(number->number);
+                                       contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NUMBER;
+                                       break;
+                               }
+                       }
+               }
+
+               if (!set_display_name &&
+                               contact->emails && contact->emails->records) {
+                       for (cur=contact->emails->records;cur;cur=cur->next) {
+                               ctsvc_email_s *email = (ctsvc_email_s *)cur->data;
+                               if (email && email->email_addr) {
+                                       set_display_name = true;
+                                       contact->display_name = SAFE_STRDUP(email->email_addr);
+                                       contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL;
+                                       break;
+                               }
+                       }
+               }
+       }
+       return;
+}
+
+static void __ctsvc_vcard_update_contact_has_properties(ctsvc_contact_s *contact)
+{
+       if (contact->numbers && 0 < contact->numbers->count)
+               contact->has_phonenumber = true;
+
+       if (contact->emails && 0 < contact->emails->count)
+               contact->has_email = true;
+}
+
+static int __ctsvc_vcard_parse(const void *vcard_stream, contacts_record_h *record)
+{
+       int ret, ver;
+       ctsvc_contact_s *contact;
+       char *val_begin, *new_start, *val;
+       char *vcard = (char *)vcard_stream;
+
+       RETV_IF(NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       __ctsvc_vcard_initial();
+
+       vcard = __ctsvc_vcard_check_word(vcard, "BEGIN:VCARD");
+       RETVM_IF(NULL == vcard, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : The vcard is invalid.");
+
+       val_begin = __ctsvc_vcard_check_word(vcard, "VERSION:");
+       new_start = __ctsvc_vcard_get_val(CTSVC_VCARD_VER_NONE, val_begin, NULL, &val);
+       if (NULL == new_start || NULL == val)
+               ver = CTSVC_VCARD_VER_2_1;
+       else {
+               ver = __ctsvc_vcard_check_version(val);
+               free(val);
+               vcard = new_start;
+       }
+
+       contacts_record_create(_contacts_contact._uri, (contacts_record_h *)&contact);
+       RETVM_IF(NULL == contact, CONTACTS_ERROR_OUT_OF_MEMORY, "Out of memory : contacts_record_create() Failed");
+
+       ret = __ctsvc_vcard_get_contact(ver, vcard, (contacts_record_h *)&contact);
+       if (CONTACTS_ERROR_NONE!= ret) {
+               contacts_record_destroy((contacts_record_h)contact, true);
+               if (CONTACTS_ERROR_INVALID_PARAMETER == ret) {
+                       CTS_ERR("cts_vcard_get_contact() Failed(%d)", ret);
+               }
+               else
+                       CTS_ERR("cts_vcard_get_contact() Failed(%d)", ret);
+
+               return ret;
+       }
+       __ctsvc_vcard_make_contact_display_name(contact);
+       __ctsvc_vcard_update_contact_has_properties(contact);
+       *record = (contacts_record_h)contact;
+       return CONTACTS_ERROR_NONE;
+}
+
+#define CTSVC_VCARD_MAX_SIZE 1024*1024
+
+static const char* __contacts_vcard_remove_line_break(const char *c)
+{
+       while (c) {
+               if ('\r' == *c && '\n' == *(c+1))
+                       c+=2;
+               else if ('\n' == *c)
+                       c++;
+               else
+                       break;
+       }
+       return c;
+}
+
+typedef struct {
+       const char *pos_start;
+       const char *pos_end;
+} sub_vcard_info_s;
+
+static void __contacts_vcard_free_sub_vcard_info_list(GList *list)
+{
+       if (NULL == list)
+               return;
+
+       GList *cursor;
+       for (cursor=list;cursor;cursor=cursor->next) {
+               sub_vcard_info_s *vcard_info = cursor->data;
+               free(vcard_info);
+       }
+       g_list_free(list);
+}
+
+static void __contacts_vcard_free_vcard_object_list(GList *list)
+{
+       if (NULL == list)
+               return;
+
+       GList *cursor;
+       for (cursor=list;cursor;cursor=cursor->next) {
+               char *vcard_object = cursor->data;
+               free(vcard_object);
+       }
+       g_list_free(list);
+
+}
+
+static const char* __contacts_vcard_parse_get_vcard_object(const char *cursor, GList **plist_vcard_object)
+{
+       char *vcard_object = NULL;
+       bool new_line = false;
+       const char *begin = "BEGIN:VCARD";
+       const char *end = "END:VCARD";
+       const char *vcard_start_cursor = cursor;
+       const char *vcard_cursor = NULL;
+       GList *sub_vcard_list = NULL;
+
+       RETVM_IF(NULL == plist_vcard_object, cursor, "Invalid parameter(pvcard_object) is NULL");
+       *plist_vcard_object = NULL;
+
+       vcard_start_cursor = __contacts_vcard_remove_line_break(vcard_start_cursor);
+
+       if (0 != strncmp(vcard_start_cursor, begin, strlen(begin)))
+               return vcard_start_cursor;
+
+       vcard_cursor = vcard_start_cursor;
+
+       vcard_cursor += strlen(begin);
+       vcard_cursor = __contacts_vcard_remove_line_break(vcard_cursor);
+
+       while (*vcard_cursor) {
+               if (new_line) {
+                       if (0 == strncmp(vcard_cursor, end, strlen(end))) {
+                               GList *sub_vcard_cursor = NULL;
+                               int vcard_len = 0;
+                               const char *pos_start = NULL;
+
+                               vcard_cursor += strlen(end);
+                               vcard_cursor = __contacts_vcard_remove_line_break(vcard_cursor);
+
+                               pos_start = vcard_start_cursor;
+                               for (sub_vcard_cursor=sub_vcard_list;sub_vcard_cursor;sub_vcard_cursor=sub_vcard_cursor->next) {
+                                       sub_vcard_info_s *sub_vcard_info = sub_vcard_cursor->data;
+                                       const char *pos_end = sub_vcard_info->pos_start;
+                                       vcard_len += (pos_end - pos_start);
+                                       pos_start = sub_vcard_info->pos_end;
+                               }
+                               vcard_len += (vcard_cursor - pos_start);
+                               vcard_object = calloc(vcard_len + 1, sizeof(char));
+                               if (NULL == vcard_object) {
+                                       CTS_ERR("calloc() return NULL");
+                                       break;
+                               }
+
+                               vcard_len = 0;
+                               pos_start = vcard_start_cursor;
+                               for (sub_vcard_cursor=sub_vcard_list;sub_vcard_cursor;sub_vcard_cursor=sub_vcard_cursor->next) {
+                                       sub_vcard_info_s *sub_vcard_info = sub_vcard_cursor->data;
+                                       const char *pos_end = sub_vcard_info->pos_start;
+                                       memcpy(vcard_object+vcard_len, pos_start, pos_end - pos_start);
+                                       vcard_len += (pos_end - pos_start);
+                                       pos_start = sub_vcard_info->pos_end;
+                               }
+                               __contacts_vcard_free_sub_vcard_info_list(sub_vcard_list);
+                               memcpy(vcard_object+vcard_len, pos_start, vcard_cursor - pos_start);
+                               *plist_vcard_object = g_list_append(*plist_vcard_object, vcard_object);
+
+                               return vcard_cursor;
+                       }
+                       else if (0 == strncmp(vcard_cursor, begin, strlen(begin))) { // sub vcard
+                               sub_vcard_info_s *sub_vcard_info = calloc(1, sizeof(sub_vcard_info_s));
+                               if (NULL == sub_vcard_info) {
+                                       CTS_ERR("calloc() return NULL");
+                                       break;
+                               }
+                               sub_vcard_info->pos_start = vcard_cursor;
+
+                               vcard_cursor = __contacts_vcard_parse_get_vcard_object(vcard_cursor, plist_vcard_object);
+                               sub_vcard_info->pos_end = vcard_cursor;
+
+                               sub_vcard_list = g_list_append(sub_vcard_list, sub_vcard_info);
+                               continue;
+                       }
+                       new_line = false;
+               }
+               vcard_cursor++;
+               if (('\n' == *vcard_cursor) || ('\r' == *vcard_cursor && '\n' == *(vcard_cursor+1))) {
+                       new_line = true;
+                       vcard_cursor = __contacts_vcard_remove_line_break(vcard_cursor);
+               }
+       }
+
+       __contacts_vcard_free_sub_vcard_info_list(sub_vcard_list);
+
+       return vcard_cursor;
+}
+
+API int contacts_vcard_parse_to_contacts(const char *vcard_stream, contacts_list_h *out_contacts)
+{
+       int ret;
+       contacts_record_h record;
+       contacts_list_h list = NULL;
+       const char *cursor = NULL;
+       char *vcard_object = NULL;
+       GList *list_vcard_object = NULL;
+
+       RETV_IF(NULL == out_contacts, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_contacts = NULL;
+
+       RETV_IF(NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       cursor = vcard_stream;
+       while ((cursor = __contacts_vcard_parse_get_vcard_object(cursor, &list_vcard_object))) {
+               GList *vcard_cursor = NULL;
+               if (NULL == list_vcard_object)
+                       break;
+
+               for (vcard_cursor=list_vcard_object;vcard_cursor;vcard_cursor=vcard_cursor->next) {
+                       vcard_object = vcard_cursor->data;
+                       if (NULL == vcard_object)
+                               continue;
+
+                       ret = __ctsvc_vcard_parse(vcard_object, &record);
+                       if (ret < CONTACTS_ERROR_NONE) {
+                               CTS_ERR("Invalid parameter : vcard stream parsing error");
+                               __contacts_vcard_free_vcard_object_list(list_vcard_object);
+                               contacts_list_destroy(list, true);
+                               return ret;
+                       }
+
+                       if (NULL == list)
+                               contacts_list_create(&list);
+                       contacts_list_add(list, record);
+                       vcard_object = NULL;
+               }
+               __contacts_vcard_free_vcard_object_list(list_vcard_object);
+       }
+       *out_contacts = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_vcard_parse_to_contact_foreach(const char *vcard_file_name,
+               contacts_vcard_parse_cb cb, void *data)
+{
+       contacts_record_h record;
+       FILE *file;
+       int buf_size, len;
+       int ret;
+       int vcard_depth = 0;
+       char *stream;
+       char line[1024] = {0};
+
+       RETV_IF(NULL == vcard_file_name, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == cb, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       file = fopen(vcard_file_name, "r");
+       RETVM_IF(NULL == file, CONTACTS_ERROR_SYSTEM, "System : fopen() Failed(%d)", errno);
+
+       len = 0;
+       buf_size = CTSVC_VCARD_MAX_SIZE;
+       stream = malloc(CTSVC_VCARD_MAX_SIZE);
+       if (NULL == stream) {
+               CTS_ERR("Out of memory : malloc() Failed");
+               fclose(file);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       while (fgets(line, sizeof(line), file)) {
+               if (0 == len)
+                       if (strncmp(line, "BEGIN:VCARD", strlen("BEGIN:VCARD")))
+                               continue;
+
+               if (len + sizeof(line) < buf_size)
+                       len += snprintf(stream + len, buf_size - len, "%s", line);
+               else {
+                       char *new_stream;
+                       buf_size += sizeof(line) * 2;
+                       new_stream = realloc(stream, buf_size);
+                       if (new_stream)
+                               stream = new_stream;
+                       else {
+                               free(stream);
+                               fclose(file);
+                               return CONTACTS_ERROR_OUT_OF_MEMORY;
+                       }
+
+                       len += snprintf(stream + len, buf_size - len, "%s", line);
+               }
+
+               if (0 == strncmp(line, "END:VCARD", 9)) {
+                       vcard_depth--;
+
+                       if (0 == vcard_depth) {
+                               const char *cursor = stream;
+                               GList *list_vcard_object = NULL;
+
+                               len = 0;
+
+                               while ((cursor = __contacts_vcard_parse_get_vcard_object(cursor, &list_vcard_object))) {
+                                       GList *vcard_cursor = NULL;
+                                       if (NULL == list_vcard_object)
+                                               break;
+
+                                       for (vcard_cursor=list_vcard_object;vcard_cursor;vcard_cursor=vcard_cursor->next) {
+                                               char *vcard_object = vcard_cursor->data;
+
+                                               if (NULL == vcard_object)
+                                                       continue;
+
+                                               ret = __ctsvc_vcard_parse(vcard_object, &record);
+                                               if (ret < CONTACTS_ERROR_NONE) {
+                                                       CTS_ERR("Invalid parameter : vcard stream parsing error");
+                                                       free(stream);
+                                                       fclose(file);
+                                                       __contacts_vcard_free_vcard_object_list(list_vcard_object);
+                                                       return ret;
+                                               }
+
+                                               if (!cb(record, data)) {
+                                                       free(stream);
+                                                       fclose(file);
+                                                       __contacts_vcard_free_vcard_object_list(list_vcard_object);
+                                                       contacts_record_destroy(record, true);
+                                                       return CONTACTS_ERROR_NONE;
+                                               }
+                                               contacts_record_destroy(record, true);
+                                       }
+                                       __contacts_vcard_free_vcard_object_list(list_vcard_object);
+                                       list_vcard_object = NULL;
+                               }
+                       }
+               }
+               else if (0 == strncmp(line, "BEGIN:VCARD", 11)) { // sub vcard object
+                       vcard_depth++;
+               }
+       }
+
+       free(stream);
+       fclose(file);
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_vcard_get_entity_count(const char *vcard_file_name, int *count)
+{
+       FILE *file;
+       int cnt;
+       char line[1024] = {0};
+       RETV_IF(NULL == count, CONTACTS_ERROR_INVALID_PARAMETER);
+       *count = 0;
+
+       RETV_IF(NULL == vcard_file_name, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       file = fopen(vcard_file_name, "r");
+       RETVM_IF(NULL == file, CONTACTS_ERROR_SYSTEM, "System : fopen() Failed(%d)", errno);
+
+       cnt = 0;
+       while (fgets(line, sizeof(line), file)) {
+               if (0 == strncmp(line, "END:VCARD", 9))
+                       cnt++;
+       }
+       fclose(file);
+
+       *count = cnt;
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/common/ctsvc_vcard.h b/common/ctsvc_vcard.h
new file mode 100644 (file)
index 0000000..d06e400
--- /dev/null
@@ -0,0 +1,27 @@
+/*\r
+ * Contacts Service\r
+ *\r
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: Dohyung Jin <dh.jin@samsung.com>\r
+ *                 Jongwon Lee <gogosing.lee@samsung.com>\r
+ *                 Donghee Ye <donghee.ye@samsung.com>\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
+\r
+#ifndef __TIZEN_SOCIAL_CTSVC_VCARD_H__\r
+#define __TIZEN_SOCIAL_CTSVC_VCARD_H__\r
+\r
+#endif /*  __TIZEN_SOCIAL_CTSVC_VCARD_H__ */\r
diff --git a/common/ctsvc_view.c b/common/ctsvc_view.c
new file mode 100644 (file)
index 0000000..632b0f9
--- /dev/null
@@ -0,0 +1,1417 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 "contacts.h"
+
+#include "ctsvc_internal.h"
+#include "ctsvc_view.h"
+
+API const _contacts_address_book_property_ids _contacts_address_book = {
+       ._uri           = CTSVC_VIEW_URI_ADDRESSBOOK,
+       .id                     = CTSVC_PROPERTY_ADDRESSBOOK_ID,
+       .account_id     = CTSVC_PROPERTY_ADDRESSBOOK_ACCOUNT_ID,
+       .name           = CTSVC_PROPERTY_ADDRESSBOOK_NAME,
+       .mode           = CTSVC_PROPERTY_ADDRESSBOOK_MODE
+};
+
+API const _contacts_group_property_ids _contacts_group = {
+       ._uri                   = CTSVC_VIEW_URI_GROUP,
+       .id                             = CTSVC_PROPERTY_GROUP_ID,
+       .address_book_id        = CTSVC_PROPERTY_GROUP_ADDRESSBOOK_ID,
+       .name                   = CTSVC_PROPERTY_GROUP_NAME,
+       .ringtone_path  = CTSVC_PROPERTY_GROUP_RINGTONE,
+       .image_path             = CTSVC_PROPERTY_GROUP_IMAGE,
+       .vibration              = CTSVC_PROPERTY_GROUP_VIBRATION,
+       .extra_data             = CTSVC_PROPERTY_GROUP_EXTRA_DATA,
+       .is_read_only   = CTSVC_PROPERTY_GROUP_IS_READ_ONLY,
+       .message_alert = CTSVC_PROPERTY_GROUP_MESSAGE_ALERT
+};
+
+API const _contacts_person_property_ids _contacts_person = {
+       ._uri                                   = CTSVC_VIEW_URI_PERSON,
+       .id                                             = CTSVC_PROPERTY_PERSON_ID,
+       .display_name                   = CTSVC_PROPERTY_PERSON_DISPLAY_NAME,
+       .display_name_index             = CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX,
+       .display_contact_id             = CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID,
+       .ringtone_path                  = CTSVC_PROPERTY_PERSON_RINGTONE,
+       .image_thumbnail_path   = CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,
+       .vibration                              = CTSVC_PROPERTY_PERSON_VIBRATION,
+       .message_alert          = CTSVC_PROPERTY_PERSON_MESSAGE_ALERT,
+       .status                                 = CTSVC_PROPERTY_PERSON_STATUS,
+       .is_favorite                    = CTSVC_PROPERTY_PERSON_IS_FAVORITE,
+       .favorite_priority              = CTSVC_PROPERTY_PERSON_FAVORITE_PRIORITY,
+       .link_count                             = CTSVC_PROPERTY_PERSON_LINK_COUNT,
+       .addressbook_ids                = CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS,
+       .has_phonenumber                = CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER,
+       .has_email                              = CTSVC_PROPERTY_PERSON_HAS_EMAIL,
+};
+
+API const _contacts_contact_property_ids _contacts_contact = {
+       ._uri                                   = CTSVC_VIEW_URI_CONTACT,
+       .id                                             = CTSVC_PROPERTY_CONTACT_ID,
+       .display_name                   = CTSVC_PROPERTY_CONTACT_DISPLAY_NAME,
+       .display_source_type    = CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID,
+       .address_book_id                = CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,
+       .ringtone_path                  = CTSVC_PROPERTY_CONTACT_RINGTONE,
+       .image_thumbnail_path   = CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL,
+       .is_favorite                    = CTSVC_PROPERTY_CONTACT_IS_FAVORITE,
+       .has_phonenumber                = CTSVC_PROPERTY_CONTACT_HAS_PHONENUMBER,
+       .has_email                              = CTSVC_PROPERTY_CONTACT_HAS_EMAIL,
+       .person_id                              = CTSVC_PROPERTY_CONTACT_PERSON_ID,
+       .uid                                    = CTSVC_PROPERTY_CONTACT_UID,
+       .vibration                              = CTSVC_PROPERTY_CONTACT_VIBRATION,
+       .message_alert          = CTSVC_PROPERTY_CONTACT_MESSAGE_ALERT,
+       .changed_time                   = CTSVC_PROPERTY_CONTACT_CHANGED_TIME,
+       .link_mode              = CTSVC_PROPERTY_CONTACT_LINK_MODE,
+       .name                                   = CTSVC_PROPERTY_CONTACT_NAME,
+       .company                                = CTSVC_PROPERTY_CONTACT_COMPANY,
+       .note                                   = CTSVC_PROPERTY_CONTACT_NOTE,
+       .number                                 = CTSVC_PROPERTY_CONTACT_NUMBER,
+       .email                                  = CTSVC_PROPERTY_CONTACT_EMAIL,
+       .event                                  = CTSVC_PROPERTY_CONTACT_EVENT,
+       .messenger                              = CTSVC_PROPERTY_CONTACT_MESSENGER,
+       .address                                = CTSVC_PROPERTY_CONTACT_ADDRESS,
+       .url                                    = CTSVC_PROPERTY_CONTACT_URL,
+       .nickname                               = CTSVC_PROPERTY_CONTACT_NICKNAME,
+       .profile                                = CTSVC_PROPERTY_CONTACT_PROFILE,
+       .relationship                   = CTSVC_PROPERTY_CONTACT_RELATIONSHIP,
+       .image                                  = CTSVC_PROPERTY_CONTACT_IMAGE,
+       .group_relation                 = CTSVC_PROPERTY_CONTACT_GROUP_RELATION,
+       .extension                              = CTSVC_PROPERTY_CONTACT_EXTENSION,
+};
+
+API const _contacts_my_profile_property_ids _contacts_my_profile = {
+       ._uri                                   = CTSVC_VIEW_URI_MY_PROFILE,
+       .id                                             = CTSVC_PROPERTY_MY_PROFILE_ID,
+       .display_name                   = CTSVC_PROPERTY_MY_PROFILE_DISPLAY_NAME,
+       .address_book_id                = CTSVC_PROPERTY_MY_PROFILE_ADDRESSBOOK_ID,
+       .image_thumbnail_path   = CTSVC_PROPERTY_MY_PROFILE_IMAGE_THUMBNAIL,
+       .uid                                    = CTSVC_PROPERTY_MY_PROFILE_UID,
+       .changed_time                   = CTSVC_PROPERTY_MY_PROFILE_CHANGED_TIME,
+       .name                                   = CTSVC_PROPERTY_MY_PROFILE_NAME,
+       .company                                = CTSVC_PROPERTY_MY_PROFILE_COMPANY,
+       .note                                   = CTSVC_PROPERTY_MY_PROFILE_NOTE,
+       .number                                 = CTSVC_PROPERTY_MY_PROFILE_NUMBER,
+       .email                                  = CTSVC_PROPERTY_MY_PROFILE_EMAIL,
+       .event                                  = CTSVC_PROPERTY_MY_PROFILE_EVENT,
+       .messenger                              = CTSVC_PROPERTY_MY_PROFILE_MESSENGER,
+       .address                                = CTSVC_PROPERTY_MY_PROFILE_ADDRESS,
+       .url                                    = CTSVC_PROPERTY_MY_PROFILE_URL,
+       .nickname                               = CTSVC_PROPERTY_MY_PROFILE_NICKNAME,
+       .profile                                = CTSVC_PROPERTY_MY_PROFILE_PROFILE,
+       .relationship                   = CTSVC_PROPERTY_MY_PROFILE_RELATIONSHIP,
+       .image                                  = CTSVC_PROPERTY_MY_PROFILE_IMAGE,
+       .extension                              = CTSVC_PROPERTY_MY_PROFILE_EXTENSION,
+};
+
+API const _contacts_simple_contact_property_ids _contacts_simple_contact = {
+       ._uri                                   = CTSVC_VIEW_URI_SIMPLE_CONTACT,
+       .id                                             = CTSVC_PROPERTY_CONTACT_ID,
+       .display_name                   = CTSVC_PROPERTY_CONTACT_DISPLAY_NAME,
+       .display_source_type    = CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID,
+       .address_book_id                = CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,
+       .person_id                              = CTSVC_PROPERTY_CONTACT_PERSON_ID,
+       .ringtone_path                  = CTSVC_PROPERTY_CONTACT_RINGTONE,
+       .image_thumbnail_path   = CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL,
+       .is_favorite                    = CTSVC_PROPERTY_CONTACT_IS_FAVORITE,
+       .has_phonenumber                = CTSVC_PROPERTY_CONTACT_HAS_PHONENUMBER,
+       .has_email                              = CTSVC_PROPERTY_CONTACT_HAS_EMAIL,
+       .uid                                    = CTSVC_PROPERTY_CONTACT_UID,
+       .vibration                              = CTSVC_PROPERTY_CONTACT_VIBRATION,
+       .message_alert          = CTSVC_PROPERTY_CONTACT_MESSAGE_ALERT,
+       .changed_time                   = CTSVC_PROPERTY_CONTACT_CHANGED_TIME,
+};
+
+API const _contacts_name_property_ids _contacts_name = {
+       ._uri                   = CTSVC_VIEW_URI_NAME,
+       .id                             = CTSVC_PROPERTY_NAME_ID,
+       .contact_id             = CTSVC_PROPERTY_NAME_CONTACT_ID,
+       .first                  = CTSVC_PROPERTY_NAME_FIRST,
+       .last                   = CTSVC_PROPERTY_NAME_LAST,
+       .addition               = CTSVC_PROPERTY_NAME_ADDITION,
+       .suffix                 = CTSVC_PROPERTY_NAME_SUFFIX,
+       .prefix                 = CTSVC_PROPERTY_NAME_PREFIX,
+       .phonetic_first = CTSVC_PROPERTY_NAME_PHONETIC_FIRST,
+       .phonetic_middle= CTSVC_PROPERTY_NAME_PHONETIC_MIDDLE,
+       .phonetic_last  = CTSVC_PROPERTY_NAME_PHONETIC_LAST
+};
+
+API const _contacts_number_property_ids _contacts_number = {
+       ._uri           = CTSVC_VIEW_URI_NUMBER,
+       .id                     = CTSVC_PROPERTY_NUMBER_ID,
+       .contact_id     = CTSVC_PROPERTY_NUMBER_CONTACT_ID,
+       .type           = CTSVC_PROPERTY_NUMBER_TYPE,
+       .label          = CTSVC_PROPERTY_NUMBER_LABEL,
+       .is_default     = CTSVC_PROPERTY_NUMBER_IS_DEFAULT,
+       .number         = CTSVC_PROPERTY_NUMBER_NUMBER,
+       .normalized_number = CTSVC_PROPERTY_NUMBER_NORMALIZED_NUMBER,
+       .cleaned_number = CTSVC_PROPERTY_NUMBER_CLEANED_NUMBER,
+       .number_filter = CTSVC_PROPERTY_NUMBER_NUMBER_FILTER
+};
+
+API const _contacts_email_property_ids _contacts_email = {
+       ._uri           = CTSVC_VIEW_URI_EMAIL,
+       .id                     = CTSVC_PROPERTY_EMAIL_ID,
+       .contact_id     = CTSVC_PROPERTY_EMAIL_CONTACT_ID,
+       .type           = CTSVC_PROPERTY_EMAIL_TYPE,
+       .label          = CTSVC_PROPERTY_EMAIL_LABEL,
+       .is_default     = CTSVC_PROPERTY_EMAIL_IS_DEFAULT,
+       .email          = CTSVC_PROPERTY_EMAIL_EMAIL
+};
+
+API const _contacts_address_property_ids _contacts_address = {
+       ._uri                   = CTSVC_VIEW_URI_ADDRESS,
+       .id                             = CTSVC_PROPERTY_ADDRESS_ID,
+       .contact_id             = CTSVC_PROPERTY_ADDRESS_CONTACT_ID,
+       .type                   = CTSVC_PROPERTY_ADDRESS_TYPE,
+       .label                  = CTSVC_PROPERTY_ADDRESS_LABEL,
+       .postbox                = CTSVC_PROPERTY_ADDRESS_POSTBOX,
+       .postal_code    = CTSVC_PROPERTY_ADDRESS_POSTAL_CODE,
+       .region                 = CTSVC_PROPERTY_ADDRESS_REGION,
+       .locality               = CTSVC_PROPERTY_ADDRESS_LOCALITY,
+       .street                 = CTSVC_PROPERTY_ADDRESS_STREET,
+       .country                = CTSVC_PROPERTY_ADDRESS_COUNTRY,
+       .extended               = CTSVC_PROPERTY_ADDRESS_EXTENDED,
+       .is_default             = CTSVC_PROPERTY_ADDRESS_IS_DEFAULT
+};
+
+API const _contacts_url_property_ids _contacts_url = {
+       ._uri           = CTSVC_VIEW_URI_URL,
+       .id                     = CTSVC_PROPERTY_URL_ID,
+       .contact_id     = CTSVC_PROPERTY_URL_CONTACT_ID,
+       .type           = CTSVC_PROPERTY_URL_TYPE,
+       .label          = CTSVC_PROPERTY_URL_LABEL,
+       .url            = CTSVC_PROPERTY_URL_URL
+};
+
+API const _contacts_event_property_ids _contacts_event = {
+       ._uri           = CTSVC_VIEW_URI_EVENT,
+       .id                     = CTSVC_PROPERTY_EVENT_ID,
+       .contact_id     = CTSVC_PROPERTY_EVENT_CONTACT_ID,
+       .type           = CTSVC_PROPERTY_EVENT_TYPE,
+       .label          = CTSVC_PROPERTY_EVENT_LABEL,
+       .date           = CTSVC_PROPERTY_EVENT_DATE,
+       .is_leap_month = CTSVC_PROPERTY_EVENT_IS_LEAP_MONTH,
+       .calendar_type = CTSVC_PROPERTY_EVENT_CALENDAR_TYPE,
+};
+
+API const _contacts_company_property_ids _contacts_company = {
+       ._uri                   = CTSVC_VIEW_URI_COMPANY,
+       .id                             = CTSVC_PROPERTY_COMPANY_ID,
+       .contact_id             = CTSVC_PROPERTY_COMPANY_CONTACT_ID,
+       .type                   = CTSVC_PROPERTY_COMPANY_TYPE,
+       .label                  = CTSVC_PROPERTY_COMPANY_LABEL,
+       .name                   = CTSVC_PROPERTY_COMPANY_NAME,
+       .department             = CTSVC_PROPERTY_COMPANY_DEPARTMENT,
+       .job_title              = CTSVC_PROPERTY_COMPANY_JOB_TITLE,
+       .assistant_name = CTSVC_PROPERTY_COMPANY_ASSISTANT_NAME,
+       .role                   = CTSVC_PROPERTY_COMPANY_ROLE,
+       .logo                   = CTSVC_PROPERTY_COMPANY_LOGO,
+       .location               = CTSVC_PROPERTY_COMPANY_LOCATION,
+       .description    = CTSVC_PROPERTY_COMPANY_DESCRIPTION,
+       .phonetic_name  = CTSVC_PROPERTY_COMPANY_PHONETIC_NAME,
+};
+
+API const _contacts_nickname_property_ids _contacts_nickname = {
+       ._uri           = CTSVC_VIEW_URI_NICKNAME,
+       .id                     = CTSVC_PROPERTY_NICKNAME_ID,
+       .contact_id     = CTSVC_PROPERTY_NICKNAME_CONTACT_ID,
+       .name           = CTSVC_PROPERTY_NICKNAME_NAME,
+};
+
+API const _contacts_note_property_ids _contacts_note = {
+       ._uri           = CTSVC_VIEW_URI_NOTE,
+       .id                     = CTSVC_PROPERTY_NOTE_ID,
+       .contact_id     = CTSVC_PROPERTY_NOTE_CONTACT_ID,
+       .note           = CTSVC_PROPERTY_NOTE_NOTE
+};
+
+API const _contacts_profile_property_ids _contacts_profile = {
+       ._uri                   = CTSVC_VIEW_URI_PROFILE,
+       .id                     = CTSVC_PROPERTY_PROFILE_ID,
+       .uid                    = CTSVC_PROPERTY_PROFILE_UID,
+       .text                   = CTSVC_PROPERTY_PROFILE_TEXT,
+       .order          = CTSVC_PROPERTY_PROFILE_ORDER,
+       .service_operation      = CTSVC_PROPERTY_PROFILE_SERVICE_OPERATION,
+       .mime           = CTSVC_PROPERTY_PROFILE_MIME,
+       .app_id         = CTSVC_PROPERTY_PROFILE_APP_ID,
+       .uri                    = CTSVC_PROPERTY_PROFILE_URI,
+       .category               = CTSVC_PROPERTY_PROFILE_CATEGORY,
+       .extra_data     = CTSVC_PROPERTY_PROFILE_EXTRA_DATA,
+       .contact_id     = CTSVC_PROPERTY_PROFILE_CONTACT_ID
+};
+
+API const _contacts_group_relation_property_ids _contacts_group_relation = {
+       ._uri           = CTSVC_VIEW_URI_GROUP_RELATION,
+       .id                     = CTSVC_PROPERTY_GROUP_RELATION_ID,
+       .group_id       = CTSVC_PROPERTY_GROUP_RELATION_GROUP_ID,
+       .contact_id     = CTSVC_PROPERTY_GROUP_RELATION_CONTACT_ID,
+       .name           = CTSVC_PROPERTY_GROUP_RELATION_GROUP_NAME,
+};
+
+API const _contacts_relationship_property_ids _contacts_relationship = {
+       ._uri           = CTSVC_VIEW_URI_RELATIONSHIP,
+       .id                     = CTSVC_PROPERTY_RELATIONSHIP_ID,
+       .contact_id     = CTSVC_PROPERTY_RELATIONSHIP_CONTACT_ID,
+       .type           = CTSVC_PROPERTY_RELATIONSHIP_TYPE,
+       .label          = CTSVC_PROPERTY_RELATIONSHIP_LABEL,
+       .name           = CTSVC_PROPERTY_RELATIONSHIP_NAME,
+};
+
+API const _contacts_image_property_ids _contacts_image = {
+       ._uri           = CTSVC_VIEW_URI_IMAGE,
+       .id                     = CTSVC_PROPERTY_IMAGE_ID,
+       .contact_id     = CTSVC_PROPERTY_IMAGE_CONTACT_ID,
+       .type           = CTSVC_PROPERTY_IMAGE_TYPE,
+       .label          = CTSVC_PROPERTY_IMAGE_LABEL,
+       .path           = CTSVC_PROPERTY_IMAGE_PATH,
+       .is_default = CTSVC_PROPERTY_IMAGE_IS_DEFAULT,
+};
+
+API const _contacts_messenger_property_ids _contacts_messenger = {
+       ._uri           = CTSVC_VIEW_URI_MESSENGER,
+       .id                     = CTSVC_PROPERTY_MESSENGER_ID,
+       .contact_id     = CTSVC_PROPERTY_MESSENGER_CONTACT_ID,
+       .type           = CTSVC_PROPERTY_MESSENGER_TYPE,
+       .label          = CTSVC_PROPERTY_MESSENGER_LABEL,
+       .im_id          = CTSVC_PROPERTY_MESSENGER_IM_ID,
+};
+
+#ifdef ENABLE_SIM_FEATURE
+API const _contacts_sdn_property_ids _contacts_sdn = {
+       ._uri   = CTSVC_VIEW_URI_SDN,
+       .id             = CTSVC_PROPERTY_SDN_ID,
+       .name   = CTSVC_PROPERTY_SDN_NAME,
+       .number = CTSVC_PROPERTY_SDN_NUMBER,
+       .sim_slot_no    = CTSVC_PROPERTY_SDN_SIM_SLOT_NO,
+};
+
+API const _contacts_speeddial_property_ids _contacts_speeddial = {
+       ._uri                                   = CTSVC_VIEW_URI_SPEEDDIAL,
+       .speeddial_number               = CTSVC_PROPERTY_SPEEDDIAL_DIAL_NUMBER,
+       .number_id                              = CTSVC_PROPERTY_SPEEDDIAL_NUMBER_ID,
+       .number                                 = CTSVC_PROPERTY_SPEEDDIAL_NUMBER,
+       .number_label                   = CTSVC_PROPERTY_SPEEDDIAL_NUMBER_LABEL,
+       .number_type                    = CTSVC_PROPERTY_SPEEDDIAL_NUMBER_TYPE,
+       .person_id                              = CTSVC_PROPERTY_SPEEDDIAL_PERSON_ID,
+       .display_name                   = CTSVC_PROPERTY_SPEEDDIAL_DISPLAY_NAME,
+       .image_thumbnail_path   = CTSVC_PROPERTY_SPEEDDIAL_IMAGE_THUMBNAIL,
+       .normalized_number      = CTSVC_PROPERTY_SPEEDDIAL_NORMALIZED_NUMBER,
+       .cleaned_number         = CTSVC_PROPERTY_SPEEDDIAL_CLEANED_NUMBER,
+       .number_filter          = CTSVC_PROPERTY_SPEEDDIAL_NUMBER_FILTER,
+};
+#endif // ENABLE_SIM_FEATURE
+
+API const _contacts_contact_updated_info_property_ids _contacts_contact_updated_info = {
+       ._uri                   = CTSVC_VIEW_URI_CONTACTS_UPDATED_INFO,
+       .contact_id             = CTSVC_PROPERTY_UPDATE_INFO_ID,
+       .address_book_id        = CTSVC_PROPERTY_UPDATE_INFO_ADDRESSBOOK_ID,
+       .type                   = CTSVC_PROPERTY_UPDATE_INFO_TYPE,
+       .version                = CTSVC_PROPERTY_UPDATE_INFO_VERSION,
+       .image_changed  = CTSVC_PROPERTY_UPDATE_INFO_IMAGE_CHANGED,
+};
+
+API const _contacts_my_profile_updated_info_property_ids _contacts_my_profile_updated_info = {
+       ._uri                   = CTSVC_VIEW_URI_MY_PROFILE_UPDATED_INFO,
+       .address_book_id        = CTSVC_PROPERTY_UPDATE_INFO_ADDRESSBOOK_ID,
+       .last_changed_type      = CTSVC_PROPERTY_UPDATE_INFO_LAST_CHANGED_TYPE,
+       .version                = CTSVC_PROPERTY_UPDATE_INFO_VERSION,
+};
+
+API const _contacts_group_updated_info_property_ids _contacts_group_updated_info = {
+       ._uri                   = CTSVC_VIEW_URI_GROUPS_UPDATED_INFO,
+       .group_id               = CTSVC_PROPERTY_UPDATE_INFO_ID,
+       .address_book_id        = CTSVC_PROPERTY_UPDATE_INFO_ADDRESSBOOK_ID,
+       .type                   = CTSVC_PROPERTY_UPDATE_INFO_TYPE,
+       .version                = CTSVC_PROPERTY_UPDATE_INFO_VERSION,
+};
+
+API const _contacts_group_member_updated_info_property_ids _contacts_group_member_updated_info = {
+       ._uri                   = CTSVC_VIEW_URI_GROUPS_MEMBER_UPDATED_INFO,
+       .group_id               = CTSVC_PROPERTY_UPDATE_INFO_ID,
+       .address_book_id        = CTSVC_PROPERTY_UPDATE_INFO_ADDRESSBOOK_ID,
+       .version                = CTSVC_PROPERTY_UPDATE_INFO_VERSION,
+};
+
+API const _contacts_grouprel_updated_info_property_ids _contacts_grouprel_updated_info = {
+       ._uri                   = CTSVC_VIEW_URI_GROUPRELS_UPDATED_INFO,
+       .group_id               = CTSVC_PROPERTY_GROUP_ID,
+       .contact_id             = CTSVC_PROPERTY_CONTACT_ID,
+       .address_book_id        = CTSVC_PROPERTY_ADDRESSBOOK_ID,
+       .type                   = CTSVC_PROPERTY_UPDATE_INFO_TYPE,
+       .version                = CTSVC_PROPERTY_UPDATE_INFO_VERSION,
+};
+
+API const _contacts_activity_property_ids _contacts_activity = {
+       ._uri                   = CTSVC_VIEW_URI_ACTIVITY,
+       .id                             = CTSVC_PROPERTY_ACTIVITY_ID,
+       .contact_id             = CTSVC_PROPERTY_ACTIVITY_CONTACT_ID,
+       .source_name    = CTSVC_PROPERTY_ACTIVITY_SOURCE_NAME,
+       .status                 = CTSVC_PROPERTY_ACTIVITY_STATUS,
+       .timestamp              = CTSVC_PROPERTY_ACTIVITY_TIMESTAMP,
+       .service_operation      = CTSVC_PROPERTY_ACTIVITY_SERVICE_OPERATION,
+       .uri                            = CTSVC_PROPERTY_ACTIVITY_URI,
+       .photo                  = CTSVC_PROPERTY_ACTIVITY_ACTIVITY_PHOTO,
+};
+
+API const _contacts_activity_photo_property_ids _contacts_activity_photo = {
+       ._uri                   = CTSVC_VIEW_URI_ACTIVITY_PHOTO,
+       .id                             = CTSVC_PROPERTY_ACTIVITY_PHOTO_ID,
+       .activity_id    = CTSVC_PROPERTY_ACTIVITY_PHOTO_ACTIVITY_ID,
+       .photo_url              = CTSVC_PROPERTY_ACTIVITY_PHOTO_URL,
+       .sort_index             = CTSVC_PROPERTY_ACTIVITY_PHOTO_SORT_INDEX,
+};
+
+#ifdef ENABLE_LOG_FEATURE
+API const _contacts_phone_log_property_ids _contacts_phone_log = {
+       ._uri                   = CTSVC_VIEW_URI_PHONELOG,
+       .id                             = CTSVC_PROPERTY_PHONELOG_ID,
+       .person_id              = CTSVC_PROPERTY_PHONELOG_PERSON_ID,
+       .address                = CTSVC_PROPERTY_PHONELOG_ADDRESS,
+       .log_time               = CTSVC_PROPERTY_PHONELOG_LOG_TIME,
+       .log_type               = CTSVC_PROPERTY_PHONELOG_LOG_TYPE,
+       .extra_data1    = CTSVC_PROPERTY_PHONELOG_EXTRA_DATA1,
+       .extra_data2    = CTSVC_PROPERTY_PHONELOG_EXTRA_DATA2,
+       .normalized_address = CTSVC_PROPERTY_PHONELOG_NORMALIZED_ADDRESS,
+       .cleaned_address = CTSVC_PROPERTY_PHONELOG_CLEANED_ADDRESS,
+       .address_filter = CTSVC_PROPERTY_PHONELOG_ADDRESS_FILTER,
+       .sim_slot_no            = CTSVC_PROPERTY_PHONELOG_SIM_SLOT_NO,
+};
+#endif // ENABLE_LOG_FEATURE
+
+API const _contacts_extension_property_ids _contacts_extension = {
+       ._uri           = CTSVC_VIEW_URI_EXTENSION,
+       .id                     = CTSVC_PROPERTY_EXTENSION_ID,
+       .contact_id     = CTSVC_PROPERTY_EXTENSION_CONTACT_ID,
+       .data1          = CTSVC_PROPERTY_EXTENSION_DATA1,
+       .data2          = CTSVC_PROPERTY_EXTENSION_DATA2,
+       .data3          = CTSVC_PROPERTY_EXTENSION_DATA3,
+       .data4          = CTSVC_PROPERTY_EXTENSION_DATA4,
+       .data5          = CTSVC_PROPERTY_EXTENSION_DATA5,
+       .data6          = CTSVC_PROPERTY_EXTENSION_DATA6,
+       .data7          = CTSVC_PROPERTY_EXTENSION_DATA7,
+       .data8          = CTSVC_PROPERTY_EXTENSION_DATA8,
+       .data9          = CTSVC_PROPERTY_EXTENSION_DATA9,
+       .data10         = CTSVC_PROPERTY_EXTENSION_DATA10,
+       .data11         = CTSVC_PROPERTY_EXTENSION_DATA11,
+       .data12         = CTSVC_PROPERTY_EXTENSION_DATA12,
+};
+
+API const _contacts_person_contact_property_ids _contacts_person_contact = {
+       ._uri                                   = CTSVC_VIEW_URI_READ_ONLY_PERSON_CONTACT,
+       .person_id                              = CTSVC_PROPERTY_PERSON_ID,
+       .display_name                   = CTSVC_PROPERTY_PERSON_DISPLAY_NAME,
+       .display_name_index             = CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX,
+       .display_contact_id             = CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID,
+       .ringtone_path                  = CTSVC_PROPERTY_PERSON_RINGTONE,
+       .image_thumbnail_path   = CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,
+       .vibration                              = CTSVC_PROPERTY_PERSON_VIBRATION,
+       .message_alert          = CTSVC_PROPERTY_PERSON_MESSAGE_ALERT,
+       .status                                 = CTSVC_PROPERTY_PERSON_STATUS,
+       .is_favorite                    = CTSVC_PROPERTY_PERSON_IS_FAVORITE,
+       .link_count                             = CTSVC_PROPERTY_PERSON_LINK_COUNT,
+       .addressbook_ids                = CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS,
+       .has_phonenumber                = CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER,
+       .has_email                              = CTSVC_PROPERTY_PERSON_HAS_EMAIL,
+       .contact_id                             = CTSVC_PROPERTY_CONTACT_ID,
+       .address_book_id                = CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,
+       .address_book_name              = CTSVC_PROPERTY_ADDRESSBOOK_NAME,
+       .address_book_mode              = CTSVC_PROPERTY_ADDRESSBOOK_MODE
+};
+
+API const _contacts_person_number_property_ids _contacts_person_number = {
+       ._uri                                   = CTSVC_VIEW_URI_READ_ONLY_PERSON_NUMBER,
+       .person_id                              = CTSVC_PROPERTY_PERSON_ID,
+       .display_name                   = CTSVC_PROPERTY_PERSON_DISPLAY_NAME,
+       .display_name_index             = CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX,
+       .display_contact_id             = CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID,
+       .ringtone_path                  = CTSVC_PROPERTY_PERSON_RINGTONE,
+       .image_thumbnail_path   = CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,
+       .vibration                              = CTSVC_PROPERTY_PERSON_VIBRATION,
+       .message_alert          = CTSVC_PROPERTY_PERSON_MESSAGE_ALERT,
+       .is_favorite                    = CTSVC_PROPERTY_PERSON_IS_FAVORITE,
+       .has_phonenumber                = CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER,
+       .has_email                              = CTSVC_PROPERTY_PERSON_HAS_EMAIL,
+       .number_id                      = CTSVC_PROPERTY_NUMBER_ID,
+       .type                           = CTSVC_PROPERTY_NUMBER_TYPE,
+       .label                          = CTSVC_PROPERTY_NUMBER_LABEL,
+       .is_primary_default     = CTSVC_PROPERTY_DATA_IS_PRIMARY_DEFAULT,
+       .number                         = CTSVC_PROPERTY_NUMBER_NUMBER,
+       .number_filter          = CTSVC_PROPERTY_NUMBER_NUMBER_FILTER,
+       .normalized_number = CTSVC_PROPERTY_NUMBER_NORMALIZED_NUMBER,
+       .cleaned_number = CTSVC_PROPERTY_NUMBER_CLEANED_NUMBER
+};
+
+API const _contacts_person_email_property_ids _contacts_person_email = {
+       ._uri                                   = CTSVC_VIEW_URI_READ_ONLY_PERSON_EMAIL,
+       .person_id                              = CTSVC_PROPERTY_PERSON_ID,
+       .display_name                   = CTSVC_PROPERTY_PERSON_DISPLAY_NAME,
+       .display_name_index             = CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX,
+       .display_contact_id             = CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID,
+       .ringtone_path                  = CTSVC_PROPERTY_PERSON_RINGTONE,
+       .image_thumbnail_path   = CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,
+       .vibration                              = CTSVC_PROPERTY_PERSON_VIBRATION,
+       .message_alert          = CTSVC_PROPERTY_PERSON_MESSAGE_ALERT,
+       .is_favorite                    = CTSVC_PROPERTY_PERSON_IS_FAVORITE,
+       .has_phonenumber                = CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER,
+       .has_email                              = CTSVC_PROPERTY_PERSON_HAS_EMAIL,
+       .email_id                       = CTSVC_PROPERTY_EMAIL_ID,
+       .type                           = CTSVC_PROPERTY_EMAIL_TYPE,
+       .label                          = CTSVC_PROPERTY_EMAIL_LABEL,
+       .is_primary_default     = CTSVC_PROPERTY_DATA_IS_PRIMARY_DEFAULT,
+       .email                          = CTSVC_PROPERTY_EMAIL_EMAIL
+};
+
+API const _contacts_person_usage_property_ids _contacts_person_usage = {
+       ._uri                                   = CTSVC_VIEW_URI_READ_ONLY_PERSON_USAGE,
+       .person_id                              = CTSVC_PROPERTY_PERSON_ID,
+       .display_name                   = CTSVC_PROPERTY_PERSON_DISPLAY_NAME,
+       .display_name_index             = CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX,
+       .display_contact_id             = CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID,
+       .ringtone_path                  = CTSVC_PROPERTY_PERSON_RINGTONE,
+       .image_thumbnail_path   = CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,
+       .vibration                              = CTSVC_PROPERTY_PERSON_VIBRATION,
+       .message_alert          = CTSVC_PROPERTY_PERSON_MESSAGE_ALERT,
+       .is_favorite                    = CTSVC_PROPERTY_PERSON_IS_FAVORITE,
+       .has_phonenumber                = CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER,
+       .has_email                              = CTSVC_PROPERTY_PERSON_HAS_EMAIL,
+       .usage_type                             = CTSVC_PROPERTY_PERSON_USAGE_TYPE,
+       .times_used                             = CTSVC_PROPERTY_PERSON_TIMES_USED
+};
+
+API const _contacts_person_grouprel_property_ids _contacts_person_grouprel = {
+       ._uri                                   = CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP,
+       .person_id                              = CTSVC_PROPERTY_PERSON_ID,
+       .display_name                   = CTSVC_PROPERTY_PERSON_DISPLAY_NAME,
+       .display_name_index             = CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX,
+       .display_contact_id             = CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID,
+       .ringtone_path                  = CTSVC_PROPERTY_PERSON_RINGTONE,
+       .image_thumbnail_path   = CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,
+       .vibration                              = CTSVC_PROPERTY_PERSON_VIBRATION,
+       .message_alert                  = CTSVC_PROPERTY_PERSON_MESSAGE_ALERT,
+       .status                                 = CTSVC_PROPERTY_PERSON_STATUS,
+       .is_favorite                    = CTSVC_PROPERTY_PERSON_IS_FAVORITE,
+       .has_phonenumber                = CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER,
+       .has_email                              = CTSVC_PROPERTY_PERSON_HAS_EMAIL,
+       .link_count                             = CTSVC_PROPERTY_PERSON_LINK_COUNT,
+       .addressbook_ids                = CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS,
+       .address_book_id                = CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,
+       .group_id               = CTSVC_PROPERTY_GROUP_RELATION_GROUP_ID,
+       .address_book_name              = CTSVC_PROPERTY_ADDRESSBOOK_NAME,
+       .address_book_mode              = CTSVC_PROPERTY_ADDRESSBOOK_MODE,
+       .contact_id                             = CTSVC_PROPERTY_GROUP_RELATION_CONTACT_ID
+};
+
+API const _contacts_person_group_not_assigned_property_ids _contacts_person_group_not_assigned = {
+       ._uri                                           = CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP_NOT_ASSIGNED,
+       .person_id                              = CTSVC_PROPERTY_PERSON_ID,
+       .display_name                   = CTSVC_PROPERTY_PERSON_DISPLAY_NAME,
+       .display_name_index             = CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX,
+       .display_contact_id             = CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID,
+       .ringtone_path                          = CTSVC_PROPERTY_PERSON_RINGTONE,
+       .image_thumbnail_path           = CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,
+       .vibration                                      = CTSVC_PROPERTY_PERSON_VIBRATION,
+       .message_alert                  = CTSVC_PROPERTY_PERSON_MESSAGE_ALERT,
+       .status                                 = CTSVC_PROPERTY_PERSON_STATUS,
+       .is_favorite                            = CTSVC_PROPERTY_PERSON_IS_FAVORITE,
+       .has_phonenumber                        = CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER,
+       .has_email                              = CTSVC_PROPERTY_PERSON_HAS_EMAIL,
+       .link_count                             = CTSVC_PROPERTY_PERSON_LINK_COUNT,
+       .linked_address_book_ids        = CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS,
+       .contact_id                             = CTSVC_PROPERTY_CONTACT_ID,
+       .address_book_id                        = CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,
+       .address_book_mode              = CTSVC_PROPERTY_ADDRESSBOOK_MODE
+};
+
+API const _contacts_person_group_assigned_property_ids _contacts_person_group_assigned = {
+       ._uri                                   = CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP_ASSIGNED,
+       .person_id                              = CTSVC_PROPERTY_PERSON_ID,
+       .display_name                   = CTSVC_PROPERTY_PERSON_DISPLAY_NAME,
+       .display_name_index             = CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX,
+       .display_contact_id             = CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID,
+       .ringtone_path                  = CTSVC_PROPERTY_PERSON_RINGTONE,
+       .image_thumbnail_path   = CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,
+       .vibration                              = CTSVC_PROPERTY_PERSON_VIBRATION,
+       .message_alert                  = CTSVC_PROPERTY_PERSON_MESSAGE_ALERT,
+       .status                                 = CTSVC_PROPERTY_PERSON_STATUS,
+       .is_favorite                    = CTSVC_PROPERTY_PERSON_IS_FAVORITE,
+       .has_phonenumber                = CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER,
+       .has_email                              = CTSVC_PROPERTY_PERSON_HAS_EMAIL,
+       .link_count                             = CTSVC_PROPERTY_PERSON_LINK_COUNT,
+       .linked_address_book_ids                = CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS,
+       .address_book_id                = CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,
+       .group_id                               = CTSVC_PROPERTY_GROUP_RELATION_GROUP_ID,
+       .address_book_mode              = CTSVC_PROPERTY_ADDRESSBOOK_MODE,
+       .contact_id                             = CTSVC_PROPERTY_GROUP_RELATION_CONTACT_ID
+};
+
+#ifdef ENABLE_LOG_FEATURE
+API const _contacts_person_phone_log_property_ids _contacts_person_phone_log = {
+       ._uri                   = CTSVC_VIEW_URI_READ_ONLY_PERSON_PHONELOG,
+       .person_id                              = CTSVC_PROPERTY_PERSON_ID,
+       .display_name                   = CTSVC_PROPERTY_PERSON_DISPLAY_NAME,
+       .image_thumbnail_path   = CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,
+       .log_id = CTSVC_PROPERTY_PHONELOG_ID,
+       .address                = CTSVC_PROPERTY_PHONELOG_ADDRESS,
+       .address_type   = CTSVC_PROPERTY_DATA_DATA1,
+       .log_time               = CTSVC_PROPERTY_PHONELOG_LOG_TIME,
+       .log_type               = CTSVC_PROPERTY_PHONELOG_LOG_TYPE,
+       .extra_data1    = CTSVC_PROPERTY_PHONELOG_EXTRA_DATA1,
+       .extra_data2    = CTSVC_PROPERTY_PHONELOG_EXTRA_DATA2,
+       .normalized_address = CTSVC_PROPERTY_PHONELOG_NORMALIZED_ADDRESS,
+       .cleaned_address = CTSVC_PROPERTY_PHONELOG_CLEANED_ADDRESS,
+       .address_filter = CTSVC_PROPERTY_PHONELOG_CLEANED_ADDRESS,
+       .sim_slot_no            = CTSVC_PROPERTY_PHONELOG_SIM_SLOT_NO,
+};
+#endif // ENABLE_LOG_FEATURE
+
+API const _contacts_contact_number_property_ids _contacts_contact_number = {
+       ._uri                                   = CTSVC_VIEW_URI_READ_ONLY_CONTACT_NUMBER,
+       .contact_id                             = CTSVC_PROPERTY_CONTACT_ID,
+       .display_name                   = CTSVC_PROPERTY_CONTACT_DISPLAY_NAME,
+       .display_source_type    = CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID,
+       .address_book_id                = CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,
+       .person_id                              = CTSVC_PROPERTY_CONTACT_PERSON_ID,
+       .ringtone_path                  = CTSVC_PROPERTY_CONTACT_RINGTONE,
+       .image_thumbnail_path   = CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL,
+       .number_id                      = CTSVC_PROPERTY_NUMBER_ID,
+       .type                           = CTSVC_PROPERTY_NUMBER_TYPE,
+       .label                          = CTSVC_PROPERTY_NUMBER_LABEL,
+       .is_default                     = CTSVC_PROPERTY_NUMBER_IS_DEFAULT,
+       .number                         = CTSVC_PROPERTY_NUMBER_NUMBER,
+       .number_filter          = CTSVC_PROPERTY_NUMBER_NUMBER_FILTER,
+       .normalized_number = CTSVC_PROPERTY_NUMBER_NORMALIZED_NUMBER,
+       .cleaned_number = CTSVC_PROPERTY_NUMBER_CLEANED_NUMBER
+};
+
+API const _contacts_contact_email_property_ids _contacts_contact_email = {
+       ._uri                                   = CTSVC_VIEW_URI_READ_ONLY_CONTACT_EMAIL,
+       .contact_id                             = CTSVC_PROPERTY_CONTACT_ID,
+       .display_name                   = CTSVC_PROPERTY_CONTACT_DISPLAY_NAME,
+       .display_source_type    = CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID,
+       .address_book_id                = CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,
+       .person_id                              = CTSVC_PROPERTY_CONTACT_PERSON_ID,
+       .ringtone_path                  = CTSVC_PROPERTY_CONTACT_RINGTONE,
+       .image_thumbnail_path   = CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL,
+       .email_id                       = CTSVC_PROPERTY_EMAIL_ID,
+       .type                           = CTSVC_PROPERTY_EMAIL_TYPE,
+       .label                          = CTSVC_PROPERTY_EMAIL_LABEL,
+       .is_default                     = CTSVC_PROPERTY_EMAIL_IS_DEFAULT,
+       .email                          = CTSVC_PROPERTY_EMAIL_EMAIL
+};
+
+API const _contacts_contact_grouprel_property_ids _contacts_contact_grouprel = {
+       ._uri                                   = CTSVC_VIEW_URI_READ_ONLY_CONTACT_GROUP,
+       .contact_id                             = CTSVC_PROPERTY_CONTACT_ID,
+       .display_name                   = CTSVC_PROPERTY_CONTACT_DISPLAY_NAME,
+       .display_source_type    = CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID,
+       .address_book_id                = CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,
+       .person_id                              = CTSVC_PROPERTY_CONTACT_PERSON_ID,
+       .ringtone_path                  = CTSVC_PROPERTY_CONTACT_RINGTONE,
+       .image_thumbnail_path   = CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL,
+       .group_id               = CTSVC_PROPERTY_GROUP_RELATION_GROUP_ID,
+       .group_name             = CTSVC_PROPERTY_GROUP_RELATION_GROUP_NAME
+};
+
+API const _contacts_contact_activity_property_ids _contacts_contact_activity = {
+       ._uri                   = CTSVC_VIEW_URI_READ_ONLY_CONTACT_ACTIVITY,
+       .contact_id                             = CTSVC_PROPERTY_CONTACT_ID,
+       .display_name                   = CTSVC_PROPERTY_CONTACT_DISPLAY_NAME,
+       .display_source_type    = CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID,
+       .address_book_id                = CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,
+       .person_id                              = CTSVC_PROPERTY_CONTACT_PERSON_ID,
+       .ringtone_path                  = CTSVC_PROPERTY_CONTACT_RINGTONE,
+       .image_thumbnail_path   = CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL,
+       .activity_id    = CTSVC_PROPERTY_ACTIVITY_ID,
+       .source_name    = CTSVC_PROPERTY_ACTIVITY_SOURCE_NAME,
+       .status                 = CTSVC_PROPERTY_ACTIVITY_STATUS,
+       .timestamp              = CTSVC_PROPERTY_ACTIVITY_TIMESTAMP,
+       .service_operation      = CTSVC_PROPERTY_ACTIVITY_SERVICE_OPERATION,
+       .uri                            = CTSVC_PROPERTY_ACTIVITY_URI,
+       .account_id             = CTSVC_PROPERTY_ADDRESSBOOK_ACCOUNT_ID,
+};
+
+#ifdef ENABLE_LOG_FEATURE
+API const _contacts_phone_log_stat_property_ids _contacts_phone_log_stat = {
+       ._uri           = CTSVC_VIEW_URI_READ_ONLY_PHONELOG_STAT,
+       .log_count      = CTSVC_PROPERTY_PHONELOG_STAT_LOG_COUNT,
+       .log_type       = CTSVC_PROPERTY_PHONELOG_STAT_LOG_TYPE,
+};
+#endif // ENABLE_LOG_FEATURE
+
+const property_info_s __property_addressbook[] = {
+       {CTSVC_PROPERTY_ADDRESSBOOK_ID,                 CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_id"},
+       {CTSVC_PROPERTY_ADDRESSBOOK_ACCOUNT_ID, CTSVC_SEARCH_PROPERTY_ALL,      "account_id"},
+       {CTSVC_PROPERTY_ADDRESSBOOK_NAME,               CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_name"},
+       {CTSVC_PROPERTY_ADDRESSBOOK_MODE,               CTSVC_SEARCH_PROPERTY_ALL,      "mode"},
+};
+
+#ifdef ENABLE_SIM_FEATURE
+const property_info_s __property_sdn[] = {             // _contacts_sdn
+       {CTSVC_PROPERTY_SDN_ID,         CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_SDN_NAME,               CTSVC_SEARCH_PROPERTY_ALL,      "name"},
+       {CTSVC_PROPERTY_SDN_NUMBER,     CTSVC_SEARCH_PROPERTY_ALL,      "number"},
+       {CTSVC_PROPERTY_SDN_SIM_SLOT_NO,        CTSVC_SEARCH_PROPERTY_ALL,      "sim_slot_no"},
+};
+#endif // ENABLE_SIM_FEATURE
+
+const property_info_s __property_group[] = {
+       {CTSVC_PROPERTY_GROUP_ID,                               CTSVC_SEARCH_PROPERTY_ALL,      "group_id"},
+       {CTSVC_PROPERTY_GROUP_ADDRESSBOOK_ID,   CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_id"},
+       {CTSVC_PROPERTY_GROUP_NAME,                     CTSVC_SEARCH_PROPERTY_ALL,      "group_name"},
+       {CTSVC_PROPERTY_GROUP_RINGTONE,         CTSVC_SEARCH_PROPERTY_ALL,      "ringtone_path"},
+       {CTSVC_PROPERTY_GROUP_IMAGE,                    CTSVC_SEARCH_PROPERTY_ALL,      "image_thumbnail_path"},
+       {CTSVC_PROPERTY_GROUP_VIBRATION,                CTSVC_SEARCH_PROPERTY_ALL,      "vibration"},
+       {CTSVC_PROPERTY_GROUP_EXTRA_DATA,               CTSVC_SEARCH_PROPERTY_ALL,      "extra_data"},
+       {CTSVC_PROPERTY_GROUP_IS_READ_ONLY,     CTSVC_SEARCH_PROPERTY_ALL,      "is_read_only"},
+       {CTSVC_PROPERTY_GROUP_MESSAGE_ALERT,    CTSVC_SEARCH_PROPERTY_ALL,      "message_alert"},
+};
+
+const property_info_s __property_person[] = {
+       {CTSVC_PROPERTY_PERSON_ID,                                      CTSVC_SEARCH_PROPERTY_ALL,      "person_id"},
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME,            CTSVC_SEARCH_PROPERTY_ALL,      NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX,      CTSVC_SEARCH_PROPERTY_PROJECTION,       NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID,CTSVC_SEARCH_PROPERTY_ALL,    "name_contact_id"},
+       {CTSVC_PROPERTY_PERSON_RINGTONE,                        CTSVC_SEARCH_PROPERTY_ALL,      "ringtone_path"},
+       {CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL, CTSVC_SEARCH_PROPERTY_ALL,      "image_thumbnail_path"},
+       {CTSVC_PROPERTY_PERSON_VIBRATION,               CTSVC_SEARCH_PROPERTY_ALL,      "vibration"},
+       {CTSVC_PROPERTY_PERSON_MESSAGE_ALERT,   CTSVC_SEARCH_PROPERTY_ALL,      "message_alert"},
+       {CTSVC_PROPERTY_PERSON_STATUS,                  CTSVC_SEARCH_PROPERTY_ALL,      "status"},
+       {CTSVC_PROPERTY_PERSON_IS_FAVORITE,             CTSVC_SEARCH_PROPERTY_ALL,      "is_favorite"},
+       {CTSVC_PROPERTY_PERSON_FAVORITE_PRIORITY,       CTSVC_SEARCH_PROPERTY_FILTER,   "favorite_prio"},
+       {CTSVC_PROPERTY_PERSON_LINK_COUNT,              CTSVC_SEARCH_PROPERTY_ALL,      "link_count"},
+       {CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS, CTSVC_SEARCH_PROPERTY_PROJECTION,       "addressbook_ids"},
+       {CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER, CTSVC_SEARCH_PROPERTY_ALL,      "has_phonenumber"},
+       {CTSVC_PROPERTY_PERSON_HAS_EMAIL,               CTSVC_SEARCH_PROPERTY_ALL,      "has_email"},
+};
+
+const property_info_s __property_simple_contact[] = {
+       {CTSVC_PROPERTY_CONTACT_ID,                             CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_CONTACT_DISPLAY_NAME,   CTSVC_SEARCH_PROPERTY_ALL,      NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID, CTSVC_SEARCH_PROPERTY_ALL,      "display_name_source"},
+       {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID, CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_id"},
+       {CTSVC_PROPERTY_CONTACT_RINGTONE,               CTSVC_SEARCH_PROPERTY_ALL,      "ringtone_path"},
+       {CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL,CTSVC_SEARCH_PROPERTY_ALL,      "image_thumbnail_path"},
+       {CTSVC_PROPERTY_CONTACT_IS_FAVORITE,            CTSVC_SEARCH_PROPERTY_ALL,      "is_favorite"},
+       {CTSVC_PROPERTY_CONTACT_HAS_PHONENUMBER, CTSVC_SEARCH_PROPERTY_ALL,     "has_phonenumber"},
+       {CTSVC_PROPERTY_CONTACT_HAS_EMAIL,              CTSVC_SEARCH_PROPERTY_ALL,      "has_email"},
+       {CTSVC_PROPERTY_CONTACT_PERSON_ID,              CTSVC_SEARCH_PROPERTY_ALL,      "person_id"},
+       {CTSVC_PROPERTY_CONTACT_UID,                            CTSVC_SEARCH_PROPERTY_ALL,      "uid"},
+       {CTSVC_PROPERTY_CONTACT_VIBRATION,              CTSVC_SEARCH_PROPERTY_ALL,      "vibration"},
+       {CTSVC_PROPERTY_CONTACT_MESSAGE_ALERT,          CTSVC_SEARCH_PROPERTY_ALL,      "message_alert"},
+       {CTSVC_PROPERTY_CONTACT_CHANGED_TIME,   CTSVC_SEARCH_PROPERTY_ALL,      "changed_time"},
+};
+
+const property_info_s __property_name[] = {
+       {CTSVC_PROPERTY_NAME_ID,                                        CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_NAME_CONTACT_ID,                        CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_NAME_FIRST,                             CTSVC_SEARCH_PROPERTY_ALL,      "data2"},
+       {CTSVC_PROPERTY_NAME_LAST,                                      CTSVC_SEARCH_PROPERTY_ALL,      "data3"},
+       {CTSVC_PROPERTY_NAME_ADDITION,                  CTSVC_SEARCH_PROPERTY_ALL,      "data4"},
+       {CTSVC_PROPERTY_NAME_PREFIX,                            CTSVC_SEARCH_PROPERTY_ALL,      "data5"},
+       {CTSVC_PROPERTY_NAME_SUFFIX,                            CTSVC_SEARCH_PROPERTY_ALL,      "data6"},
+       {CTSVC_PROPERTY_NAME_PHONETIC_FIRST,    CTSVC_SEARCH_PROPERTY_ALL,      "data7"},
+       {CTSVC_PROPERTY_NAME_PHONETIC_MIDDLE,   CTSVC_SEARCH_PROPERTY_ALL,      "data8"},
+       {CTSVC_PROPERTY_NAME_PHONETIC_LAST,             CTSVC_SEARCH_PROPERTY_ALL,      "data9"},
+};
+
+const property_info_s __property_number[] = {          //_contacts_number
+       {CTSVC_PROPERTY_NUMBER_ID,                              CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_NUMBER_CONTACT_ID,      CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_NUMBER_TYPE,                    CTSVC_SEARCH_PROPERTY_ALL,      "data1"},
+       {CTSVC_PROPERTY_NUMBER_LABEL,                   CTSVC_SEARCH_PROPERTY_ALL,      "data2"},
+       {CTSVC_PROPERTY_NUMBER_IS_DEFAULT,      CTSVC_SEARCH_PROPERTY_ALL,      "is_default"},
+       {CTSVC_PROPERTY_NUMBER_NUMBER,          CTSVC_SEARCH_PROPERTY_ALL,      "data3"},
+       {CTSVC_PROPERTY_NUMBER_NORMALIZED_NUMBER,       CTSVC_SEARCH_PROPERTY_FILTER,   "data5"},
+       {CTSVC_PROPERTY_NUMBER_CLEANED_NUMBER,  CTSVC_SEARCH_PROPERTY_FILTER,   "data6"},
+       {CTSVC_PROPERTY_NUMBER_NUMBER_FILTER,   CTSVC_SEARCH_PROPERTY_FILTER,   "data4"},
+};
+
+const property_info_s __property_email[] = {
+       {CTSVC_PROPERTY_EMAIL_ID,                               CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_EMAIL_CONTACT_ID,       CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_EMAIL_TYPE,                     CTSVC_SEARCH_PROPERTY_ALL,      "data1"},
+       {CTSVC_PROPERTY_EMAIL_LABEL,                    CTSVC_SEARCH_PROPERTY_ALL,      "data2"},
+       {CTSVC_PROPERTY_EMAIL_IS_DEFAULT,       CTSVC_SEARCH_PROPERTY_ALL,      "is_default"},
+       {CTSVC_PROPERTY_EMAIL_EMAIL,                    CTSVC_SEARCH_PROPERTY_ALL,      "data3"},
+};
+
+const property_info_s __property_address[] = {
+       {CTSVC_PROPERTY_ADDRESS_ID,                     CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_ADDRESS_CONTACT_ID,     CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_ADDRESS_TYPE,                   CTSVC_SEARCH_PROPERTY_ALL,      "data1"},
+       {CTSVC_PROPERTY_ADDRESS_LABEL,          CTSVC_SEARCH_PROPERTY_ALL,      "data2"},
+       {CTSVC_PROPERTY_ADDRESS_POSTBOX,                CTSVC_SEARCH_PROPERTY_ALL,      "data3"},
+       {CTSVC_PROPERTY_ADDRESS_POSTAL_CODE,CTSVC_SEARCH_PROPERTY_ALL,  "data4"},
+       {CTSVC_PROPERTY_ADDRESS_REGION,         CTSVC_SEARCH_PROPERTY_ALL,      "data5"},
+       {CTSVC_PROPERTY_ADDRESS_LOCALITY,       CTSVC_SEARCH_PROPERTY_ALL,      "data6"},
+       {CTSVC_PROPERTY_ADDRESS_STREET,         CTSVC_SEARCH_PROPERTY_ALL,      "data7"},
+       {CTSVC_PROPERTY_ADDRESS_COUNTRY,                CTSVC_SEARCH_PROPERTY_ALL,      "data9"},
+       {CTSVC_PROPERTY_ADDRESS_EXTENDED,       CTSVC_SEARCH_PROPERTY_ALL,      "data8"},
+       {CTSVC_PROPERTY_ADDRESS_IS_DEFAULT,     CTSVC_SEARCH_PROPERTY_ALL,      "is_default"},
+};
+
+const property_info_s __property_url[] = {
+       {CTSVC_PROPERTY_URL_ID,                         CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_URL_CONTACT_ID, CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_URL_TYPE,                       CTSVC_SEARCH_PROPERTY_ALL,      "data1"},
+       {CTSVC_PROPERTY_URL_LABEL,                      CTSVC_SEARCH_PROPERTY_ALL,      "data2"},
+       {CTSVC_PROPERTY_URL_URL,                        CTSVC_SEARCH_PROPERTY_ALL,      "data3"},
+};
+
+const property_info_s __property_event[] = {
+       {CTSVC_PROPERTY_EVENT_ID,                               CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_EVENT_CONTACT_ID,       CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_EVENT_TYPE,                     CTSVC_SEARCH_PROPERTY_ALL,      "data1"},
+       {CTSVC_PROPERTY_EVENT_LABEL,                    CTSVC_SEARCH_PROPERTY_ALL,      "data2"},
+       {CTSVC_PROPERTY_EVENT_DATE,                     CTSVC_SEARCH_PROPERTY_ALL,      "data3"},
+       {CTSVC_PROPERTY_EVENT_CALENDAR_TYPE,    CTSVC_SEARCH_PROPERTY_ALL,      "data4"},
+       {CTSVC_PROPERTY_EVENT_IS_LEAP_MONTH,    CTSVC_SEARCH_PROPERTY_ALL,      "data5"},
+};
+
+const property_info_s __property_group_relation[] = {
+       {CTSVC_PROPERTY_GROUP_RELATION_GROUP_ID,        CTSVC_SEARCH_PROPERTY_ALL,      "group_id"},
+       {CTSVC_PROPERTY_GROUP_RELATION_CONTACT_ID,      CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_GROUP_RELATION_GROUP_NAME,CTSVC_SEARCH_PROPERTY_ALL,    "group_name"},
+};
+
+const property_info_s __property_relationship[] = {
+       {CTSVC_PROPERTY_RELATIONSHIP_ID,                                CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_RELATIONSHIP_CONTACT_ID,        CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_RELATIONSHIP_TYPE,                      CTSVC_SEARCH_PROPERTY_ALL,      "data1"},
+       {CTSVC_PROPERTY_RELATIONSHIP_LABEL,                     CTSVC_SEARCH_PROPERTY_ALL,      "data2"},
+       {CTSVC_PROPERTY_RELATIONSHIP_NAME,                      CTSVC_SEARCH_PROPERTY_ALL,      "data3"},
+};
+
+const property_info_s __property_image[] = {
+       {CTSVC_PROPERTY_IMAGE_ID,                               CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_IMAGE_CONTACT_ID,       CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_IMAGE_TYPE,                     CTSVC_SEARCH_PROPERTY_ALL,      "data1"},
+       {CTSVC_PROPERTY_IMAGE_LABEL,                    CTSVC_SEARCH_PROPERTY_ALL,      "data2"},
+       {CTSVC_PROPERTY_IMAGE_PATH,                     CTSVC_SEARCH_PROPERTY_ALL,      "data3"},
+       {CTSVC_PROPERTY_IMAGE_IS_DEFAULT,       CTSVC_SEARCH_PROPERTY_ALL,      "is_default"},
+};
+
+const property_info_s __property_company[] = {
+       {CTSVC_PROPERTY_COMPANY_ID,                             CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_COMPANY_CONTACT_ID,             CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_COMPANY_TYPE,                           CTSVC_SEARCH_PROPERTY_ALL,      "data1"},
+       {CTSVC_PROPERTY_COMPANY_LABEL,                  CTSVC_SEARCH_PROPERTY_ALL,      "data2"},
+       {CTSVC_PROPERTY_COMPANY_NAME,                           CTSVC_SEARCH_PROPERTY_ALL,      "data3"},
+       {CTSVC_PROPERTY_COMPANY_DEPARTMENT,             CTSVC_SEARCH_PROPERTY_ALL,      "data4"},
+       {CTSVC_PROPERTY_COMPANY_JOB_TITLE,              CTSVC_SEARCH_PROPERTY_ALL,      "data5"},
+       {CTSVC_PROPERTY_COMPANY_ROLE,                   CTSVC_SEARCH_PROPERTY_ALL,      "data6"},
+       {CTSVC_PROPERTY_COMPANY_ASSISTANT_NAME, CTSVC_SEARCH_PROPERTY_ALL,      "data7"},
+       {CTSVC_PROPERTY_COMPANY_LOGO,                           CTSVC_SEARCH_PROPERTY_ALL,      "data8"},
+       {CTSVC_PROPERTY_COMPANY_LOCATION,               CTSVC_SEARCH_PROPERTY_ALL,      "data9"},
+       {CTSVC_PROPERTY_COMPANY_DESCRIPTION,    CTSVC_SEARCH_PROPERTY_ALL,      "data10"},
+       {CTSVC_PROPERTY_COMPANY_PHONETIC_NAME,  CTSVC_SEARCH_PROPERTY_ALL,      "data11"},
+};
+
+const property_info_s __property_nickname[] = {
+       {CTSVC_PROPERTY_NICKNAME_ID,                            CTSVC_SEARCH_PROPERTY_ALL,      "id",},
+       {CTSVC_PROPERTY_NICKNAME_CONTACT_ID,    CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_NICKNAME_NAME,                  CTSVC_SEARCH_PROPERTY_ALL,      "data3"},
+};
+
+const property_info_s __property_messenger[] = {
+       {CTSVC_PROPERTY_MESSENGER_ID,                           CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_MESSENGER_CONTACT_ID,   CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_MESSENGER_TYPE,                 CTSVC_SEARCH_PROPERTY_ALL,      "data1"},
+       {CTSVC_PROPERTY_MESSENGER_LABEL,                        CTSVC_SEARCH_PROPERTY_ALL,      "data2"},
+       {CTSVC_PROPERTY_MESSENGER_IM_ID,                        CTSVC_SEARCH_PROPERTY_ALL,      "data3"},
+};
+
+const property_info_s __property_note[] = {
+       {CTSVC_PROPERTY_NOTE_ID,                        CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_NOTE_CONTACT_ID,        CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_NOTE_NOTE,                      CTSVC_SEARCH_PROPERTY_ALL,      "data3"},
+};
+
+const property_info_s __property_profile[] = {
+       {CTSVC_PROPERTY_PROFILE_ID,                                     CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_PROFILE_CONTACT_ID,                     CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_PROFILE_UID,                                    CTSVC_SEARCH_PROPERTY_ALL,      "data3"},
+       {CTSVC_PROPERTY_PROFILE_TEXT,                                   CTSVC_SEARCH_PROPERTY_ALL,      "data4"},
+       {CTSVC_PROPERTY_PROFILE_ORDER,                          CTSVC_SEARCH_PROPERTY_ALL,      "data5"},
+       {CTSVC_PROPERTY_PROFILE_SERVICE_OPERATION,      CTSVC_SEARCH_PROPERTY_ALL,      "data6"},
+       {CTSVC_PROPERTY_PROFILE_MIME,                           CTSVC_SEARCH_PROPERTY_ALL,      "data7"},
+       {CTSVC_PROPERTY_PROFILE_APP_ID,                         CTSVC_SEARCH_PROPERTY_ALL,      "data8"},
+       {CTSVC_PROPERTY_PROFILE_URI,                                    CTSVC_SEARCH_PROPERTY_ALL,      "data9"},
+       {CTSVC_PROPERTY_PROFILE_CATEGORY,                       CTSVC_SEARCH_PROPERTY_ALL,      "data10"},
+       {CTSVC_PROPERTY_PROFILE_EXTRA_DATA,             CTSVC_SEARCH_PROPERTY_ALL,      "data11"},
+};
+
+const property_info_s __property_activity_photo[] = {
+       {CTSVC_PROPERTY_ACTIVITY_PHOTO_ID,                      CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_ACTIVITY_PHOTO_ACTIVITY_ID,     CTSVC_SEARCH_PROPERTY_ALL,      "activity_id"},
+       {CTSVC_PROPERTY_ACTIVITY_PHOTO_URL,                     CTSVC_SEARCH_PROPERTY_ALL,      "photo_url"},
+       {CTSVC_PROPERTY_ACTIVITY_PHOTO_SORT_INDEX,      CTSVC_SEARCH_PROPERTY_ALL,      "sort_index"},
+};
+
+const property_info_s __property_activity[] = {
+       {CTSVC_PROPERTY_ACTIVITY_ID,                            CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_ACTIVITY_CONTACT_ID,            CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_ACTIVITY_SOURCE_NAME,   CTSVC_SEARCH_PROPERTY_ALL,      "source_name"},
+       {CTSVC_PROPERTY_ACTIVITY_STATUS,                        CTSVC_SEARCH_PROPERTY_ALL,      "status"},
+       {CTSVC_PROPERTY_ACTIVITY_TIMESTAMP,             CTSVC_SEARCH_PROPERTY_ALL,      "timestamp"},
+       {CTSVC_PROPERTY_ACTIVITY_SERVICE_OPERATION, CTSVC_SEARCH_PROPERTY_ALL,  "service_operation"},
+       {CTSVC_PROPERTY_ACTIVITY_URI,                           CTSVC_SEARCH_PROPERTY_ALL,      "uri"},
+       {CTSVC_PROPERTY_ACTIVITY_ACTIVITY_PHOTO,CTSVC_SEARCH_PROPERTY_NONE,     (void*)__property_activity_photo},
+};
+
+const property_info_s __property_extension[] = {
+       {CTSVC_PROPERTY_EXTENSION_ID,                           CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_EXTENSION_CONTACT_ID,   CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_EXTENSION_DATA1,                CTSVC_SEARCH_PROPERTY_ALL,      "data1"},
+       {CTSVC_PROPERTY_EXTENSION_DATA2,                CTSVC_SEARCH_PROPERTY_ALL,      "data2"},
+       {CTSVC_PROPERTY_EXTENSION_DATA3,                CTSVC_SEARCH_PROPERTY_ALL,      "data3"},
+       {CTSVC_PROPERTY_EXTENSION_DATA4,                CTSVC_SEARCH_PROPERTY_ALL,      "data4"},
+       {CTSVC_PROPERTY_EXTENSION_DATA5,                CTSVC_SEARCH_PROPERTY_ALL,      "data5"},
+       {CTSVC_PROPERTY_EXTENSION_DATA6,                CTSVC_SEARCH_PROPERTY_ALL,      "data6"},
+       {CTSVC_PROPERTY_EXTENSION_DATA7,                CTSVC_SEARCH_PROPERTY_ALL,      "data7"},
+       {CTSVC_PROPERTY_EXTENSION_DATA8,                CTSVC_SEARCH_PROPERTY_ALL,      "data8"},
+       {CTSVC_PROPERTY_EXTENSION_DATA9,                CTSVC_SEARCH_PROPERTY_ALL,      "data9"},
+       {CTSVC_PROPERTY_EXTENSION_DATA10,               CTSVC_SEARCH_PROPERTY_ALL,      "data10"},
+       {CTSVC_PROPERTY_EXTENSION_DATA11,               CTSVC_SEARCH_PROPERTY_ALL,      "data11"},
+       {CTSVC_PROPERTY_EXTENSION_DATA12,               CTSVC_SEARCH_PROPERTY_ALL,      "data12"},
+};
+
+const property_info_s __property_contact[] = {
+       {CTSVC_PROPERTY_CONTACT_ID,                                     CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_CONTACT_DISPLAY_NAME,           CTSVC_SEARCH_PROPERTY_ALL,      NULL},  //dispaly_name, reverse_display_name
+       {CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID, CTSVC_SEARCH_PROPERTY_ALL,      "display_name_source"},
+       {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,         CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_id"},
+       {CTSVC_PROPERTY_CONTACT_RINGTONE,                       CTSVC_SEARCH_PROPERTY_ALL,      "ringtone_path"},
+       {CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL,        CTSVC_SEARCH_PROPERTY_ALL,      "image_thumbnail_path"},
+       {CTSVC_PROPERTY_CONTACT_IS_FAVORITE,                    CTSVC_SEARCH_PROPERTY_ALL,      "is_favorite"},
+       {CTSVC_PROPERTY_CONTACT_HAS_PHONENUMBER,        CTSVC_SEARCH_PROPERTY_ALL,      "has_phonenumber"},
+       {CTSVC_PROPERTY_CONTACT_HAS_EMAIL,                      CTSVC_SEARCH_PROPERTY_ALL,      "has_email"},
+       {CTSVC_PROPERTY_CONTACT_PERSON_ID,                      CTSVC_SEARCH_PROPERTY_ALL,      "person_id"},
+       {CTSVC_PROPERTY_CONTACT_UID,                                    CTSVC_SEARCH_PROPERTY_ALL,      "uid"},
+       {CTSVC_PROPERTY_CONTACT_VIBRATION,                      CTSVC_SEARCH_PROPERTY_ALL,      "vibration"},
+       {CTSVC_PROPERTY_CONTACT_MESSAGE_ALERT,          CTSVC_SEARCH_PROPERTY_ALL,      "message_alert"},
+       {CTSVC_PROPERTY_CONTACT_CHANGED_TIME,           CTSVC_SEARCH_PROPERTY_ALL,      "changed_time"},
+       {CTSVC_PROPERTY_CONTACT_LINK_MODE,                      CTSVC_SEARCH_PROPERTY_ALL,      "link_mode"},
+       {CTSVC_PROPERTY_CONTACT_NAME,                                   CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_name},
+       {CTSVC_PROPERTY_CONTACT_COMPANY,                                CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_company},
+       {CTSVC_PROPERTY_CONTACT_NOTE,                                   CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_note},
+       {CTSVC_PROPERTY_CONTACT_NUMBER,                         CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_number},
+       {CTSVC_PROPERTY_CONTACT_EMAIL,                          CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_email},
+       {CTSVC_PROPERTY_CONTACT_EVENT,                          CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_event},
+       {CTSVC_PROPERTY_CONTACT_MESSENGER,                      CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_messenger},
+       {CTSVC_PROPERTY_CONTACT_ADDRESS,                                CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_address},
+       {CTSVC_PROPERTY_CONTACT_URL,                                    CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_url},
+       {CTSVC_PROPERTY_CONTACT_NICKNAME,                       CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_nickname},
+       {CTSVC_PROPERTY_CONTACT_PROFILE,                                CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_profile},
+       {CTSVC_PROPERTY_CONTACT_RELATIONSHIP,           CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_relationship},
+       {CTSVC_PROPERTY_CONTACT_IMAGE,                          CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_image},
+       {CTSVC_PROPERTY_CONTACT_GROUP_RELATION,         CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_group_relation},
+       {CTSVC_PROPERTY_CONTACT_EXTENSION,                      CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_extension},
+};
+
+const property_info_s __property_my_profile[] = {
+       {CTSVC_PROPERTY_MY_PROFILE_ID,                                  CTSVC_SEARCH_PROPERTY_ALL,      "my_profile_id"},
+       {CTSVC_PROPERTY_MY_PROFILE_DISPLAY_NAME,                CTSVC_SEARCH_PROPERTY_ALL,      NULL},  //dispaly_name, reverse_display_name
+       {CTSVC_PROPERTY_MY_PROFILE_ADDRESSBOOK_ID,              CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_id"},
+       {CTSVC_PROPERTY_MY_PROFILE_IMAGE_THUMBNAIL,     CTSVC_SEARCH_PROPERTY_ALL,      "image_thumbnail_path"},
+       {CTSVC_PROPERTY_MY_PROFILE_UID,                                 CTSVC_SEARCH_PROPERTY_ALL,      "uid"},
+       {CTSVC_PROPERTY_MY_PROFILE_CHANGED_TIME,                CTSVC_SEARCH_PROPERTY_ALL,      "changed_time"},
+       {CTSVC_PROPERTY_MY_PROFILE_NAME,                                        CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_name},
+       {CTSVC_PROPERTY_MY_PROFILE_COMPANY,                             CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_company},
+       {CTSVC_PROPERTY_MY_PROFILE_NOTE,                                        CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_note},
+       {CTSVC_PROPERTY_MY_PROFILE_NUMBER,                              CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_number},
+       {CTSVC_PROPERTY_MY_PROFILE_EMAIL,                               CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_email},
+       {CTSVC_PROPERTY_MY_PROFILE_EVENT,                               CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_event},
+       {CTSVC_PROPERTY_MY_PROFILE_MESSENGER,                   CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_messenger},
+       {CTSVC_PROPERTY_MY_PROFILE_ADDRESS,                             CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_address},
+       {CTSVC_PROPERTY_MY_PROFILE_URL,                                 CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_url},
+       {CTSVC_PROPERTY_MY_PROFILE_NICKNAME,                            CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_nickname},
+       {CTSVC_PROPERTY_MY_PROFILE_PROFILE,                             CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_profile},
+       {CTSVC_PROPERTY_MY_PROFILE_RELATIONSHIP,                CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_relationship},
+       {CTSVC_PROPERTY_MY_PROFILE_IMAGE,                               CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_image},
+       {CTSVC_PROPERTY_MY_PROFILE_EXTENSION,                   CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_extension},
+};
+
+#ifdef ENABLE_SIM_FEATURE
+const property_info_s __property_speeddial[] = {               // _contacts_speeddial
+       {CTSVC_PROPERTY_SPEEDDIAL_DIAL_NUMBER,          CTSVC_SEARCH_PROPERTY_ALL,      "speed_number"},
+       {CTSVC_PROPERTY_SPEEDDIAL_NUMBER_ID,                    CTSVC_SEARCH_PROPERTY_ALL,      "number_id"},
+       {CTSVC_PROPERTY_SPEEDDIAL_NUMBER,                       CTSVC_SEARCH_PROPERTY_ALL,      "number"},
+       {CTSVC_PROPERTY_SPEEDDIAL_NUMBER_LABEL, CTSVC_SEARCH_PROPERTY_ALL,      "label"},
+       {CTSVC_PROPERTY_SPEEDDIAL_NUMBER_TYPE,          CTSVC_SEARCH_PROPERTY_ALL,      "type"},
+       {CTSVC_PROPERTY_SPEEDDIAL_PERSON_ID,                    CTSVC_SEARCH_PROPERTY_ALL,      "person_id"},
+       {CTSVC_PROPERTY_SPEEDDIAL_DISPLAY_NAME, CTSVC_SEARCH_PROPERTY_ALL,      NULL},          // display_name or reverse_display_name
+       {CTSVC_PROPERTY_SPEEDDIAL_IMAGE_THUMBNAIL,      CTSVC_SEARCH_PROPERTY_ALL,      "image_thumbnail_path"},
+       {CTSVC_PROPERTY_SPEEDDIAL_NORMALIZED_NUMBER,    CTSVC_SEARCH_PROPERTY_FILTER,   "normalized_number"},
+       {CTSVC_PROPERTY_SPEEDDIAL_CLEANED_NUMBER,       CTSVC_SEARCH_PROPERTY_FILTER,   "cleaned_number"},
+       {CTSVC_PROPERTY_SPEEDDIAL_NUMBER_FILTER,        CTSVC_SEARCH_PROPERTY_FILTER,   "minmatch"},
+};
+#endif // ENABLE_SIM_FEATURE
+
+#ifdef ENABLE_LOG_FEATURE
+const property_info_s __property_phonelog[] = {                // _contacts_phone_log
+       {CTSVC_PROPERTY_PHONELOG_ID,                            CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_PHONELOG_PERSON_ID,             CTSVC_SEARCH_PROPERTY_ALL,      "person_id"},
+       {CTSVC_PROPERTY_PHONELOG_ADDRESS,               CTSVC_SEARCH_PROPERTY_ALL,      "number"},
+       {CTSVC_PROPERTY_PHONELOG_LOG_TIME,              CTSVC_SEARCH_PROPERTY_ALL,      "log_time"},
+       {CTSVC_PROPERTY_PHONELOG_LOG_TYPE,              CTSVC_SEARCH_PROPERTY_ALL,      "log_type"},
+       {CTSVC_PROPERTY_PHONELOG_EXTRA_DATA1,   CTSVC_SEARCH_PROPERTY_ALL,      "data1"},               // duration
+       {CTSVC_PROPERTY_PHONELOG_EXTRA_DATA2,   CTSVC_SEARCH_PROPERTY_ALL,      "data2"},               // short message, email subject
+       {CTSVC_PROPERTY_PHONELOG_NORMALIZED_ADDRESS,    CTSVC_SEARCH_PROPERTY_FILTER,   "normal_num"},
+       {CTSVC_PROPERTY_PHONELOG_CLEANED_ADDRESS, CTSVC_SEARCH_PROPERTY_FILTER, "clean_num"},
+       {CTSVC_PROPERTY_PHONELOG_ADDRESS_FILTER, CTSVC_SEARCH_PROPERTY_FILTER, "minmatch"},
+       {CTSVC_PROPERTY_PHONELOG_SIM_SLOT_NO,                   CTSVC_SEARCH_PROPERTY_ALL, "sim_id"},
+};
+#endif // ENABLE_LOG_FEATURE
+
+#if 0
+const property_info_s __property_updated_info[] = {
+       {CTSVC_PROPERTY_UPDATE_INFO_ID,                                 CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_UPDATE_INFO_ADDRESSBOOK_ID, CTSVC_SEARCH_PROPERTY_ALL,  "addressbook_id"},
+       {CTSVC_PROPERTY_UPDATE_INFO_TYPE,                       CTSVC_SEARCH_PROPERTY_ALL,      "type"},
+       {CTSVC_PROPERTY_UPDATE_INFO_VERSION,            CTSVC_SEARCH_PROPERTY_ALL,      "version"},
+       {CTSVC_PROPERTY_UPDATE_INFO_IMAGE_CHANGED,      CTSVC_SEARCH_PROPERTY_ALL,      "image_changed"},
+       {CTSVC_PROPERTY_UPDATE_INFO_LAST_CHANGED_TYPE,  CTSVC_SEARCH_PROPERTY_ALL,      "is_deleted"},
+};
+
+const property_info_s __property_grouprel_updated_info[] = {
+       {CTSVC_PROPERTY_GROUP_ID,                               CTSVC_SEARCH_PROPERTY_ALL,      "group_id"},
+       {CTSVC_PROPERTY_CONTACT_ID,                     CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_ADDRESSBOOK_ID,         CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_id"},
+       {CTSVC_PROPERTY_UPDATE_INFO_TYPE,       CTSVC_SEARCH_PROPERTY_ALL,      "type"},
+       {CTSVC_PROPERTY_UPDATE_INFO_VERSION,    CTSVC_SEARCH_PROPERTY_ALL,      "version"},
+};
+#endif
+
+// search properties ///////////////////////////////////////////////////////////////////////////////////////////////////
+const property_info_s __property_person_contact[] = {          // _contacts_person_contact
+       {CTSVC_PROPERTY_PERSON_ID,                                              CTSVC_SEARCH_PROPERTY_ALL,      "person_id"},
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME,                    CTSVC_SEARCH_PROPERTY_ALL,      NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX,              CTSVC_SEARCH_PROPERTY_PROJECTION,       NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID,              CTSVC_SEARCH_PROPERTY_PROJECTION,       "name_contact_id"},
+       {CTSVC_PROPERTY_PERSON_RINGTONE,                                CTSVC_SEARCH_PROPERTY_PROJECTION,       "ringtone_path"},
+       {CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,         CTSVC_SEARCH_PROPERTY_PROJECTION,       "image_thumbnail_path"},
+       {CTSVC_PROPERTY_PERSON_VIBRATION,                               CTSVC_SEARCH_PROPERTY_PROJECTION,       "vibration"},
+       {CTSVC_PROPERTY_PERSON_MESSAGE_ALERT,           CTSVC_SEARCH_PROPERTY_PROJECTION,       "message_alert"},
+       {CTSVC_PROPERTY_PERSON_STATUS,                          CTSVC_SEARCH_PROPERTY_PROJECTION,       "status"},
+       {CTSVC_PROPERTY_PERSON_IS_FAVORITE,                     CTSVC_SEARCH_PROPERTY_ALL,      "is_favorite"},
+       {CTSVC_PROPERTY_PERSON_LINK_COUNT,                              CTSVC_SEARCH_PROPERTY_PROJECTION,       "link_count"},
+       {CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS,         CTSVC_SEARCH_PROPERTY_PROJECTION,       "addressbook_ids"},
+       {CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER,                 CTSVC_SEARCH_PROPERTY_ALL,      "has_phonenumber"},
+       {CTSVC_PROPERTY_PERSON_HAS_EMAIL,                               CTSVC_SEARCH_PROPERTY_ALL,      "has_email"},
+       // contact
+       {CTSVC_PROPERTY_CONTACT_ID,                                             CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,                 CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_id"},
+       // addressbook
+       {CTSVC_PROPERTY_ADDRESSBOOK_NAME,                               CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_name"},
+       {CTSVC_PROPERTY_ADDRESSBOOK_MODE,                               CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_mode"},
+};
+
+const property_info_s __property_person_number[] = {           // _contacts_person_number
+       {CTSVC_PROPERTY_PERSON_ID,                                              CTSVC_SEARCH_PROPERTY_ALL,      "person_id"},
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME,                    CTSVC_SEARCH_PROPERTY_ALL,      NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX,              CTSVC_SEARCH_PROPERTY_PROJECTION,       NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID,              CTSVC_SEARCH_PROPERTY_PROJECTION,       "name_contact_id"},
+       {CTSVC_PROPERTY_PERSON_RINGTONE,                                CTSVC_SEARCH_PROPERTY_PROJECTION,       "ringtone_path"},
+       {CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,         CTSVC_SEARCH_PROPERTY_PROJECTION,       "image_thumbnail_path"},
+       {CTSVC_PROPERTY_PERSON_VIBRATION,                               CTSVC_SEARCH_PROPERTY_PROJECTION,       "vibration"},
+       {CTSVC_PROPERTY_PERSON_MESSAGE_ALERT,           CTSVC_SEARCH_PROPERTY_PROJECTION,       "message_alert"},
+       {CTSVC_PROPERTY_PERSON_IS_FAVORITE,                     CTSVC_SEARCH_PROPERTY_ALL,      "is_favorite"},
+       {CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER,                 CTSVC_SEARCH_PROPERTY_ALL,      "has_phonenumber"},
+       {CTSVC_PROPERTY_PERSON_HAS_EMAIL,                               CTSVC_SEARCH_PROPERTY_ALL,      "has_email"},
+       // number
+       {CTSVC_PROPERTY_NUMBER_ID,                                              CTSVC_SEARCH_PROPERTY_ALL,      "number_id"},
+       {CTSVC_PROPERTY_DATA_IS_PRIMARY_DEFAULT,                CTSVC_SEARCH_PROPERTY_ALL,      "is_primary_default"},
+       {CTSVC_PROPERTY_NUMBER_TYPE,                                    CTSVC_SEARCH_PROPERTY_PROJECTION,       "type"},
+       {CTSVC_PROPERTY_NUMBER_LABEL,                                   CTSVC_SEARCH_PROPERTY_PROJECTION,       "label"},
+       {CTSVC_PROPERTY_NUMBER_NUMBER,                          CTSVC_SEARCH_PROPERTY_ALL,      "number"},
+       {CTSVC_PROPERTY_NUMBER_NUMBER_FILTER,                   CTSVC_SEARCH_PROPERTY_FILTER,   "minmatch"},
+       {CTSVC_PROPERTY_NUMBER_NORMALIZED_NUMBER,       CTSVC_SEARCH_PROPERTY_FILTER,   "normalized_number"},
+       {CTSVC_PROPERTY_NUMBER_CLEANED_NUMBER,  CTSVC_SEARCH_PROPERTY_FILTER,   "cleaned_number"},
+};
+
+const property_info_s __property_person_email[] = {    // _contacts_person_email
+       {CTSVC_PROPERTY_PERSON_ID,                                              CTSVC_SEARCH_PROPERTY_ALL,      "person_id"},
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME,                    CTSVC_SEARCH_PROPERTY_ALL,      NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX,              CTSVC_SEARCH_PROPERTY_PROJECTION,       NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID,              CTSVC_SEARCH_PROPERTY_PROJECTION,       "name_contact_id"},
+       {CTSVC_PROPERTY_PERSON_RINGTONE,                                CTSVC_SEARCH_PROPERTY_PROJECTION,       "ringtone_path"},
+       {CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,         CTSVC_SEARCH_PROPERTY_PROJECTION,       "image_thumbnail_path"},
+       {CTSVC_PROPERTY_PERSON_VIBRATION,                               CTSVC_SEARCH_PROPERTY_PROJECTION,       "vibration"},
+       {CTSVC_PROPERTY_PERSON_MESSAGE_ALERT,           CTSVC_SEARCH_PROPERTY_PROJECTION,       "message_alert"},
+       {CTSVC_PROPERTY_PERSON_IS_FAVORITE,                     CTSVC_SEARCH_PROPERTY_ALL,      "is_favorite"},
+       {CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER,                 CTSVC_SEARCH_PROPERTY_ALL,      "has_phonenumber"},
+       {CTSVC_PROPERTY_PERSON_HAS_EMAIL,                               CTSVC_SEARCH_PROPERTY_ALL,      "has_email"},
+       // email
+       {CTSVC_PROPERTY_EMAIL_ID,                                               CTSVC_SEARCH_PROPERTY_ALL,      "email_id"},
+       {CTSVC_PROPERTY_EMAIL_TYPE,                                     CTSVC_SEARCH_PROPERTY_PROJECTION,       "type"},
+       {CTSVC_PROPERTY_EMAIL_LABEL,                                    CTSVC_SEARCH_PROPERTY_PROJECTION,       "label"},
+       {CTSVC_PROPERTY_DATA_IS_PRIMARY_DEFAULT,                CTSVC_SEARCH_PROPERTY_ALL,      "is_primary_default"},
+       {CTSVC_PROPERTY_EMAIL_EMAIL,                                    CTSVC_SEARCH_PROPERTY_ALL,      "email"},
+};
+
+const property_info_s __property_person_grouprel[] = { // _contacts_person_grouprel
+       {CTSVC_PROPERTY_PERSON_ID,                                              CTSVC_SEARCH_PROPERTY_ALL,      "person_id"},
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME,                    CTSVC_SEARCH_PROPERTY_ALL,      NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX,              CTSVC_SEARCH_PROPERTY_PROJECTION,       NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID,              CTSVC_SEARCH_PROPERTY_PROJECTION,       "name_contact_id"},
+       {CTSVC_PROPERTY_PERSON_RINGTONE,                                CTSVC_SEARCH_PROPERTY_PROJECTION,       "ringtone_path"},
+       {CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,         CTSVC_SEARCH_PROPERTY_PROJECTION,       "image_thumbnail_path"},
+       {CTSVC_PROPERTY_PERSON_VIBRATION,                               CTSVC_SEARCH_PROPERTY_PROJECTION,       "vibration"},
+       {CTSVC_PROPERTY_PERSON_MESSAGE_ALERT,           CTSVC_SEARCH_PROPERTY_PROJECTION,       "message_alert"},
+       {CTSVC_PROPERTY_PERSON_STATUS,                                  CTSVC_SEARCH_PROPERTY_PROJECTION,       "status"},
+       {CTSVC_PROPERTY_PERSON_IS_FAVORITE,                     CTSVC_SEARCH_PROPERTY_ALL,      "is_favorite"},
+       {CTSVC_PROPERTY_PERSON_LINK_COUNT,                              CTSVC_SEARCH_PROPERTY_PROJECTION,       "link_count"},
+       {CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS,         CTSVC_SEARCH_PROPERTY_PROJECTION,       "addressbook_ids"},
+       {CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER,                 CTSVC_SEARCH_PROPERTY_ALL,      "has_phonenumber"},
+       {CTSVC_PROPERTY_PERSON_HAS_EMAIL,                               CTSVC_SEARCH_PROPERTY_ALL,      "has_email"},
+       // contacts
+       {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,                         CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_id"},
+       // group relation
+       {CTSVC_PROPERTY_GROUP_RELATION_GROUP_ID,                        CTSVC_SEARCH_PROPERTY_ALL,      "group_id"},
+       {CTSVC_PROPERTY_GROUP_RELATION_CONTACT_ID,                      CTSVC_SEARCH_PROPERTY_PROJECTION,       "contact_id"},
+       // addressbook
+       {CTSVC_PROPERTY_ADDRESSBOOK_NAME,                               CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_name"},
+       {CTSVC_PROPERTY_ADDRESSBOOK_MODE,                               CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_mode"},
+};
+
+const property_info_s __property_person_group_assigned[] = {   // _contacts_person_group_assigned
+       {CTSVC_PROPERTY_PERSON_ID,                                              CTSVC_SEARCH_PROPERTY_ALL,      "person_id"},
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME,                    CTSVC_SEARCH_PROPERTY_ALL,      NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX,              CTSVC_SEARCH_PROPERTY_PROJECTION,       NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID,              CTSVC_SEARCH_PROPERTY_PROJECTION,       "name_contact_id"},
+       {CTSVC_PROPERTY_PERSON_RINGTONE,                                CTSVC_SEARCH_PROPERTY_PROJECTION,       "ringtone_path"},
+       {CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,         CTSVC_SEARCH_PROPERTY_PROJECTION,       "image_thumbnail_path"},
+       {CTSVC_PROPERTY_PERSON_VIBRATION,                               CTSVC_SEARCH_PROPERTY_PROJECTION,       "vibration"},
+       {CTSVC_PROPERTY_PERSON_MESSAGE_ALERT,           CTSVC_SEARCH_PROPERTY_PROJECTION,       "message_alert"},
+       {CTSVC_PROPERTY_PERSON_STATUS,                                  CTSVC_SEARCH_PROPERTY_PROJECTION,       "status"},
+       {CTSVC_PROPERTY_PERSON_IS_FAVORITE,                     CTSVC_SEARCH_PROPERTY_ALL,      "is_favorite"},
+       {CTSVC_PROPERTY_PERSON_LINK_COUNT,                              CTSVC_SEARCH_PROPERTY_PROJECTION,       "link_count"},
+       {CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS,         CTSVC_SEARCH_PROPERTY_PROJECTION,       "addressbook_ids"},
+       {CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER,                 CTSVC_SEARCH_PROPERTY_ALL,      "has_phonenumber"},
+       {CTSVC_PROPERTY_PERSON_HAS_EMAIL,                               CTSVC_SEARCH_PROPERTY_ALL,      "has_email"},
+       // contacts
+       {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,                         CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_id"},
+       // group relation
+       {CTSVC_PROPERTY_GROUP_RELATION_GROUP_ID,                        CTSVC_SEARCH_PROPERTY_ALL,      "group_id"},
+       {CTSVC_PROPERTY_GROUP_RELATION_CONTACT_ID,                      CTSVC_SEARCH_PROPERTY_PROJECTION,       "contact_id"},
+       // addressbook
+       {CTSVC_PROPERTY_ADDRESSBOOK_MODE,                               CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_mode"},
+};
+
+const property_info_s __property_person_group_not_assigned[] = {       // _contacts_person_group_not_assigned
+       {CTSVC_PROPERTY_PERSON_ID,                                              CTSVC_SEARCH_PROPERTY_ALL,      "person_id"},
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME,                    CTSVC_SEARCH_PROPERTY_ALL,      NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX,              CTSVC_SEARCH_PROPERTY_PROJECTION,       NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID,              CTSVC_SEARCH_PROPERTY_PROJECTION,       "name_contact_id"},
+       {CTSVC_PROPERTY_PERSON_RINGTONE,                                CTSVC_SEARCH_PROPERTY_PROJECTION,       "ringtone_path"},
+       {CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,         CTSVC_SEARCH_PROPERTY_PROJECTION,       "image_thumbnail_path"},
+       {CTSVC_PROPERTY_PERSON_VIBRATION,                               CTSVC_SEARCH_PROPERTY_PROJECTION,       "vibration"},
+       {CTSVC_PROPERTY_PERSON_MESSAGE_ALERT,           CTSVC_SEARCH_PROPERTY_PROJECTION,       "message_alert"},
+       {CTSVC_PROPERTY_PERSON_STATUS,                                  CTSVC_SEARCH_PROPERTY_PROJECTION,       "status"},
+       {CTSVC_PROPERTY_PERSON_IS_FAVORITE,                     CTSVC_SEARCH_PROPERTY_ALL,      "is_favorite"},
+       {CTSVC_PROPERTY_PERSON_LINK_COUNT,                              CTSVC_SEARCH_PROPERTY_PROJECTION,       "link_count"},
+       {CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS,         CTSVC_SEARCH_PROPERTY_PROJECTION,       "addressbook_ids"},
+       {CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER,                 CTSVC_SEARCH_PROPERTY_ALL,      "has_phonenumber"},
+       {CTSVC_PROPERTY_PERSON_HAS_EMAIL,                               CTSVC_SEARCH_PROPERTY_ALL,      "has_email"},
+       // contacts
+       {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,                 CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_id"},
+       {CTSVC_PROPERTY_CONTACT_ID,                                                     CTSVC_SEARCH_PROPERTY_PROJECTION,       "contact_id"},
+       // addressbook
+       {CTSVC_PROPERTY_ADDRESSBOOK_MODE,                               CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_mode"},
+};
+
+#ifdef ENABLE_LOG_FEATURE
+const property_info_s __property_person_phonelog[] = { // _contacts_person_phone_log
+       {CTSVC_PROPERTY_PERSON_ID,                                              CTSVC_SEARCH_PROPERTY_ALL,      "id"},
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME,                    CTSVC_SEARCH_PROPERTY_ALL,      NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,         CTSVC_SEARCH_PROPERTY_PROJECTION,       "image_thumbnail_path"},
+       // phonelog
+       {CTSVC_PROPERTY_PHONELOG_ID,                            CTSVC_SEARCH_PROPERTY_ALL,      "phonelog_id"},
+       {CTSVC_PROPERTY_PHONELOG_ADDRESS,                       CTSVC_SEARCH_PROPERTY_ALL,      "address"},
+       {CTSVC_PROPERTY_DATA_DATA1,                                     CTSVC_SEARCH_PROPERTY_PROJECTION,       "address_type"},
+       {CTSVC_PROPERTY_PHONELOG_LOG_TIME,                      CTSVC_SEARCH_PROPERTY_ALL,      "log_time"},
+       {CTSVC_PROPERTY_PHONELOG_LOG_TYPE,                      CTSVC_SEARCH_PROPERTY_ALL,      "log_type"},
+       {CTSVC_PROPERTY_PHONELOG_EXTRA_DATA1,           CTSVC_SEARCH_PROPERTY_PROJECTION,       "data1"},               // duration
+       {CTSVC_PROPERTY_PHONELOG_EXTRA_DATA2,           CTSVC_SEARCH_PROPERTY_PROJECTION,       "data2"},               // message_id
+       {CTSVC_PROPERTY_PHONELOG_NORMALIZED_ADDRESS,    CTSVC_SEARCH_PROPERTY_FILTER,   "normal_num"},
+       {CTSVC_PROPERTY_PHONELOG_CLEANED_ADDRESS,       CTSVC_SEARCH_PROPERTY_FILTER,   "clean_num"},
+       {CTSVC_PROPERTY_PHONELOG_ADDRESS_FILTER,        CTSVC_SEARCH_PROPERTY_FILTER,   "minmatch"},
+       {CTSVC_PROPERTY_PHONELOG_SIM_SLOT_NO, CTSVC_SEARCH_PROPERTY_ALL, "sim_id"},
+};
+#endif // ENABLE_LOG_FEATURE
+
+const property_info_s __property_person_usage[] = {    // _contacts_person_usage
+       {CTSVC_PROPERTY_PERSON_ID,                                              CTSVC_SEARCH_PROPERTY_ALL,      "person_id"},
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME,                    CTSVC_SEARCH_PROPERTY_ALL,      NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX,                              CTSVC_SEARCH_PROPERTY_PROJECTION,       NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID,              CTSVC_SEARCH_PROPERTY_PROJECTION,       "name_contact_id"},
+       {CTSVC_PROPERTY_PERSON_RINGTONE,                                CTSVC_SEARCH_PROPERTY_PROJECTION,       "ringtone_path"},
+       {CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL,         CTSVC_SEARCH_PROPERTY_PROJECTION,       "image_thumbnail_path"},
+       {CTSVC_PROPERTY_PERSON_VIBRATION,                               CTSVC_SEARCH_PROPERTY_PROJECTION,       "vibration"},
+       {CTSVC_PROPERTY_PERSON_MESSAGE_ALERT,           CTSVC_SEARCH_PROPERTY_PROJECTION,       "message_alert"},
+       {CTSVC_PROPERTY_PERSON_IS_FAVORITE,                     CTSVC_SEARCH_PROPERTY_ALL,      "is_favorite"},
+       {CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER,                 CTSVC_SEARCH_PROPERTY_ALL,      "has_phonenumber"},
+       {CTSVC_PROPERTY_PERSON_HAS_EMAIL,                               CTSVC_SEARCH_PROPERTY_ALL,      "has_email"},
+       // contact_stat
+       {CTSVC_PROPERTY_PERSON_USAGE_TYPE,                              CTSVC_SEARCH_PROPERTY_ALL,      "usage_type"},
+       {CTSVC_PROPERTY_PERSON_TIMES_USED,                              CTSVC_SEARCH_PROPERTY_ALL,      "times_used"},
+};
+
+const property_info_s __property_contact_number[] = {          // _contacts_contact_number
+       {CTSVC_PROPERTY_CONTACT_ID,                                     CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_CONTACT_DISPLAY_NAME,           CTSVC_SEARCH_PROPERTY_ALL,      NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID,                 CTSVC_SEARCH_PROPERTY_PROJECTION,       "display_name_source"},
+       {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,         CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_id"},
+       {CTSVC_PROPERTY_CONTACT_PERSON_ID,                      CTSVC_SEARCH_PROPERTY_ALL,      "person_id"},
+       {CTSVC_PROPERTY_CONTACT_RINGTONE,                       CTSVC_SEARCH_PROPERTY_PROJECTION,       "ringtone_path"},
+       {CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL,        CTSVC_SEARCH_PROPERTY_PROJECTION,       "image_thumbnail_path"},
+       // number
+       {CTSVC_PROPERTY_NUMBER_ID,                                      CTSVC_SEARCH_PROPERTY_ALL,      "number_id"},
+       {CTSVC_PROPERTY_NUMBER_TYPE,                            CTSVC_SEARCH_PROPERTY_PROJECTION,       "type"},
+       {CTSVC_PROPERTY_NUMBER_LABEL,                           CTSVC_SEARCH_PROPERTY_PROJECTION,       "label"},
+       {CTSVC_PROPERTY_NUMBER_IS_DEFAULT,                      CTSVC_SEARCH_PROPERTY_ALL,      "is_default"},
+       {CTSVC_PROPERTY_NUMBER_NUMBER,                          CTSVC_SEARCH_PROPERTY_ALL,      "number"},
+       {CTSVC_PROPERTY_NUMBER_NUMBER_FILTER,           CTSVC_SEARCH_PROPERTY_FILTER,   "minmatch"},
+       {CTSVC_PROPERTY_NUMBER_NORMALIZED_NUMBER,       CTSVC_SEARCH_PROPERTY_FILTER,   "normalized_number"},
+       {CTSVC_PROPERTY_NUMBER_CLEANED_NUMBER,  CTSVC_SEARCH_PROPERTY_FILTER,   "cleaned_number"},
+};
+
+const property_info_s __property_contact_email[] = {           // _contacts_contact_email
+       {CTSVC_PROPERTY_CONTACT_ID,                                     CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_CONTACT_DISPLAY_NAME,           CTSVC_SEARCH_PROPERTY_ALL,      NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID,                 CTSVC_SEARCH_PROPERTY_ALL,      "display_name_source"},
+       {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,         CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_id"},
+       {CTSVC_PROPERTY_CONTACT_PERSON_ID,                      CTSVC_SEARCH_PROPERTY_ALL,      "person_id"},
+       {CTSVC_PROPERTY_CONTACT_RINGTONE,                       CTSVC_SEARCH_PROPERTY_PROJECTION,       "ringtone_path"},
+       {CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL,                CTSVC_SEARCH_PROPERTY_PROJECTION,       "image_thumbnail_path"},
+       // email
+       {CTSVC_PROPERTY_EMAIL_ID,                                               CTSVC_SEARCH_PROPERTY_ALL,      "email_id"},
+       {CTSVC_PROPERTY_EMAIL_TYPE,                                             CTSVC_SEARCH_PROPERTY_PROJECTION,       "type"},
+       {CTSVC_PROPERTY_EMAIL_LABEL,                                    CTSVC_SEARCH_PROPERTY_PROJECTION,       "label"},
+       {CTSVC_PROPERTY_EMAIL_IS_DEFAULT,                               CTSVC_SEARCH_PROPERTY_ALL,      "is_default"},
+       {CTSVC_PROPERTY_EMAIL_EMAIL,                                    CTSVC_SEARCH_PROPERTY_ALL,      "email"},
+};
+
+const property_info_s __property_contact_grouprel[] = {                // _contacts_contact_grouprel
+       {CTSVC_PROPERTY_CONTACT_ID,                                     CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_CONTACT_DISPLAY_NAME,           CTSVC_SEARCH_PROPERTY_ALL,      NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID,                 CTSVC_SEARCH_PROPERTY_PROJECTION,       "display_name_source"},
+       {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,         CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_id"},
+       {CTSVC_PROPERTY_CONTACT_PERSON_ID,                      CTSVC_SEARCH_PROPERTY_ALL,      "person_id"},
+       {CTSVC_PROPERTY_CONTACT_RINGTONE,                       CTSVC_SEARCH_PROPERTY_PROJECTION,       "ringtone_path"},
+       {CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL,                CTSVC_SEARCH_PROPERTY_PROJECTION,       "image_thumbnail_path"},
+       // group relation
+       {CTSVC_PROPERTY_GROUP_RELATION_GROUP_ID,                CTSVC_SEARCH_PROPERTY_ALL,      "group_id"},
+       {CTSVC_PROPERTY_GROUP_RELATION_GROUP_NAME,              CTSVC_SEARCH_PROPERTY_PROJECTION,       "group_name"},
+};
+
+const property_info_s __property_contact_activity[] = {                // _contacts_contact_activity
+       {CTSVC_PROPERTY_CONTACT_ID,                                     CTSVC_SEARCH_PROPERTY_ALL,      "contact_id"},
+       {CTSVC_PROPERTY_CONTACT_DISPLAY_NAME,           CTSVC_SEARCH_PROPERTY_ALL,      NULL},  // "dispaly_name" or "reverse_dispaly_name"
+       {CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID,                 CTSVC_SEARCH_PROPERTY_PROJECTION,       "display_name_source"},
+       {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID,         CTSVC_SEARCH_PROPERTY_ALL,      "addressbook_id"},
+       {CTSVC_PROPERTY_CONTACT_PERSON_ID,                      CTSVC_SEARCH_PROPERTY_ALL,      "person_id"},
+       {CTSVC_PROPERTY_CONTACT_RINGTONE,                       CTSVC_SEARCH_PROPERTY_PROJECTION,       "ringtone_path"},
+       {CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL,                CTSVC_SEARCH_PROPERTY_PROJECTION,       "image_thumbnail_path"},
+       {CTSVC_PROPERTY_ACTIVITY_ID,                            CTSVC_SEARCH_PROPERTY_ALL,      "activity_id"},
+       {CTSVC_PROPERTY_ACTIVITY_SOURCE_NAME,           CTSVC_SEARCH_PROPERTY_ALL,      "source_name"},
+       {CTSVC_PROPERTY_ACTIVITY_STATUS,                        CTSVC_SEARCH_PROPERTY_PROJECTION,       "status"},
+       {CTSVC_PROPERTY_ACTIVITY_TIMESTAMP,             CTSVC_SEARCH_PROPERTY_ALL,      "timestamp"},
+       {CTSVC_PROPERTY_ACTIVITY_SERVICE_OPERATION, CTSVC_SEARCH_PROPERTY_ALL,  "service_operation"},
+       {CTSVC_PROPERTY_ACTIVITY_URI,                                   CTSVC_SEARCH_PROPERTY_ALL,      "uri"},
+       {CTSVC_PROPERTY_ADDRESSBOOK_ACCOUNT_ID,         CTSVC_SEARCH_PROPERTY_ALL,      "account_id"},
+};
+
+#ifdef ENABLE_LOG_FEATURE
+const property_info_s __property_phonelog_stat[] = {           //_contacts_phone_log_stat
+       {CTSVC_PROPERTY_PHONELOG_STAT_LOG_COUNT,                CTSVC_SEARCH_PROPERTY_PROJECTION,       "log_count"},
+       {CTSVC_PROPERTY_PHONELOG_STAT_LOG_TYPE,                 CTSVC_SEARCH_PROPERTY_ALL,      "log_type"},
+};
+#endif
+
+typedef struct {
+       char *view_uri;
+       ctsvc_record_type_e type;
+       property_info_s *properties;
+       unsigned int property_count;
+}view_uri_info_s;
+
+#define PTR_COUNT(X)   (void*)(X), sizeof(X)/sizeof(property_info_s)
+
+static const view_uri_info_s __tables[] = {
+       {CTSVC_VIEW_URI_ADDRESSBOOK,    CTSVC_RECORD_ADDRESSBOOK,               PTR_COUNT(__property_addressbook)},
+       {CTSVC_VIEW_URI_GROUP,                  CTSVC_RECORD_GROUP,                             PTR_COUNT(__property_group)},
+       {CTSVC_VIEW_URI_PERSON,                 CTSVC_RECORD_PERSON,                    PTR_COUNT(__property_person)},
+       {CTSVC_VIEW_URI_SIMPLE_CONTACT, CTSVC_RECORD_SIMPLE_CONTACT,    PTR_COUNT(__property_simple_contact)},
+       {CTSVC_VIEW_URI_CONTACT,                CTSVC_RECORD_CONTACT,                   PTR_COUNT(__property_contact)},
+       {CTSVC_VIEW_URI_MY_PROFILE,             CTSVC_RECORD_MY_PROFILE,                PTR_COUNT(__property_my_profile)},
+       {CTSVC_VIEW_URI_ACTIVITY,               CTSVC_RECORD_ACTIVITY,                  PTR_COUNT(__property_activity)},
+       {CTSVC_VIEW_URI_ACTIVITY_PHOTO, CTSVC_RECORD_ACTIVITY_PHOTO,    PTR_COUNT(__property_activity_photo)},
+#ifdef ENABLE_LOG_FEATURE
+       {CTSVC_VIEW_URI_PHONELOG,               CTSVC_RECORD_PHONELOG,                  PTR_COUNT(__property_phonelog)},
+#endif // ENABLE_LOG_FEATURE
+#ifdef ENABLE_SIM_FEATURE
+       {CTSVC_VIEW_URI_SPEEDDIAL,              CTSVC_RECORD_SPEEDDIAL,                 PTR_COUNT(__property_speeddial)},
+       {CTSVC_VIEW_URI_SDN,                    CTSVC_RECORD_SDN,                               PTR_COUNT(__property_sdn)},
+#endif // ENABLE_SIM_FEATURE
+
+       {CTSVC_VIEW_URI_NAME,                   CTSVC_RECORD_NAME,                              PTR_COUNT(__property_name)},
+       {CTSVC_VIEW_URI_COMPANY,                CTSVC_RECORD_COMPANY,                   PTR_COUNT(__property_company)},
+       {CTSVC_VIEW_URI_NUMBER,         CTSVC_RECORD_NUMBER,                    PTR_COUNT(__property_number)},
+       {CTSVC_VIEW_URI_EMAIL,                  CTSVC_RECORD_EMAIL,                             PTR_COUNT(__property_email)},
+       {CTSVC_VIEW_URI_URL,                    CTSVC_RECORD_URL,                               PTR_COUNT(__property_url)},
+       {CTSVC_VIEW_URI_ADDRESS,                CTSVC_RECORD_ADDRESS,                   PTR_COUNT(__property_address)},
+       {CTSVC_VIEW_URI_PROFILE,                CTSVC_RECORD_PROFILE,                   PTR_COUNT(__property_profile)},
+       {CTSVC_VIEW_URI_RELATIONSHIP,   CTSVC_RECORD_RELATIONSHIP,              PTR_COUNT(__property_relationship)},
+       {CTSVC_VIEW_URI_IMAGE,                  CTSVC_RECORD_IMAGE,                             PTR_COUNT(__property_image)},
+       {CTSVC_VIEW_URI_NOTE,                   CTSVC_RECORD_NOTE,                              PTR_COUNT(__property_note)},
+       {CTSVC_VIEW_URI_NICKNAME,               CTSVC_RECORD_NICKNAME,                  PTR_COUNT(__property_nickname)},
+       {CTSVC_VIEW_URI_EVENT,                  CTSVC_RECORD_EVENT,                             PTR_COUNT(__property_event)},
+       {CTSVC_VIEW_URI_MESSENGER,              CTSVC_RECORD_MESSENGER,                 PTR_COUNT(__property_messenger)},
+       {CTSVC_VIEW_URI_GROUP_RELATION, CTSVC_RECORD_GROUP_RELATION,    PTR_COUNT(__property_group_relation)},
+       {CTSVC_VIEW_URI_EXTENSION,                      CTSVC_RECORD_EXTENSION,                 PTR_COUNT(__property_extension)},
+
+       {CTSVC_VIEW_URI_GROUPS_UPDATED_INFO,  CTSVC_RECORD_UPDATED_INFO, NULL, 0},
+       {CTSVC_VIEW_URI_GROUPS_MEMBER_UPDATED_INFO,  CTSVC_RECORD_UPDATED_INFO, NULL, 0},
+       {CTSVC_VIEW_URI_CONTACTS_UPDATED_INFO, CTSVC_RECORD_UPDATED_INFO, NULL, 0},
+       {CTSVC_VIEW_URI_MY_PROFILE_UPDATED_INFO, CTSVC_RECORD_UPDATED_INFO,  NULL, 0},
+       {CTSVC_VIEW_URI_GROUPRELS_UPDATED_INFO, CTSVC_RECORD_RESULT, NULL, 0},
+
+       {CTSVC_VIEW_URI_READ_ONLY_PERSON_CONTACT,               CTSVC_RECORD_RESULT, PTR_COUNT(__property_person_contact)},
+       {CTSVC_VIEW_URI_READ_ONLY_PERSON_NUMBER,                CTSVC_RECORD_RESULT, PTR_COUNT(__property_person_number)},
+       {CTSVC_VIEW_URI_READ_ONLY_PERSON_EMAIL,         CTSVC_RECORD_RESULT, PTR_COUNT(__property_person_email)},
+       {CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP,         CTSVC_RECORD_RESULT, PTR_COUNT(__property_person_grouprel)},
+       {CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP_ASSIGNED,                CTSVC_RECORD_RESULT, PTR_COUNT(__property_person_group_assigned)},
+       {CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP_NOT_ASSIGNED,            CTSVC_RECORD_RESULT, PTR_COUNT(__property_person_group_not_assigned)},
+#ifdef ENABLE_LOG_FEATURE
+       {CTSVC_VIEW_URI_READ_ONLY_PERSON_PHONELOG,                              CTSVC_RECORD_RESULT, PTR_COUNT(__property_person_phonelog)},
+#endif // ENABLE_LOG_FEATURE
+       {CTSVC_VIEW_URI_READ_ONLY_PERSON_USAGE,                         CTSVC_RECORD_RESULT, PTR_COUNT(__property_person_usage)},
+
+       {CTSVC_VIEW_URI_READ_ONLY_CONTACT_NUMBER,                               CTSVC_RECORD_RESULT, PTR_COUNT(__property_contact_number)},
+       {CTSVC_VIEW_URI_READ_ONLY_CONTACT_EMAIL,                                CTSVC_RECORD_RESULT, PTR_COUNT(__property_contact_email)},
+       {CTSVC_VIEW_URI_READ_ONLY_CONTACT_GROUP,                                CTSVC_RECORD_RESULT, PTR_COUNT(__property_contact_grouprel)},
+       {CTSVC_VIEW_URI_READ_ONLY_CONTACT_ACTIVITY,                     CTSVC_RECORD_RESULT, PTR_COUNT(__property_contact_activity)},
+#ifdef ENABLE_LOG_FEATURE
+       {CTSVC_VIEW_URI_READ_ONLY_PHONELOG_STAT,                                CTSVC_RECORD_RESULT, PTR_COUNT(__property_phonelog_stat)},
+#endif // ENABLE_LOG_FEATURE
+};
+
+static GHashTable *__ctsvc_view_uri_hash = NULL;
+
+#ifndef _CONTACTS_IPC_SERVER           // native or client library
+static int __ctsvc_view_ref_count = 0;
+#endif
+
+void ctsvc_view_uri_init()
+{
+       int i;
+       int count;
+
+#ifndef _CONTACTS_IPC_SERVER           // native or client library
+       // it is called in mutex lock
+       __ctsvc_view_ref_count++;
+#endif
+
+       if (__ctsvc_view_uri_hash)
+               return;
+
+       __ctsvc_view_uri_hash = g_hash_table_new(g_str_hash, g_str_equal);
+
+       i = 0;
+       count = sizeof(__tables)/sizeof(view_uri_info_s);
+       for (i=0;i<count;i++)
+               g_hash_table_insert(__ctsvc_view_uri_hash, __tables[i].view_uri, GINT_TO_POINTER(&__tables[i]));
+}
+
+void ctsvc_view_uri_deinit()
+{
+#ifndef _CONTACTS_IPC_SERVER           // native or client library
+       // it is called in mutex lock
+       __ctsvc_view_ref_count--;
+       if (__ctsvc_view_ref_count != 0)
+               return;
+
+       if (NULL == __ctsvc_view_uri_hash) {
+               CTS_ERR("contacts-service is not initialized");
+               return;
+       }
+
+       g_hash_table_destroy(__ctsvc_view_uri_hash);
+       __ctsvc_view_uri_hash = NULL;
+#endif
+}
+
+ctsvc_record_type_e ctsvc_view_get_record_type(const char* view_uri)
+{
+       view_uri_info_s* view_uri_info = NULL;
+       ctsvc_record_type_e type = CTSVC_RECORD_INVALID;
+
+       if (NULL == __ctsvc_view_uri_hash) {
+               CTS_ERR("contacts-service is not initialized");
+               return type;
+       }
+
+       view_uri_info = g_hash_table_lookup(__ctsvc_view_uri_hash, view_uri);
+       if (view_uri_info)
+               type = view_uri_info->type;
+
+       return type;
+}
+
+const char* ctsvc_view_get_uri( const char* view_uri )
+{
+       view_uri_info_s* view_uri_info = NULL;
+
+       if (NULL == __ctsvc_view_uri_hash) {
+               CTS_ERR("contacts-service is not initialized");
+               return NULL;
+       }
+
+       view_uri_info = g_hash_table_lookup(__ctsvc_view_uri_hash, view_uri);
+       if (view_uri_info)
+               return view_uri_info->view_uri;
+
+       return NULL;
+}
+
+const property_info_s* ctsvc_view_get_all_property_infos(const char *view_uri, unsigned int *count)
+{
+       view_uri_info_s* view_uri_info = NULL;
+
+       if (NULL == __ctsvc_view_uri_hash) {
+               CTS_ERR("contacts-service is not initialized");
+               return NULL;
+       }
+
+       view_uri_info = g_hash_table_lookup(__ctsvc_view_uri_hash, view_uri);
+       if (view_uri_info) {
+               *count = view_uri_info->property_count;
+               return view_uri_info->properties;
+       }
+
+       return NULL;
+}
+
diff --git a/common/ctsvc_view.h b/common/ctsvc_view.h
new file mode 100644 (file)
index 0000000..0f6b876
--- /dev/null
@@ -0,0 +1,472 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 __TIZEN_SOCIAL_CTSVC_VIEW_H__
+#define __TIZEN_SOCIAL_CTSVC_VIEW_H__
+
+#include "ctsvc_struct.h"
+
+#define CTSVC_VIEW_URI_ADDRESSBOOK             "tizen.contacts_view.addressbook"
+#define CTSVC_VIEW_URI_GROUP                   "tizen.contacts_view.group"
+#define CTSVC_VIEW_URI_PERSON                  "tizen.contacts_view.person"
+#define CTSVC_VIEW_URI_SIMPLE_CONTACT  "tizen.contacts_view.simple_contact"
+#define CTSVC_VIEW_URI_CONTACT                 "tizen.contacts_view.contact"
+#define CTSVC_VIEW_URI_MY_PROFILE                      "tizen.contacts_view.my_profile"
+#define CTSVC_VIEW_URI_ACTIVITY                        "tizen.contacts_view.activity"
+#define CTSVC_VIEW_URI_ACTIVITY_PHOTO  "tizen.contacts_view.activity/photo"
+#define CTSVC_VIEW_URI_PHONELOG                        "tizen.contacts_view.phonelog"
+#define CTSVC_VIEW_URI_SPEEDDIAL               "tizen.contacts_view.speeddial"
+#define CTSVC_VIEW_URI_SDN                             "tizen.contacts_view.sdn"
+#define CTSVC_VIEW_URI_CONTACTS_UPDATED_INFO   "tizen.contacts_view.contacts_updated_info"
+#define CTSVC_VIEW_URI_MY_PROFILE_UPDATED_INFO "tizen.contacts_view.my_profile_updated_info"
+#define CTSVC_VIEW_URI_GROUPS_UPDATED_INFO             "tizen.contacts_view.groups_updated_info"
+#define CTSVC_VIEW_URI_GROUPS_MEMBER_UPDATED_INFO "tizen.contacts_view.groups_member_updated_info"
+#define CTSVC_VIEW_URI_GROUPRELS_UPDATED_INFO          "tizen.contacts_view.group_relations_updated_info"
+#define CTSVC_VIEW_URI_NAME                            "tizen.contacts_view.name"
+#define CTSVC_VIEW_URI_COMPANY                 "tizen.contacts_view.company"
+#define CTSVC_VIEW_URI_NUMBER                  "tizen.contacts_view.number"
+#define CTSVC_VIEW_URI_EMAIL                   "tizen.contacts_view.email"
+#define CTSVC_VIEW_URI_URL                             "tizen.contacts_view.url"
+#define CTSVC_VIEW_URI_ADDRESS                 "tizen.contacts_view.address"
+#define CTSVC_VIEW_URI_PROFILE                 "tizen.contacts_view.profile"
+#define CTSVC_VIEW_URI_RELATIONSHIP            "tizen.contacts_view.relationship"
+#define CTSVC_VIEW_URI_IMAGE                   "tizen.contacts_view.image"
+#define CTSVC_VIEW_URI_NOTE                            "tizen.contacts_view.note"
+#define CTSVC_VIEW_URI_NICKNAME                        "tizen.contacts_view.nickname"
+#define CTSVC_VIEW_URI_EVENT                   "tizen.contacts_view.event"
+#define CTSVC_VIEW_URI_MESSENGER               "tizen.contacts_view.messenger"
+#define CTSVC_VIEW_URI_GROUP_RELATION  "tizen.contacts_view.group_relation"
+#define CTSVC_VIEW_URI_EXTENSION                       "tizen.contacts_view.extension"
+
+#define CTSVC_VIEW_URI_READ_ONLY_PERSON_CONTACT                                        "tizen.contacts_view.person/simple_contact"
+#define CTSVC_VIEW_URI_READ_ONLY_PERSON_NUMBER                                 "tizen.contacts_view.person/simple_contact/number"
+#define CTSVC_VIEW_URI_READ_ONLY_PERSON_EMAIL                                  "tizen.contacts_view.person/simple_contact/email"
+
+#define CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP                                  "tizen.contacts_view.person/simple_contact/group"
+#define CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP_ASSIGNED         "tizen.contacts_view.person/simple_contact/group_assigned"
+#define CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP_NOT_ASSIGNED             "tizen.contacts_view.person/simple_contact/group_not_assigned"
+
+#define CTSVC_VIEW_URI_READ_ONLY_PERSON_PHONELOG                               "tizen.contacts_view.person/simple_contact/phonelog"
+#define CTSVC_VIEW_URI_READ_ONLY_PERSON_USAGE                                                  "tizen.contacts_view.person/usage"
+
+#define CTSVC_VIEW_URI_READ_ONLY_CONTACT_NUMBER                                                "tizen.contacts_view.simple_contact/number"
+#define CTSVC_VIEW_URI_READ_ONLY_CONTACT_EMAIL                                         "tizen.contacts_view.simple_contact/email"
+#define CTSVC_VIEW_URI_READ_ONLY_CONTACT_GROUP                                         "tizen.contacts_view.simple_contact/group"
+#define CTSVC_VIEW_URI_READ_ONLY_CONTACT_ACTIVITY                                      "tizen.contacts_view.simple_contact/activity"
+
+#define CTSVC_VIEW_URI_READ_ONLY_PHONELOG_STAT                                         "tizen.contacts_view.phonelog_stat"
+
+
+typedef enum
+{
+       CTSVC_PROPERTY_FLAG_PROJECTION = 0x00000001,
+       CTSVC_PROPERTY_FLAG_DIRTY = 0x00000002, // for dirty bit
+} contacts_property_flag_e;
+
+
+// for type check                                                                      // data_type mask 0x000FF000
+#define CTSVC_VIEW_DATA_TYPE_MASK             0x000F0000
+#define CTSVC_VIEW_DATA_TYPE_BOOL                0x00010000
+#define CTSVC_VIEW_DATA_TYPE_INT              0x00020000
+#define CTSVC_VIEW_DATA_TYPE_LLI              0x00030000
+#define CTSVC_VIEW_DATA_TYPE_STR              0x00040000
+#define CTSVC_VIEW_DATA_TYPE_DOUBLE           0x00050000
+#define CTSVC_VIEW_DATA_TYPE_REC              0x00060000
+#define CTSVC_VIEW_CHECK_DATA_TYPE(property_id,data_type) \
+       ((property_id&CTSVC_VIEW_DATA_TYPE_MASK) == data_type ? true : false)
+
+#define CTSVC_READ_WRITE_TYPE_MASK            0x0000F000
+#define CTSVC_READ_ONLY_PROPERTY                 0x00001000
+
+#define CTSVC_READ_ONLY_CHECK(property_id, data_type) \
+       ((property_id & CTSVC_READ_WRITE_TYPE_MASK) == data_type ? true : false)
+
+
+// for property                            //  0x0FF00000
+#define CTSVC_PROPERTY_MASK                      0x0FF00000
+
+#define CTSVC_PROPERTY_ADDRESSBOOK              0x00100000
+#define CTSVC_PROPERTY_GROUP                    0x00200000
+#define CTSVC_PROPERTY_PERSON                   0x00300000
+#define CTSVC_PROPERTY_ACTIVITY                                                0x00500000
+#define CTSVC_PROPERTY_DATA                                                    0x00600000
+#define CTSVC_PROPERTY_SPEEDDIAL                                               0x00700000
+#define CTSVC_PROPERTY_PHONELOG                                                0x00800000
+#define CTSVC_PROPERTY_UPDATE_INFO                                     0x00900000
+#define CTSVC_PROPERTY_SDN                                                             0x00A00000
+#define CTSVC_PROPERTY_PHONELOG_STAT                           0x00B00000
+
+#define CTSVC_PROPERTY_CONTACT                  0x01000000
+#define CTSVC_PROPERTY_NAME                     0x01100000
+#define CTSVC_PROPERTY_NUMBER                                                  0x01200000
+#define CTSVC_PROPERTY_EMAIL                                                   0x01300000
+#define CTSVC_PROPERTY_ADDRESS                                         0x01400000
+#define CTSVC_PROPERTY_URL                      0x01500000
+#define CTSVC_PROPERTY_EVENT                                                   0x01600000
+#define CTSVC_PROPERTY_GROUP_RELATION           0x01700000
+#define CTSVC_PROPERTY_RELATIONSHIP             0x01800000
+#define CTSVC_PROPERTY_COMPANY                                         0x01900000
+#define CTSVC_PROPERTY_NICKNAME                                                0x01A00000
+#define CTSVC_PROPERTY_MESSENGER                                               0x01B00000
+#define CTSVC_PROPERTY_NOTE                                                    0x01C00000
+#define CTSVC_PROPERTY_PROFILE                                         0x01D00000
+#define CTSVC_PROPERTY_IMAGE                                                   0x01E00000
+#define CTSVC_PROPERTY_EXTENSION                                               0x01F00000
+#define CTSVC_PROPERTY_MY_PROFILE                                      0x02000000
+#define CTSVC_PROPERTY_ACTIVITY_PHOTO                          0x02100000
+
+#define CTSVC_PROPERTY_CHECK(property_id,data_type) \
+       ((property_id & CTSVC_PROPERTY_MASK) == data_type ? true : false)
+
+#define CTSVC_SEARCH_PROPERTY_MASK              0xF0000000
+#define CTSVC_SEARCH_PROPERTY_NONE                           0x10000000
+#define CTSVC_SEARCH_PROPERTY_FILTER            0x20000000
+#define CTSVC_SEARCH_PROPERTY_PROJECTION        0x30000000
+#define CTSVC_SEARCH_PROPERTY_ALL               0x40000000
+#define CTSVC_SEARCH_PROPERTY_CHECK(property_id,data_type) \
+       ((property_id & CTSVC_SEARCH_PROPERTY_MASK) == data_type ? true : false)
+
+typedef enum {
+       // addressbook
+       CTSVC_PROPERTY_ADDRESSBOOK_ID = (CTSVC_PROPERTY_ADDRESSBOOK | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_ADDRESSBOOK_ACCOUNT_ID = (CTSVC_PROPERTY_ADDRESSBOOK | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_ADDRESSBOOK_NAME = (CTSVC_PROPERTY_ADDRESSBOOK | CTSVC_VIEW_DATA_TYPE_STR) +2,
+       CTSVC_PROPERTY_ADDRESSBOOK_MODE = (CTSVC_PROPERTY_ADDRESSBOOK | CTSVC_VIEW_DATA_TYPE_INT) +3,
+
+       // group
+       CTSVC_PROPERTY_GROUP_ID = (CTSVC_PROPERTY_GROUP | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_GROUP_ADDRESSBOOK_ID = (CTSVC_PROPERTY_GROUP | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_GROUP_NAME = (CTSVC_PROPERTY_GROUP | CTSVC_VIEW_DATA_TYPE_STR) +2,
+       CTSVC_PROPERTY_GROUP_RINGTONE = (CTSVC_PROPERTY_GROUP | CTSVC_VIEW_DATA_TYPE_STR) +3,
+       CTSVC_PROPERTY_GROUP_IMAGE = (CTSVC_PROPERTY_GROUP | CTSVC_VIEW_DATA_TYPE_STR) +4,
+       CTSVC_PROPERTY_GROUP_VIBRATION = (CTSVC_PROPERTY_GROUP | CTSVC_VIEW_DATA_TYPE_STR) +5,
+       CTSVC_PROPERTY_GROUP_EXTRA_DATA = (CTSVC_PROPERTY_GROUP | CTSVC_VIEW_DATA_TYPE_STR) +6,
+       CTSVC_PROPERTY_GROUP_IS_READ_ONLY = (CTSVC_PROPERTY_GROUP | CTSVC_VIEW_DATA_TYPE_BOOL) +7,
+       CTSVC_PROPERTY_GROUP_MESSAGE_ALERT = (CTSVC_PROPERTY_GROUP | CTSVC_VIEW_DATA_TYPE_STR) +8,
+
+       // person
+       CTSVC_PROPERTY_PERSON_ID = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_PERSON_DISPLAY_NAME = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +1,
+       CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_INT ) +2,
+       CTSVC_PROPERTY_PERSON_RINGTONE = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_STR) +3,
+       CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +4,
+       CTSVC_PROPERTY_PERSON_VIBRATION = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_STR) +5,
+       CTSVC_PROPERTY_PERSON_IS_FAVORITE = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_BOOL) +6,
+       CTSVC_PROPERTY_PERSON_FAVORITE_PRIORITY = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_DOUBLE | CTSVC_READ_ONLY_PROPERTY) +7,
+       CTSVC_PROPERTY_PERSON_LINK_COUNT = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY) +8,
+       CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +9,
+       CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_BOOL | CTSVC_READ_ONLY_PROPERTY) +10,
+       CTSVC_PROPERTY_PERSON_HAS_EMAIL = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_BOOL | CTSVC_READ_ONLY_PROPERTY) +11,
+       CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +12,
+       CTSVC_PROPERTY_PERSON_STATUS = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +13,
+       CTSVC_PROPERTY_PERSON_MESSAGE_ALERT = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_STR) +14,
+
+       // person-stat
+       CTSVC_PROPERTY_PERSON_USAGE_TYPE = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_INT) +100,
+       CTSVC_PROPERTY_PERSON_TIMES_USED = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_INT) +101,
+
+       // simple contact : read only
+       // contact
+       CTSVC_PROPERTY_CONTACT_ID = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_CONTACT_DISPLAY_NAME = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +1,
+       CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY) +2,
+       CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_INT) +3,
+       CTSVC_PROPERTY_CONTACT_RINGTONE = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_STR) +4,
+       CTSVC_PROPERTY_CONTACT_IMAGE = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_REC) +5,
+       CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +6,
+       CTSVC_PROPERTY_CONTACT_IS_FAVORITE = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_BOOL) +7,
+       CTSVC_PROPERTY_CONTACT_HAS_PHONENUMBER = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_BOOL | CTSVC_READ_ONLY_PROPERTY) +8,
+       CTSVC_PROPERTY_CONTACT_HAS_EMAIL = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_BOOL | CTSVC_READ_ONLY_PROPERTY) +9,
+       CTSVC_PROPERTY_CONTACT_PERSON_ID = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_INT) +10,
+       CTSVC_PROPERTY_CONTACT_UID = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_STR) +11,
+       CTSVC_PROPERTY_CONTACT_VIBRATION = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_STR) +12,
+       CTSVC_PROPERTY_CONTACT_CHANGED_TIME = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY) +13,
+       CTSVC_PROPERTY_CONTACT_NAME = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_REC) +14,
+       CTSVC_PROPERTY_CONTACT_COMPANY = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_REC) +15,
+       CTSVC_PROPERTY_CONTACT_NOTE = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_REC) +16,
+       CTSVC_PROPERTY_CONTACT_NUMBER = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_REC) +17,
+       CTSVC_PROPERTY_CONTACT_EMAIL = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_REC) +18,
+       CTSVC_PROPERTY_CONTACT_EVENT = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_REC) +19,
+       CTSVC_PROPERTY_CONTACT_MESSENGER = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_REC) +20,
+       CTSVC_PROPERTY_CONTACT_ADDRESS = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_REC) +21,
+       CTSVC_PROPERTY_CONTACT_URL = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_REC) +22,
+       CTSVC_PROPERTY_CONTACT_NICKNAME = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_REC) +23,
+       CTSVC_PROPERTY_CONTACT_PROFILE = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_REC) +24,
+       CTSVC_PROPERTY_CONTACT_RELATIONSHIP = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_REC) +25,
+       CTSVC_PROPERTY_CONTACT_GROUP_RELATION = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_REC) +26,
+       CTSVC_PROPERTY_CONTACT_EXTENSION = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_REC) +27,
+       CTSVC_PROPERTY_CONTACT_LINK_MODE = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_INT) +28,
+       CTSVC_PROPERTY_CONTACT_MESSAGE_ALERT = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_STR) +29,
+
+       // my_profile
+       CTSVC_PROPERTY_MY_PROFILE_ID = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_MY_PROFILE_DISPLAY_NAME = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +1,
+       CTSVC_PROPERTY_MY_PROFILE_ADDRESSBOOK_ID = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_INT) +2,
+       CTSVC_PROPERTY_MY_PROFILE_IMAGE = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_REC) +3,
+       CTSVC_PROPERTY_MY_PROFILE_IMAGE_THUMBNAIL = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +4,
+       CTSVC_PROPERTY_MY_PROFILE_UID = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +5,
+       CTSVC_PROPERTY_MY_PROFILE_CHANGED_TIME = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_INT) +6,
+       CTSVC_PROPERTY_MY_PROFILE_NAME = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_REC) +7,
+       CTSVC_PROPERTY_MY_PROFILE_COMPANY = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_REC) +8,
+       CTSVC_PROPERTY_MY_PROFILE_NOTE = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_REC) +9,
+       CTSVC_PROPERTY_MY_PROFILE_NUMBER = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_REC) +10,
+       CTSVC_PROPERTY_MY_PROFILE_EMAIL = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_REC) +11,
+       CTSVC_PROPERTY_MY_PROFILE_EVENT = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_REC) +12,
+       CTSVC_PROPERTY_MY_PROFILE_MESSENGER = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_REC) +13,
+       CTSVC_PROPERTY_MY_PROFILE_ADDRESS = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_REC) +14,
+       CTSVC_PROPERTY_MY_PROFILE_URL = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_REC) +15,
+       CTSVC_PROPERTY_MY_PROFILE_NICKNAME = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_REC) +16,
+       CTSVC_PROPERTY_MY_PROFILE_PROFILE = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_REC) +17,
+       CTSVC_PROPERTY_MY_PROFILE_RELATIONSHIP = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_REC) +18,
+       CTSVC_PROPERTY_MY_PROFILE_EXTENSION = (CTSVC_PROPERTY_MY_PROFILE | CTSVC_VIEW_DATA_TYPE_REC) +19,
+
+       // contact_name
+       CTSVC_PROPERTY_NAME_ID = (CTSVC_PROPERTY_NAME | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_NAME_CONTACT_ID = (CTSVC_PROPERTY_NAME | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_NAME_FIRST = (CTSVC_PROPERTY_NAME | CTSVC_VIEW_DATA_TYPE_STR) +2,
+       CTSVC_PROPERTY_NAME_LAST = (CTSVC_PROPERTY_NAME | CTSVC_VIEW_DATA_TYPE_STR) +3,
+       CTSVC_PROPERTY_NAME_ADDITION = (CTSVC_PROPERTY_NAME | CTSVC_VIEW_DATA_TYPE_STR) +4,
+       CTSVC_PROPERTY_NAME_SUFFIX = (CTSVC_PROPERTY_NAME | CTSVC_VIEW_DATA_TYPE_STR) +5,
+       CTSVC_PROPERTY_NAME_PREFIX = (CTSVC_PROPERTY_NAME | CTSVC_VIEW_DATA_TYPE_STR) +6,
+       CTSVC_PROPERTY_NAME_PHONETIC_FIRST = (CTSVC_PROPERTY_NAME | CTSVC_VIEW_DATA_TYPE_STR) +7,
+       CTSVC_PROPERTY_NAME_PHONETIC_MIDDLE = (CTSVC_PROPERTY_NAME | CTSVC_VIEW_DATA_TYPE_STR) +8,
+       CTSVC_PROPERTY_NAME_PHONETIC_LAST = (CTSVC_PROPERTY_NAME | CTSVC_VIEW_DATA_TYPE_STR) +9,
+
+       // contact_number
+       CTSVC_PROPERTY_NUMBER_ID = (CTSVC_PROPERTY_NUMBER | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_NUMBER_CONTACT_ID = (CTSVC_PROPERTY_NUMBER | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_NUMBER_TYPE = (CTSVC_PROPERTY_NUMBER | CTSVC_VIEW_DATA_TYPE_INT) +2,
+       CTSVC_PROPERTY_NUMBER_LABEL = (CTSVC_PROPERTY_NUMBER | CTSVC_VIEW_DATA_TYPE_STR) +3,
+       CTSVC_PROPERTY_NUMBER_IS_DEFAULT = (CTSVC_PROPERTY_NUMBER | CTSVC_VIEW_DATA_TYPE_BOOL) +4,
+       CTSVC_PROPERTY_NUMBER_NUMBER = (CTSVC_PROPERTY_NUMBER | CTSVC_VIEW_DATA_TYPE_STR) +5,
+       CTSVC_PROPERTY_NUMBER_NUMBER_FILTER = (CTSVC_PROPERTY_NUMBER | CTSVC_VIEW_DATA_TYPE_STR) +6,
+       CTSVC_PROPERTY_NUMBER_NORMALIZED_NUMBER = (CTSVC_PROPERTY_NUMBER | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +7,
+       CTSVC_PROPERTY_NUMBER_CLEANED_NUMBER = (CTSVC_PROPERTY_NUMBER | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +8,
+
+       // contact_email
+       CTSVC_PROPERTY_EMAIL_ID = (CTSVC_PROPERTY_EMAIL | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_EMAIL_CONTACT_ID = (CTSVC_PROPERTY_EMAIL | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_EMAIL_TYPE = (CTSVC_PROPERTY_EMAIL | CTSVC_VIEW_DATA_TYPE_INT) +2,
+       CTSVC_PROPERTY_EMAIL_LABEL = (CTSVC_PROPERTY_EMAIL | CTSVC_VIEW_DATA_TYPE_STR) +3,
+       CTSVC_PROPERTY_EMAIL_IS_DEFAULT = (CTSVC_PROPERTY_EMAIL | CTSVC_VIEW_DATA_TYPE_BOOL) +4,
+       CTSVC_PROPERTY_EMAIL_EMAIL = (CTSVC_PROPERTY_EMAIL | CTSVC_VIEW_DATA_TYPE_STR) +5,
+
+       // contact_address
+       CTSVC_PROPERTY_ADDRESS_ID = (CTSVC_PROPERTY_ADDRESS | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_ADDRESS_CONTACT_ID = (CTSVC_PROPERTY_ADDRESS | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_ADDRESS_TYPE = (CTSVC_PROPERTY_ADDRESS | CTSVC_VIEW_DATA_TYPE_INT) +2,
+       CTSVC_PROPERTY_ADDRESS_LABEL = (CTSVC_PROPERTY_ADDRESS | CTSVC_VIEW_DATA_TYPE_STR) +3,
+       CTSVC_PROPERTY_ADDRESS_POSTBOX = (CTSVC_PROPERTY_ADDRESS | CTSVC_VIEW_DATA_TYPE_STR) +4,
+       CTSVC_PROPERTY_ADDRESS_POSTAL_CODE = (CTSVC_PROPERTY_ADDRESS | CTSVC_VIEW_DATA_TYPE_STR) +5,
+       CTSVC_PROPERTY_ADDRESS_REGION = (CTSVC_PROPERTY_ADDRESS | CTSVC_VIEW_DATA_TYPE_STR) +6,
+       CTSVC_PROPERTY_ADDRESS_LOCALITY = (CTSVC_PROPERTY_ADDRESS | CTSVC_VIEW_DATA_TYPE_STR) +7,
+       CTSVC_PROPERTY_ADDRESS_STREET = (CTSVC_PROPERTY_ADDRESS | CTSVC_VIEW_DATA_TYPE_STR) +8,
+       CTSVC_PROPERTY_ADDRESS_COUNTRY = (CTSVC_PROPERTY_ADDRESS | CTSVC_VIEW_DATA_TYPE_STR) +9,
+       CTSVC_PROPERTY_ADDRESS_EXTENDED = (CTSVC_PROPERTY_ADDRESS | CTSVC_VIEW_DATA_TYPE_STR) +10,
+       CTSVC_PROPERTY_ADDRESS_IS_DEFAULT = (CTSVC_PROPERTY_ADDRESS | CTSVC_VIEW_DATA_TYPE_BOOL) +11,
+
+       // contact_url
+       CTSVC_PROPERTY_URL_ID = (CTSVC_PROPERTY_URL | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_URL_CONTACT_ID = (CTSVC_PROPERTY_URL | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_URL_TYPE = (CTSVC_PROPERTY_URL | CTSVC_VIEW_DATA_TYPE_INT) +2,
+       CTSVC_PROPERTY_URL_LABEL = (CTSVC_PROPERTY_URL | CTSVC_VIEW_DATA_TYPE_STR) +3,
+       CTSVC_PROPERTY_URL_URL = (CTSVC_PROPERTY_URL | CTSVC_VIEW_DATA_TYPE_STR) +4,
+
+       // contact_event
+       CTSVC_PROPERTY_EVENT_ID = (CTSVC_PROPERTY_EVENT | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_EVENT_CONTACT_ID = (CTSVC_PROPERTY_EVENT | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_EVENT_TYPE = (CTSVC_PROPERTY_EVENT | CTSVC_VIEW_DATA_TYPE_INT) +2,
+       CTSVC_PROPERTY_EVENT_LABEL = (CTSVC_PROPERTY_EVENT | CTSVC_VIEW_DATA_TYPE_STR) +3,
+       CTSVC_PROPERTY_EVENT_DATE = (CTSVC_PROPERTY_EVENT | CTSVC_VIEW_DATA_TYPE_INT) +4,
+       CTSVC_PROPERTY_EVENT_CALENDAR_TYPE = (CTSVC_PROPERTY_EVENT | CTSVC_VIEW_DATA_TYPE_INT) +5,
+       CTSVC_PROPERTY_EVENT_IS_LEAP_MONTH = (CTSVC_PROPERTY_EVENT | CTSVC_VIEW_DATA_TYPE_BOOL) +6,
+
+       // contact_grouprelation
+       CTSVC_PROPERTY_GROUP_RELATION_ID = (CTSVC_PROPERTY_GROUP_RELATION | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_GROUP_RELATION_GROUP_ID = (CTSVC_PROPERTY_GROUP_RELATION | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_GROUP_RELATION_CONTACT_ID = (CTSVC_PROPERTY_GROUP_RELATION | CTSVC_VIEW_DATA_TYPE_INT) +2,
+       CTSVC_PROPERTY_GROUP_RELATION_GROUP_NAME = (CTSVC_PROPERTY_GROUP_RELATION | CTSVC_VIEW_DATA_TYPE_STR) +3,
+
+       // contact_relationship
+       CTSVC_PROPERTY_RELATIONSHIP_ID = (CTSVC_PROPERTY_RELATIONSHIP | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_RELATIONSHIP_CONTACT_ID = (CTSVC_PROPERTY_RELATIONSHIP | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_RELATIONSHIP_TYPE = (CTSVC_PROPERTY_RELATIONSHIP | CTSVC_VIEW_DATA_TYPE_INT) +2,
+       CTSVC_PROPERTY_RELATIONSHIP_LABEL = (CTSVC_PROPERTY_RELATIONSHIP | CTSVC_VIEW_DATA_TYPE_STR) +3,
+       CTSVC_PROPERTY_RELATIONSHIP_NAME = (CTSVC_PROPERTY_RELATIONSHIP | CTSVC_VIEW_DATA_TYPE_STR) +4,
+
+       // contact_image
+       CTSVC_PROPERTY_IMAGE_ID = (CTSVC_PROPERTY_IMAGE | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_IMAGE_CONTACT_ID = (CTSVC_PROPERTY_IMAGE | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_IMAGE_TYPE = (CTSVC_PROPERTY_IMAGE | CTSVC_VIEW_DATA_TYPE_INT) +2,
+       CTSVC_PROPERTY_IMAGE_LABEL = (CTSVC_PROPERTY_IMAGE | CTSVC_VIEW_DATA_TYPE_STR) +3,
+       CTSVC_PROPERTY_IMAGE_PATH = (CTSVC_PROPERTY_IMAGE | CTSVC_VIEW_DATA_TYPE_STR) +4,
+       CTSVC_PROPERTY_IMAGE_IS_DEFAULT = (CTSVC_PROPERTY_IMAGE | CTSVC_VIEW_DATA_TYPE_BOOL) + 5,
+
+       // contact_company
+       CTSVC_PROPERTY_COMPANY_ID = (CTSVC_PROPERTY_COMPANY | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_COMPANY_CONTACT_ID = (CTSVC_PROPERTY_COMPANY | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_COMPANY_TYPE = (CTSVC_PROPERTY_COMPANY | CTSVC_VIEW_DATA_TYPE_INT) +2,
+       CTSVC_PROPERTY_COMPANY_LABEL = (CTSVC_PROPERTY_COMPANY | CTSVC_VIEW_DATA_TYPE_STR) +3,
+       CTSVC_PROPERTY_COMPANY_NAME = (CTSVC_PROPERTY_COMPANY | CTSVC_VIEW_DATA_TYPE_STR) +4,
+       CTSVC_PROPERTY_COMPANY_DEPARTMENT = (CTSVC_PROPERTY_COMPANY | CTSVC_VIEW_DATA_TYPE_STR) +5,
+       CTSVC_PROPERTY_COMPANY_JOB_TITLE = (CTSVC_PROPERTY_COMPANY | CTSVC_VIEW_DATA_TYPE_STR) +6,
+       CTSVC_PROPERTY_COMPANY_ROLE = (CTSVC_PROPERTY_COMPANY | CTSVC_VIEW_DATA_TYPE_STR) +7,
+       CTSVC_PROPERTY_COMPANY_ASSISTANT_NAME = (CTSVC_PROPERTY_COMPANY | CTSVC_VIEW_DATA_TYPE_STR) +8,
+       CTSVC_PROPERTY_COMPANY_LOGO = (CTSVC_PROPERTY_COMPANY | CTSVC_VIEW_DATA_TYPE_STR) +9,
+       CTSVC_PROPERTY_COMPANY_LOCATION = (CTSVC_PROPERTY_COMPANY | CTSVC_VIEW_DATA_TYPE_STR) +10,
+       CTSVC_PROPERTY_COMPANY_DESCRIPTION = (CTSVC_PROPERTY_COMPANY | CTSVC_VIEW_DATA_TYPE_STR) +11,
+       CTSVC_PROPERTY_COMPANY_PHONETIC_NAME = (CTSVC_PROPERTY_COMPANY | CTSVC_VIEW_DATA_TYPE_STR) +12,
+
+       // contact_nickname
+       CTSVC_PROPERTY_NICKNAME_ID = (CTSVC_PROPERTY_NICKNAME | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_NICKNAME_CONTACT_ID = (CTSVC_PROPERTY_NICKNAME | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_NICKNAME_NAME = (CTSVC_PROPERTY_NICKNAME | CTSVC_VIEW_DATA_TYPE_STR) +2,
+
+       // contact_messenger
+       CTSVC_PROPERTY_MESSENGER_ID = (CTSVC_PROPERTY_MESSENGER | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_MESSENGER_CONTACT_ID = (CTSVC_PROPERTY_MESSENGER | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_MESSENGER_TYPE = (CTSVC_PROPERTY_MESSENGER | CTSVC_VIEW_DATA_TYPE_INT) +2,
+       CTSVC_PROPERTY_MESSENGER_LABEL = (CTSVC_PROPERTY_MESSENGER | CTSVC_VIEW_DATA_TYPE_STR) +3,
+       CTSVC_PROPERTY_MESSENGER_IM_ID = (CTSVC_PROPERTY_MESSENGER | CTSVC_VIEW_DATA_TYPE_STR) +4,
+
+       // contact_note
+       CTSVC_PROPERTY_NOTE_ID = (CTSVC_PROPERTY_NOTE | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_NOTE_CONTACT_ID = (CTSVC_PROPERTY_NOTE | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_NOTE_NOTE = (CTSVC_PROPERTY_NOTE | CTSVC_VIEW_DATA_TYPE_STR) +2,
+
+       // contact_extend
+       CTSVC_PROPERTY_EXTENSION_ID = (CTSVC_PROPERTY_EXTENSION | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_EXTENSION_CONTACT_ID = (CTSVC_PROPERTY_EXTENSION | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_EXTENSION_DATA1 = (CTSVC_PROPERTY_EXTENSION | CTSVC_VIEW_DATA_TYPE_INT) +2,
+       CTSVC_PROPERTY_EXTENSION_DATA2 = (CTSVC_PROPERTY_EXTENSION | CTSVC_VIEW_DATA_TYPE_STR) +3,
+       CTSVC_PROPERTY_EXTENSION_DATA3 = (CTSVC_PROPERTY_EXTENSION | CTSVC_VIEW_DATA_TYPE_STR) +4,
+       CTSVC_PROPERTY_EXTENSION_DATA4 = (CTSVC_PROPERTY_EXTENSION | CTSVC_VIEW_DATA_TYPE_STR) +5,
+       CTSVC_PROPERTY_EXTENSION_DATA5 = (CTSVC_PROPERTY_EXTENSION | CTSVC_VIEW_DATA_TYPE_STR) +6,
+       CTSVC_PROPERTY_EXTENSION_DATA6 = (CTSVC_PROPERTY_EXTENSION | CTSVC_VIEW_DATA_TYPE_STR) +7,
+       CTSVC_PROPERTY_EXTENSION_DATA7 = (CTSVC_PROPERTY_EXTENSION | CTSVC_VIEW_DATA_TYPE_STR) +8,
+       CTSVC_PROPERTY_EXTENSION_DATA8 = (CTSVC_PROPERTY_EXTENSION | CTSVC_VIEW_DATA_TYPE_STR) +9,
+       CTSVC_PROPERTY_EXTENSION_DATA9 = (CTSVC_PROPERTY_EXTENSION | CTSVC_VIEW_DATA_TYPE_STR) +10,
+       CTSVC_PROPERTY_EXTENSION_DATA10 = (CTSVC_PROPERTY_EXTENSION | CTSVC_VIEW_DATA_TYPE_STR) +11,
+       CTSVC_PROPERTY_EXTENSION_DATA11 = (CTSVC_PROPERTY_EXTENSION | CTSVC_VIEW_DATA_TYPE_STR) +12,
+       CTSVC_PROPERTY_EXTENSION_DATA12 = (CTSVC_PROPERTY_EXTENSION | CTSVC_VIEW_DATA_TYPE_STR) +13,
+
+       // contact_profile
+       CTSVC_PROPERTY_PROFILE_ID = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_PROFILE_CONTACT_ID = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_PROFILE_UID = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +2,
+       CTSVC_PROPERTY_PROFILE_TEXT = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +3,
+       CTSVC_PROPERTY_PROFILE_ORDER = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_INT) +4,
+       CTSVC_PROPERTY_PROFILE_SERVICE_OPERATION = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +5,
+       CTSVC_PROPERTY_PROFILE_MIME = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +6,
+       CTSVC_PROPERTY_PROFILE_APP_ID = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +7,
+       CTSVC_PROPERTY_PROFILE_URI = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +8,
+       CTSVC_PROPERTY_PROFILE_CATEGORY = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +9,
+       CTSVC_PROPERTY_PROFILE_EXTRA_DATA = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +10,
+
+       // activity
+       CTSVC_PROPERTY_ACTIVITY_ID = (CTSVC_PROPERTY_ACTIVITY | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_ACTIVITY_CONTACT_ID = (CTSVC_PROPERTY_ACTIVITY | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_ACTIVITY_SOURCE_NAME = (CTSVC_PROPERTY_ACTIVITY | CTSVC_VIEW_DATA_TYPE_STR) +2,
+       CTSVC_PROPERTY_ACTIVITY_STATUS = (CTSVC_PROPERTY_ACTIVITY | CTSVC_VIEW_DATA_TYPE_STR) +3,
+       CTSVC_PROPERTY_ACTIVITY_TIMESTAMP = (CTSVC_PROPERTY_ACTIVITY | CTSVC_VIEW_DATA_TYPE_INT) +4,
+       CTSVC_PROPERTY_ACTIVITY_SERVICE_OPERATION = (CTSVC_PROPERTY_ACTIVITY | CTSVC_VIEW_DATA_TYPE_STR) +5,
+       CTSVC_PROPERTY_ACTIVITY_URI = (CTSVC_PROPERTY_ACTIVITY | CTSVC_VIEW_DATA_TYPE_STR) +6,
+       CTSVC_PROPERTY_ACTIVITY_ACTIVITY_PHOTO = (CTSVC_PROPERTY_ACTIVITY | CTSVC_VIEW_DATA_TYPE_REC) +7,
+
+       // activity photo
+       CTSVC_PROPERTY_ACTIVITY_PHOTO_ID = (CTSVC_PROPERTY_ACTIVITY_PHOTO | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_ACTIVITY_PHOTO_ACTIVITY_ID = (CTSVC_PROPERTY_ACTIVITY_PHOTO | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_ACTIVITY_PHOTO_URL = (CTSVC_PROPERTY_ACTIVITY_PHOTO | CTSVC_VIEW_DATA_TYPE_STR) +2,
+       CTSVC_PROPERTY_ACTIVITY_PHOTO_SORT_INDEX = (CTSVC_PROPERTY_ACTIVITY_PHOTO | CTSVC_VIEW_DATA_TYPE_INT) +3,
+
+       // data
+       CTSVC_PROPERTY_DATA_ID = (CTSVC_PROPERTY_DATA | CTSVC_VIEW_DATA_TYPE_INT),
+       CTSVC_PROPERTY_DATA_CONTACT_ID = (CTSVC_PROPERTY_DATA | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_DATA_TYPE = (CTSVC_PROPERTY_DATA | CTSVC_VIEW_DATA_TYPE_INT) +2,
+       CTSVC_PROPERTY_DATA_IS_PRIMARY_DEFAULT = (CTSVC_PROPERTY_DATA | CTSVC_VIEW_DATA_TYPE_BOOL) +3,
+       CTSVC_PROPERTY_DATA_IS_DEFAULT = (CTSVC_PROPERTY_DATA | CTSVC_VIEW_DATA_TYPE_BOOL) +4,
+       CTSVC_PROPERTY_DATA_DATA1 = (CTSVC_PROPERTY_DATA | CTSVC_VIEW_DATA_TYPE_INT) +5,
+       CTSVC_PROPERTY_DATA_DATA2 = (CTSVC_PROPERTY_DATA | CTSVC_VIEW_DATA_TYPE_STR) +6,
+       CTSVC_PROPERTY_DATA_DATA3 = (CTSVC_PROPERTY_DATA | CTSVC_VIEW_DATA_TYPE_STR) +7,
+       CTSVC_PROPERTY_DATA_DATA4 = (CTSVC_PROPERTY_DATA | CTSVC_VIEW_DATA_TYPE_STR) +8,
+       CTSVC_PROPERTY_DATA_DATA5 = (CTSVC_PROPERTY_DATA | CTSVC_VIEW_DATA_TYPE_STR) +9,
+       CTSVC_PROPERTY_DATA_DATA6 = (CTSVC_PROPERTY_DATA | CTSVC_VIEW_DATA_TYPE_STR) +10,
+       CTSVC_PROPERTY_DATA_DATA7 = (CTSVC_PROPERTY_DATA | CTSVC_VIEW_DATA_TYPE_STR) +11,
+       CTSVC_PROPERTY_DATA_DATA8 = (CTSVC_PROPERTY_DATA | CTSVC_VIEW_DATA_TYPE_STR) +12,
+       CTSVC_PROPERTY_DATA_DATA9 = (CTSVC_PROPERTY_DATA | CTSVC_VIEW_DATA_TYPE_STR) +13,
+       CTSVC_PROPERTY_DATA_DATA10 = (CTSVC_PROPERTY_DATA | CTSVC_VIEW_DATA_TYPE_STR) +14,
+
+       // speeddial
+       CTSVC_PROPERTY_SPEEDDIAL_DIAL_NUMBER = (CTSVC_PROPERTY_SPEEDDIAL | CTSVC_VIEW_DATA_TYPE_INT),
+       CTSVC_PROPERTY_SPEEDDIAL_NUMBER_ID = (CTSVC_PROPERTY_SPEEDDIAL | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_SPEEDDIAL_NUMBER = (CTSVC_PROPERTY_SPEEDDIAL | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +2,
+       CTSVC_PROPERTY_SPEEDDIAL_NUMBER_LABEL = (CTSVC_PROPERTY_SPEEDDIAL | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +3,
+       CTSVC_PROPERTY_SPEEDDIAL_NUMBER_TYPE = (CTSVC_PROPERTY_SPEEDDIAL | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY) +4,
+       CTSVC_PROPERTY_SPEEDDIAL_PERSON_ID = (CTSVC_PROPERTY_SPEEDDIAL | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY) +5,
+       CTSVC_PROPERTY_SPEEDDIAL_DISPLAY_NAME = (CTSVC_PROPERTY_SPEEDDIAL | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +6,
+       CTSVC_PROPERTY_SPEEDDIAL_IMAGE_THUMBNAIL = (CTSVC_PROPERTY_SPEEDDIAL | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +7,
+       CTSVC_PROPERTY_SPEEDDIAL_NORMALIZED_NUMBER = (CTSVC_PROPERTY_SPEEDDIAL | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +8,
+       CTSVC_PROPERTY_SPEEDDIAL_CLEANED_NUMBER = (CTSVC_PROPERTY_SPEEDDIAL | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +9,
+       CTSVC_PROPERTY_SPEEDDIAL_NUMBER_FILTER = (CTSVC_PROPERTY_SPEEDDIAL | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +10,
+
+       // phonelog
+       CTSVC_PROPERTY_PHONELOG_ID = (CTSVC_PROPERTY_PHONELOG | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_PHONELOG_PERSON_ID = (CTSVC_PROPERTY_PHONELOG | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_PHONELOG_ADDRESS = (CTSVC_PROPERTY_PHONELOG | CTSVC_VIEW_DATA_TYPE_STR) +2,
+       CTSVC_PROPERTY_PHONELOG_LOG_TIME = (CTSVC_PROPERTY_PHONELOG | CTSVC_VIEW_DATA_TYPE_INT) +3,
+       CTSVC_PROPERTY_PHONELOG_LOG_TYPE = (CTSVC_PROPERTY_PHONELOG | CTSVC_VIEW_DATA_TYPE_INT) +4,
+       CTSVC_PROPERTY_PHONELOG_EXTRA_DATA1 = (CTSVC_PROPERTY_PHONELOG | CTSVC_VIEW_DATA_TYPE_INT) +5,          // duration, message_id, email_id
+       CTSVC_PROPERTY_PHONELOG_EXTRA_DATA2 = (CTSVC_PROPERTY_PHONELOG | CTSVC_VIEW_DATA_TYPE_STR) +6,          // short message, subject
+       CTSVC_PROPERTY_PHONELOG_NORMALIZED_ADDRESS = (CTSVC_PROPERTY_PHONELOG | CTSVC_VIEW_DATA_TYPE_STR|CTSVC_READ_ONLY_PROPERTY) +7,          // for search by calllog number
+       CTSVC_PROPERTY_PHONELOG_CLEANED_ADDRESS = (CTSVC_PROPERTY_PHONELOG | CTSVC_VIEW_DATA_TYPE_STR|CTSVC_READ_ONLY_PROPERTY) +8,             // for search by calllog number
+       CTSVC_PROPERTY_PHONELOG_ADDRESS_FILTER = (CTSVC_PROPERTY_PHONELOG | CTSVC_VIEW_DATA_TYPE_STR|CTSVC_READ_ONLY_PROPERTY) +9,              // for search by calllog number
+       CTSVC_PROPERTY_PHONELOG_SIM_SLOT_NO = (CTSVC_PROPERTY_PHONELOG | CTSVC_VIEW_DATA_TYPE_INT) +10,
+
+       // updated_info : read only
+       CTSVC_PROPERTY_UPDATE_INFO_ID = (CTSVC_PROPERTY_UPDATE_INFO | CTSVC_VIEW_DATA_TYPE_INT),
+       CTSVC_PROPERTY_UPDATE_INFO_ADDRESSBOOK_ID = (CTSVC_PROPERTY_UPDATE_INFO | CTSVC_VIEW_DATA_TYPE_INT) +1,
+       CTSVC_PROPERTY_UPDATE_INFO_TYPE = (CTSVC_PROPERTY_UPDATE_INFO | CTSVC_VIEW_DATA_TYPE_INT) +2,
+       CTSVC_PROPERTY_UPDATE_INFO_VERSION = (CTSVC_PROPERTY_UPDATE_INFO | CTSVC_VIEW_DATA_TYPE_INT) +3,
+       CTSVC_PROPERTY_UPDATE_INFO_IMAGE_CHANGED = (CTSVC_PROPERTY_UPDATE_INFO | CTSVC_VIEW_DATA_TYPE_BOOL) +4,
+       CTSVC_PROPERTY_UPDATE_INFO_LAST_CHANGED_TYPE = (CTSVC_PROPERTY_UPDATE_INFO | CTSVC_VIEW_DATA_TYPE_INT)+5,               // now, it is used for _contacts_my_profile_updated_info
+
+       // contact_sdn
+       CTSVC_PROPERTY_SDN_ID = (CTSVC_PROPERTY_SDN | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY),
+       CTSVC_PROPERTY_SDN_NAME = (CTSVC_PROPERTY_SDN | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +1,
+       CTSVC_PROPERTY_SDN_NUMBER = (CTSVC_PROPERTY_SDN | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +2,
+       CTSVC_PROPERTY_SDN_SIM_SLOT_NO = (CTSVC_PROPERTY_SDN | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY) +3,
+
+       // phonelog_stat
+       CTSVC_PROPERTY_PHONELOG_STAT_LOG_COUNT = (CTSVC_PROPERTY_PHONELOG_STAT | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY ),
+       CTSVC_PROPERTY_PHONELOG_STAT_LOG_TYPE = (CTSVC_PROPERTY_PHONELOG_STAT | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY ) +1,
+
+}ctsvc_property_ids_e;
+
+void ctsvc_view_uri_init();
+void ctsvc_view_uri_deinit();
+
+const char* ctsvc_view_get_uri( const char* view_uri );
+ctsvc_record_type_e ctsvc_view_get_record_type(const char* view_uri);
+const property_info_s* ctsvc_view_get_all_property_infos(const char *view_uri, unsigned int *count);
+
+#endif /* __TIZEN_SOCIAL_CTSVC_VIEW_H__ */
diff --git a/common/ipc/ctsvc_ipc_activity.c b/common/ipc/ctsvc_ipc_activity.c
new file mode 100644 (file)
index 0000000..447ca90
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_activity(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_activity(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_activity_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_activity_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_activity,
+       .marshal_record = __ctsvc_ipc_marshal_activity,
+       .get_primary_id = __ctsvc_ipc_marshal_activity_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_activity(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_INTERNAL);
+       RETV_IF(record==NULL,CONTACTS_ERROR_INTERNAL);
+
+       ctsvc_activity_s* activity_p = (ctsvc_activity_s*) record;
+
+       do
+       {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &activity_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &activity_p->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &activity_p->source_name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &activity_p->status) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &activity_p->timestamp) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &activity_p->service_operation) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &activity_p->uri) != CONTACTS_ERROR_NONE) break;
+
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&activity_p->photos) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_activity(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_activity_s* activity_p = (ctsvc_activity_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(activity_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_int((activity_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((activity_p->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((activity_p->source_name),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((activity_p->status),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((activity_p->timestamp),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((activity_p->service_operation),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((activity_p->uri),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)activity_p->photos, ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+
+}
+
+static int __ctsvc_ipc_marshal_activity_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_ACTIVITY_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_activity_photo.c b/common/ipc/ctsvc_ipc_activity_photo.c
new file mode 100644 (file)
index 0000000..d379015
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_activity_photo(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_activity_photo(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_activity_photo_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_activity_photo_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_activity_photo,
+       .marshal_record = __ctsvc_ipc_marshal_activity_photo,
+       .get_primary_id = __ctsvc_ipc_marshal_activity_photo_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_activity_photo(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_activity_photo_s* photo_p = (ctsvc_activity_photo_s*) record;
+
+       do
+       {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &photo_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &photo_p->activity_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &photo_p->photo_url) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &photo_p->sort_index) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_activity_photo(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_activity_photo_s* photo_p = (ctsvc_activity_photo_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(photo_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_int((photo_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((photo_p->activity_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((photo_p->photo_url),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((photo_p->sort_index),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+
+}
+
+static int __ctsvc_ipc_marshal_activity_photo_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_ACTIVITY_PHOTO_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_address.c b/common/ipc/ctsvc_ipc_address.c
new file mode 100644 (file)
index 0000000..74a5577
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_address(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_address(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_address_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_address_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_address,
+       .marshal_record = __ctsvc_ipc_marshal_address,
+       .get_primary_id = __ctsvc_ipc_marshal_address_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_address(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_address_s* address_p = (ctsvc_address_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &address_p->is_default) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &address_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &address_p->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &address_p->type) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &address_p->label) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &address_p->pobox) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &address_p->postalcode) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &address_p->region) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &address_p->locality) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &address_p->street) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &address_p->extended) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &address_p->country) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_address(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_address_s* address_p = (ctsvc_address_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(address_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_bool((address_p->is_default),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((address_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((address_p->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((address_p->type),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((address_p->label),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((address_p->pobox),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((address_p->postalcode),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((address_p->region),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((address_p->locality),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((address_p->street),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((address_p->extended),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((address_p->country),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_address_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_ADDRESS_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
+
diff --git a/common/ipc/ctsvc_ipc_addressbook.c b/common/ipc/ctsvc_ipc_addressbook.c
new file mode 100644 (file)
index 0000000..3f4554b
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_addressbook(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_addressbook(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_addressbook_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_addressbook_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_addressbook,
+       .marshal_record = __ctsvc_ipc_marshal_addressbook,
+       .get_primary_id = __ctsvc_ipc_marshal_addressbook_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_addressbook(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_addressbook_s* addressbook_p = (ctsvc_addressbook_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &addressbook_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &addressbook_p->name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &addressbook_p->account_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &addressbook_p->mode) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_addressbook(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_addressbook_s* addressbook_p = (ctsvc_addressbook_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(addressbook_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_int((addressbook_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((addressbook_p->name),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((addressbook_p->account_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((addressbook_p->mode),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_addressbook_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_ADDRESSBOOK_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
+
diff --git a/common/ipc/ctsvc_ipc_company.c b/common/ipc/ctsvc_ipc_company.c
new file mode 100644 (file)
index 0000000..6902967
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_company(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_company(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_company_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_company_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_company,
+       .marshal_record = __ctsvc_ipc_marshal_company,
+       .get_primary_id = __ctsvc_ipc_marshal_company_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_company(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_company_s* company_p = (ctsvc_company_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &company_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &company_p->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &company_p->is_default) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &company_p->type) != CONTACTS_ERROR_NONE) break;
+
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &company_p->label) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &company_p->name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &company_p->department) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &company_p->job_title) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &company_p->role) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &company_p->assistant_name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &company_p->logo) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &company_p->location) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &company_p->description) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &company_p->phonetic_name) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_company(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_company_s* company_p = (ctsvc_company_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(company_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_int((company_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((company_p->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_bool((company_p->is_default),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((company_p->type),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((company_p->label),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((company_p->name),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((company_p->department),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((company_p->job_title),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((company_p->role),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((company_p->assistant_name),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((company_p->logo),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((company_p->location),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((company_p->description),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((company_p->phonetic_name),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_company_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_COMPANY_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_contact.c b/common/ipc/ctsvc_ipc_contact.c
new file mode 100644 (file)
index 0000000..54dcf63
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+
+static int __ctsvc_ipc_unmarshal_contact(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_contact(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_contact_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_contact_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_contact,
+       .marshal_record = __ctsvc_ipc_marshal_contact,
+       .get_primary_id = __ctsvc_ipc_marshal_contact_get_primary_id
+};
+
+static int __ctsvc_ipc_unmarshal_contact(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_contact_s* pcontact = (ctsvc_contact_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &pcontact->is_favorite) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pcontact->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pcontact->person_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pcontact->changed_time) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pcontact->link_mode) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pcontact->addressbook_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &pcontact->has_phonenumber) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &pcontact->has_email) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->display_name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->reverse_display_name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pcontact->display_source_type) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pcontact->display_name_language) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pcontact->reverse_display_name_language) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->sort_name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->reverse_sort_name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->sortkey) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->reverse_sortkey) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->uid) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->image_thumbnail_path) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->ringtone_path) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->vibration) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->message_alert) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pcontact->changed_ver) != CONTACTS_ERROR_NONE) break;
+
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pcontact->name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pcontact->note) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pcontact->company) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pcontact->numbers) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pcontact->emails) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pcontact->grouprelations) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pcontact->events) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pcontact->messengers) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pcontact->postal_addrs) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pcontact->urls) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pcontact->nicknames) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pcontact->profiles) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pcontact->relationships) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pcontact->images) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pcontact->extensions) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_contact(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_contact_s* pcontact = (ctsvc_contact_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(pcontact==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_bool((pcontact->is_favorite),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((pcontact->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((pcontact->person_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((pcontact->changed_time),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((pcontact->link_mode),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((pcontact->addressbook_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_bool((pcontact->has_phonenumber),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_bool((pcontact->has_email),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->display_name),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->reverse_display_name),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((pcontact->display_source_type),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((pcontact->display_name_language),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((pcontact->reverse_display_name_language),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->sort_name),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->reverse_sort_name),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->sortkey),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->reverse_sortkey),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->uid),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->image_thumbnail_path),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->ringtone_path),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->vibration),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->message_alert),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((pcontact->changed_ver),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->name, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->note, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->company, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->numbers, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->emails, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->grouprelations, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->events, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->messengers, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->postal_addrs, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->urls, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->nicknames, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->profiles, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->relationships, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->images, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->extensions, ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_contact_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_CONTACT_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_define.h b/common/ipc/ctsvc_ipc_define.h
new file mode 100644 (file)
index 0000000..f39efb9
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_IPC_DEFINE_H__
+#define __CTSVC_IPC_DEFINE_H__
+
+#define CTSVC_IPC_SERVICE              "contacts_svc_ipc"
+#define CTSVC_IPC_SOCKET_PATH          "/tmp/."CTSVC_IPC_SERVICE
+
+#define CTSVC_IPC_SOCKET_PATH_FOR_CHANGE_SUBSCRIPTION    "/tmp/."CTSVC_IPC_SERVICE"_for_subscribe"
+#define CTSVC_IPC_SUBSCRIBE_MODULE               "ctsvc_ipc_subscribe_module"
+
+#define CTSVC_IPC_MODULE               "ctsvc_ipc_module"
+#define CTSVC_IPC_DB_MODULE               "ctsvc_ipc_db_module"
+#define CTSVC_IPC_ACTIVITY_MODULE               "ctsvc_ipc_activity_module"
+#define CTSVC_IPC_GROUP_MODULE               "ctsvc_ipc_group_module"
+#define CTSVC_IPC_PERSON_MODULE               "ctsvc_ipc_person_module"
+#define CTSVC_IPC_PHONELOG_MODULE               "ctsvc_ipc_phonelog_module"
+#define CTSVC_IPC_SIM_MODULE               "ctsvc_ipc_sim_module"
+#define CTSVC_IPC_SETTING_MODULE               "ctsvc_ipc_setting_module"
+#define CTSVC_IPC_UTILS_MODULE               "ctsvc_ipc_utils_module"
+
+#define CTSVC_IPC_SERVER_CONNECT                      "connect"
+#define CTSVC_IPC_SERVER_DISCONNECT                   "disconnect"
+#define CTSVC_IPC_SERVER_CHECK_PERMISSION                              "check_permission"
+
+#define CTSVC_IPC_SERVER_DB_INSERT_RECORD             "insert_record"
+#define CTSVC_IPC_SERVER_DB_GET_RECORD                "get_record"
+#define CTSVC_IPC_SERVER_DB_UPDATE_RECORD             "update_record"
+#define CTSVC_IPC_SERVER_DB_DELETE_RECORD             "delete_record"
+#define CTSVC_IPC_SERVER_DB_REPLACE_RECORD                     "replace_record"
+#define CTSVC_IPC_SERVER_DB_GET_ALL_RECORDS           "get_all_records"
+#define CTSVC_IPC_SERVER_DB_GET_RECORDS_WITH_QUERY    "get_records_with_query"
+#define CTSVC_IPC_SERVER_DB_GET_COUNT                 "get_count"
+#define CTSVC_IPC_SERVER_DB_GET_COUNT_WITH_QUERY      "get_count_with_query"
+#define CTSVC_IPC_SERVER_DB_INSERT_RECORDS            "insert_records"
+#define CTSVC_IPC_SERVER_DB_UPDATE_RECORDS            "update_records"
+#define CTSVC_IPC_SERVER_DB_DELETE_RECORDS            "delete_records"
+#define CTSVC_IPC_SERVER_DB_REPLACE_RECORDS                    "replace_records"
+#define CTSVC_IPC_SERVER_DB_CHANGES_BY_VERSION        "changes_by_version"
+#define CTSVC_IPC_SERVER_DB_GET_CURRENT_VERSION       "get_current_version"
+#define CTSVC_IPC_SERVER_DB_SEARCH_RECORDS            "search_records"
+#define CTSVC_IPC_SERVER_DB_SEARCH_RECORDS_WITH_RANGE          "search_records_with_range"
+#define CTSVC_IPC_SERVER_DB_SEARCH_RECORDS_WITH_QUERY    "search_records_with_query"
+#define CTSVC_IPC_SERVER_DB_GET_STATUS                                 "get_db_status"
+#define CTSVC_IPC_SERVER_DB_STATUS_CHANGED                     "db_status_changed"
+
+
+#define CTSVC_IPC_SERVER_ACTIVITY_DELETE_BY_CONTACT_ID   "activity_delete_by_contact_id"
+#define CTSVC_IPC_SERVER_ACTIVITY_DELETE_BY_ACCOUNT_ID   "activity_delete_by_account_id"
+
+#define CTSVC_IPC_SERVER_GROUP_ADD_CONTACT                                      "group_add_contact"
+#define CTSVC_IPC_SERVER_GROUP_REMOVE_CONTACT                           "group_remove_contact"
+#define CTSVC_IPC_SERVER_GROUP_SET_GROUP_ORDER       "group_set_group_order"
+
+#define CTSVC_IPC_SERVER_PERSON_LINK_PERSON                            "person_link_person"
+#define CTSVC_IPC_SERVER_PERSON_UNLINK_CONTACT                 "person_unlink_contact"
+#define CTSVC_IPC_SERVER_PERSON_RESET_USAGE                            "person_reset_usgae"
+#define CTSVC_IPC_SERVER_PERSON_SET_FAVORITE_ORDER       "person_set_favorite_order"
+#define CTSVC_IPC_SERVER_PERSON_SET_DEFAULT_PROPERTY      "person_set_default_property"
+#define CTSVC_IPC_SERVER_PERSON_GET_DEFAULT_PROPERTY      "person_get_default_property"
+
+#define CTSVC_IPC_SERVER_PHONELOG_RESET_STATISTICS    "phonelog_reset_statistics"
+#define CTSVC_IPC_SERVER_PHONELOG_DELETE    "phonelog_delete"
+
+#define CTSVC_IPC_SERVER_SETTING_GET_NAME_DISPLAY_ORDER "setting_get_name_display_order"
+#define CTSVC_IPC_SERVER_SETTING_SET_NAME_DISPLAY_ORDER "setting_set_name_display_order"
+#define CTSVC_IPC_SERVER_SETTING_GET_NAME_SORTING_ORDER "setting_get_name_sorting_order"
+#define CTSVC_IPC_SERVER_SETTING_SET_NAME_SORTING_ORDER "setting_set_name_sorting_order"
+
+#define CTSVC_IPC_SERVER_SIM_IMPORT_ALL_CONTACTS               "sim_import_all_contacts"
+
+#endif /*__CTSVC_IPC_DEFINE_H__ */
diff --git a/common/ipc/ctsvc_ipc_email.c b/common/ipc/ctsvc_ipc_email.c
new file mode 100644 (file)
index 0000000..7a44530
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_email(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_email(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_email_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_email_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_email,
+       .marshal_record = __ctsvc_ipc_marshal_email,
+       .get_primary_id = __ctsvc_ipc_marshal_email_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_email(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_email_s* email_p = (ctsvc_email_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &email_p->is_default) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &email_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &email_p->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &email_p->type) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &email_p->label) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &email_p->email_addr) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_email(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_email_s* email_p = (ctsvc_email_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(email_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_bool((email_p->is_default),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((email_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((email_p->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((email_p->type),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((email_p->label),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((email_p->email_addr),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_email_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_EMAIL_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_event.c b/common/ipc/ctsvc_ipc_event.c
new file mode 100644 (file)
index 0000000..e92c9b2
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_event(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_event(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_event_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_event_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_event,
+       .marshal_record = __ctsvc_ipc_marshal_event,
+       .get_primary_id = __ctsvc_ipc_marshal_event_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_event(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_event_s* event_p = (ctsvc_event_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &event_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &event_p->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &event_p->type) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &event_p->label) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &event_p->date) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &event_p->calendar_type) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &event_p->is_leap_month) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_event(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_event_s* event_p = (ctsvc_event_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(event_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_int((event_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((event_p->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((event_p->type),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((event_p->label),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((event_p->date),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((event_p->calendar_type),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_bool((event_p->is_leap_month),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_event_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_EVENT_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_extension.c b/common/ipc/ctsvc_ipc_extension.c
new file mode 100644 (file)
index 0000000..55c62db
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_extension(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_extension(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_extension_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_extension_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_extension,
+       .marshal_record = __ctsvc_ipc_marshal_extension,
+       .get_primary_id = __ctsvc_ipc_marshal_extension_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_extension(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_extension_s* extend_p = (ctsvc_extension_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &extend_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &extend_p->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &extend_p->data1) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &extend_p->data2) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &extend_p->data3) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &extend_p->data4) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &extend_p->data5) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &extend_p->data6) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &extend_p->data7) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &extend_p->data8) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &extend_p->data9) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &extend_p->data10) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &extend_p->data11) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &extend_p->data12) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_extension(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_extension_s* extend_p = (ctsvc_extension_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(extend_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_int((extend_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((extend_p->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((extend_p->data1),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((extend_p->data2),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((extend_p->data3),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((extend_p->data4),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((extend_p->data5),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((extend_p->data6),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((extend_p->data7),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((extend_p->data8),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((extend_p->data9),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((extend_p->data10),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((extend_p->data11),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((extend_p->data12),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_extension_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_EXTENSION_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
+
diff --git a/common/ipc/ctsvc_ipc_group.c b/common/ipc/ctsvc_ipc_group.c
new file mode 100644 (file)
index 0000000..52c20ef
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_group(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_group(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_group_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_group_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_group,
+       .marshal_record = __ctsvc_ipc_marshal_group,
+       .get_primary_id = __ctsvc_ipc_marshal_group_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_group(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_group_s* group_p = (ctsvc_group_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &group_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &group_p->addressbook_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &group_p->is_read_only) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &group_p->name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &group_p->extra_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &group_p->ringtone_path) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &group_p->vibration) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &group_p->message_alert) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &group_p->image_thumbnail_path) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_group(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_group_s* group_p = (ctsvc_group_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(group_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_int((group_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((group_p->addressbook_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_bool((group_p->is_read_only),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((group_p->name),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((group_p->extra_data),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((group_p->ringtone_path),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((group_p->vibration),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((group_p->message_alert),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((group_p->image_thumbnail_path),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_group_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_GROUP_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_grouprelation.c b/common/ipc/ctsvc_ipc_grouprelation.c
new file mode 100644 (file)
index 0000000..710733f
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_group_relation(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_group_relation(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_group_relation_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_group_relation_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_group_relation,
+       .marshal_record = __ctsvc_ipc_marshal_group_relation,
+       .get_primary_id = __ctsvc_ipc_marshal_group_relation_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_group_relation(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_group_relation_s* group_relation_p = (ctsvc_group_relation_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &group_relation_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &group_relation_p->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &group_relation_p->group_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &group_relation_p->group_name) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_group_relation(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_group_relation_s* group_relation_p = (ctsvc_group_relation_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(group_relation_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_int((group_relation_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((group_relation_p->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((group_relation_p->group_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((group_relation_p->group_name),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_group_relation_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_GROUP_RELATION_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_image.c b/common/ipc/ctsvc_ipc_image.c
new file mode 100644 (file)
index 0000000..0772f72
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_image(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_image(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_image_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_image_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_image,
+       .marshal_record = __ctsvc_ipc_marshal_image,
+       .get_primary_id = __ctsvc_ipc_marshal_image_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_image(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_image_s* image_p = (ctsvc_image_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &image_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &image_p->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &image_p->type) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &image_p->label) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &image_p->path) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &image_p->is_default) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_image(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_image_s* image_p = (ctsvc_image_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(image_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_int((image_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((image_p->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((image_p->type),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((image_p->label),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((image_p->path),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_bool((image_p->is_default),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_image_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_IMAGE_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_marshal.c b/common/ipc/ctsvc_ipc_marshal.c
new file mode 100644 (file)
index 0000000..881bec0
--- /dev/null
@@ -0,0 +1,1291 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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> //calloc
+#include <string.h>
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+#include "ctsvc_internal.h"
+#include "contacts_query.h"
+#include "contacts_filter.h"
+#include "contacts_list.h"
+#include "ctsvc_list.h"
+
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_contact_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_my_profile_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_addressbook_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_group_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_person_plugin_cb;
+#ifdef ENABLE_LOG_FEATURE
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_phonelog_plugin_cb;
+#endif // ENABLE_LOG_FEATURE
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_result_plugin_cb;
+#ifdef ENABLE_SIM_FEATURE
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_sdn_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_speeddial_plugin_cb;
+#endif // ENABLE_SIM_FEATURE
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_updated_info_plugin_cb;
+
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_simple_contact_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_address_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_activity_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_activity_photo_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_company_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_email_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_event_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_extension_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_group_relation_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_messenger_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_name_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_nickname_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_note_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_number_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_profile_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_relationship_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_url_plugin_cb;
+extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_image_plugin_cb;
+
+static ctsvc_ipc_marshal_record_plugin_cb_s* __ctsvc_ipc_marshal_get_plugin_cb(ctsvc_record_type_e type);
+
+
+static int __ctsvc_ipc_unmarshal_composite_filter(const pims_ipc_data_h ipc_data, ctsvc_composite_filter_s* filter);
+static int __ctsvc_ipc_marshal_composite_filter(const ctsvc_composite_filter_s* filter, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_unmarshal_attribute_filter(const pims_ipc_data_h ipc_data, const ctsvc_filter_type_e filter_type, ctsvc_attribute_filter_s* filter);
+static int __ctsvc_ipc_marshal_attribute_filter(const ctsvc_attribute_filter_s* filter, pims_ipc_data_h ipc_data);
+
+
+static ctsvc_ipc_marshal_record_plugin_cb_s* __ctsvc_ipc_marshal_get_plugin_cb(ctsvc_record_type_e type)
+{
+       switch (type)
+       {
+       case CTSVC_RECORD_ADDRESSBOOK:
+               return (&_ctsvc_ipc_record_addressbook_plugin_cb);
+       case CTSVC_RECORD_GROUP:
+               return (&_ctsvc_ipc_record_group_plugin_cb);
+       case CTSVC_RECORD_PERSON:
+               return (&_ctsvc_ipc_record_person_plugin_cb);
+       case CTSVC_RECORD_CONTACT:
+               return (&_ctsvc_ipc_record_contact_plugin_cb);
+       case CTSVC_RECORD_MY_PROFILE:
+               return (&_ctsvc_ipc_record_my_profile_plugin_cb);
+       case CTSVC_RECORD_UPDATED_INFO:
+               return (&_ctsvc_ipc_record_updated_info_plugin_cb);
+#ifdef ENABLE_LOG_FEATURE
+       case CTSVC_RECORD_PHONELOG:
+               return (&_ctsvc_ipc_record_phonelog_plugin_cb);
+#endif // ENABLE_LOG_FEATURE
+#ifdef ENABLE_SIM_FEATURE
+       case CTSVC_RECORD_SPEEDDIAL:
+               return (&_ctsvc_ipc_record_speeddial_plugin_cb);
+       case CTSVC_RECORD_SDN:
+               return (&_ctsvc_ipc_record_sdn_plugin_cb);
+#endif // ENABLE_SIM_FEATURE
+       case CTSVC_RECORD_RESULT:
+               return (&_ctsvc_ipc_record_result_plugin_cb);
+       case CTSVC_RECORD_SIMPLE_CONTACT:
+               return &_ctsvc_ipc_record_simple_contact_plugin_cb;
+       case CTSVC_RECORD_NAME:
+               return (&_ctsvc_ipc_record_name_plugin_cb);
+       case CTSVC_RECORD_COMPANY:
+               return (&_ctsvc_ipc_record_company_plugin_cb);
+       case CTSVC_RECORD_NOTE:
+               return (&_ctsvc_ipc_record_note_plugin_cb);
+       case CTSVC_RECORD_NUMBER:
+               return (&_ctsvc_ipc_record_number_plugin_cb);
+       case CTSVC_RECORD_EMAIL:
+               return (&_ctsvc_ipc_record_email_plugin_cb);
+       case CTSVC_RECORD_URL:
+               return (&_ctsvc_ipc_record_url_plugin_cb);
+       case CTSVC_RECORD_EVENT:
+               return (&_ctsvc_ipc_record_event_plugin_cb);
+       case CTSVC_RECORD_NICKNAME:
+               return (&_ctsvc_ipc_record_nickname_plugin_cb);
+       case CTSVC_RECORD_ADDRESS:
+               return (&_ctsvc_ipc_record_address_plugin_cb);
+       case CTSVC_RECORD_MESSENGER:
+               return (&_ctsvc_ipc_record_messenger_plugin_cb);
+       case CTSVC_RECORD_GROUP_RELATION:
+               return (&_ctsvc_ipc_record_group_relation_plugin_cb);
+       case CTSVC_RECORD_ACTIVITY:
+               return (&_ctsvc_ipc_record_activity_plugin_cb);
+       case CTSVC_RECORD_ACTIVITY_PHOTO:
+               return (&_ctsvc_ipc_record_activity_photo_plugin_cb);
+       case CTSVC_RECORD_PROFILE:
+               return (&_ctsvc_ipc_record_profile_plugin_cb);
+       case CTSVC_RECORD_RELATIONSHIP:
+               return (&_ctsvc_ipc_record_relationship_plugin_cb);
+       case CTSVC_RECORD_IMAGE:
+               return (&_ctsvc_ipc_record_image_plugin_cb);
+       case CTSVC_RECORD_EXTENSION:
+               return (&_ctsvc_ipc_record_extension_plugin_cb);
+       default:
+               ASSERT_NOT_REACHED("Unimplemented IPC module (%d)", type);
+               return NULL;
+       }
+}
+
+static void __ctsvc_ipc_unmarshal_composite_filter_free(ctsvc_composite_filter_s* filter)
+{
+       if (filter->filters) {
+               GSList *cursor = NULL;
+               for(cursor=filter->filters;cursor;cursor=cursor->next) {
+                       ctsvc_filter_s *src = (ctsvc_filter_s*)cursor->data;
+                       if (src->filter_type == CTSVC_FILTER_COMPOSITE)
+                               __ctsvc_ipc_unmarshal_composite_filter_free((ctsvc_composite_filter_s *)src);
+                       else {
+                               ctsvc_attribute_filter_s *attr = (ctsvc_attribute_filter_s *)src;
+                               if (attr->filter_type == CTSVC_FILTER_STR)
+                                       free(attr->value.s);
+                       }
+                       free(src);
+               }
+               g_slist_free(filter->filters);
+       }
+
+       if (filter->filter_ops) {
+               g_slist_free(filter->filter_ops);
+       }
+
+       free(filter->view_uri);
+}
+
+static int __ctsvc_ipc_unmarshal_composite_filter(const pims_ipc_data_h ipc_data, ctsvc_composite_filter_s* filter)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       unsigned int size = 0;
+       char* str = NULL;
+       int count =0, i=0;
+       ctsvc_filter_type_e filter_type = CTSVC_FILTER_COMPOSITE;
+       contacts_filter_operator_e op = CONTACTS_FILTER_OPERATOR_AND;
+
+       filter->filter_type = CTSVC_FILTER_COMPOSITE;
+
+       // view_uri
+       str = (char*)pims_ipc_data_get(ipc_data,&size);
+       filter->view_uri = (char*)SAFE_STRDUP(str);
+
+       // filters
+       if (ctsvc_ipc_unmarshal_int(ipc_data,&count) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_unmarshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       for(i=0;i<count;i++)
+       {
+               if (ctsvc_ipc_unmarshal_int(ipc_data,(int*)&filter_type) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+                       ret = CONTACTS_ERROR_INVALID_PARAMETER;
+                       goto ERROR_RETURN;
+               }
+               if (filter_type == CTSVC_FILTER_COMPOSITE)
+               {
+                       ctsvc_composite_filter_s* com_filter = NULL;
+                       com_filter = (ctsvc_composite_filter_s*)calloc(1,sizeof(ctsvc_composite_filter_s));
+                       if (com_filter == NULL)
+                       {
+                               CTS_ERR("calloc fail");
+                               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                               goto ERROR_RETURN;
+                       }
+                       if (__ctsvc_ipc_unmarshal_composite_filter(ipc_data, com_filter) != CONTACTS_ERROR_NONE)
+                       {
+                               CTS_ERR("_ctsvc_ipc_unmarshal fail");
+                               ret = CONTACTS_ERROR_INVALID_PARAMETER;
+                               CONTACTS_FREE(com_filter);
+                               goto ERROR_RETURN;
+                       }
+                       filter->filters = g_slist_append(filter->filters,com_filter);
+               }
+               else
+               {
+                       ctsvc_attribute_filter_s* attr_filter = NULL;
+                       attr_filter = (ctsvc_attribute_filter_s*)calloc(1,sizeof(ctsvc_attribute_filter_s));
+                       if (attr_filter == NULL)
+                       {
+                               CTS_ERR("calloc fail");
+                               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                               goto ERROR_RETURN;
+                       }
+                       if (__ctsvc_ipc_unmarshal_attribute_filter(ipc_data, filter_type, attr_filter) != CONTACTS_ERROR_NONE)
+                       {
+                               CTS_ERR("_ctsvc_ipc_unmarshal fail");
+                               ret =  CONTACTS_ERROR_INVALID_PARAMETER;
+                               CONTACTS_FREE(attr_filter);
+                               goto ERROR_RETURN;
+                       }
+                       filter->filters = g_slist_append(filter->filters,attr_filter);
+               }
+       }
+
+       // filters
+       if (ctsvc_ipc_unmarshal_int(ipc_data,&count) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_unmarshal fail");
+               ret =  CONTACTS_ERROR_INVALID_PARAMETER;
+               goto ERROR_RETURN;
+       }
+
+       for(i=0;i<count;i++)
+       {
+               if (ctsvc_ipc_unmarshal_int(ipc_data,(int*)&op) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+                       ret =  CONTACTS_ERROR_INVALID_PARAMETER;
+                       goto ERROR_RETURN;
+               }
+               filter->filter_ops = g_slist_append(filter->filter_ops, (void*)op);
+       }
+
+       // properties //property_count
+       filter->properties = (property_info_s *)ctsvc_view_get_all_property_infos(filter->view_uri, &filter->property_count);
+
+       return CONTACTS_ERROR_NONE;
+
+ERROR_RETURN:
+       __ctsvc_ipc_unmarshal_composite_filter_free(filter);
+       return ret;
+}
+
+static int __ctsvc_ipc_marshal_composite_filter(const ctsvc_composite_filter_s* filter, pims_ipc_data_h ipc_data)
+{
+       if (ctsvc_ipc_marshal_int((filter->filter_type),ipc_data) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_marshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       // view_uri
+       int length = strlen(filter->view_uri);
+       if (pims_ipc_data_put(ipc_data,(void*)filter->view_uri,length+1) < 0)
+       {
+               CTS_ERR("_ctsvc_ipc_marshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       // filter->filters
+       if (filter->filters)
+       {
+               int count = g_slist_length(filter->filters);
+               GSList *cursor = filter->filters;
+               ctsvc_filter_s* child_filter;
+
+               if (ctsvc_ipc_marshal_int(count,ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               while (cursor)
+               {
+                       child_filter = (ctsvc_filter_s*)cursor->data;
+
+                       if (child_filter->filter_type == CTSVC_FILTER_COMPOSITE)
+                       {
+                               if (__ctsvc_ipc_marshal_composite_filter((ctsvc_composite_filter_s*)child_filter, ipc_data) != CONTACTS_ERROR_NONE)
+                               {
+                                       CTS_ERR("__ctsvc_ipc_marshal_composite_filter fail");
+                                       return CONTACTS_ERROR_INVALID_PARAMETER;
+                               }
+                       }
+                       else
+                       {
+                               if (__ctsvc_ipc_marshal_attribute_filter((ctsvc_attribute_filter_s*)child_filter, ipc_data) != CONTACTS_ERROR_NONE)
+                               {
+                                       CTS_ERR("__ctsvc_ipc_marshal_attribute_filter fail");
+                                       return CONTACTS_ERROR_INVALID_PARAMETER;
+                               }
+                       }
+                       cursor = g_slist_next(cursor);
+               }
+       }
+       else
+       {
+               if (ctsvc_ipc_marshal_int(0,ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+
+       if (filter->filter_ops)
+       {
+               int count = g_slist_length(filter->filter_ops);
+               GSList *cursor = filter->filter_ops;
+
+               if (ctsvc_ipc_marshal_int(count,ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               while (cursor)
+               {
+                       contacts_filter_operator_e op = (contacts_filter_operator_e)cursor->data;
+
+                       if (ctsvc_ipc_marshal_int(op,ipc_data) != CONTACTS_ERROR_NONE)
+                       {
+                               CTS_ERR("_ctsvc_ipc_marshal fail");
+                               return CONTACTS_ERROR_INVALID_PARAMETER;
+                       }
+
+                       cursor = g_slist_next(cursor);
+               }
+       }
+       else
+       {
+               if (ctsvc_ipc_marshal_int(0,ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+
+       // properties //property_count
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_ipc_unmarshal_attribute_filter(const pims_ipc_data_h ipc_data, const ctsvc_filter_type_e filter_type, ctsvc_attribute_filter_s* filter)
+{
+       filter->filter_type = filter_type;
+       if (ctsvc_ipc_unmarshal_int(ipc_data,&filter->property_id) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_unmarshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       if (ctsvc_ipc_unmarshal_int(ipc_data,&filter->match) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_unmarshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       switch(filter->filter_type)
+       {
+       case CTSVC_FILTER_STR:
+               if (ctsvc_ipc_unmarshal_string(ipc_data,&filter->value.s) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               break;
+       case CTSVC_FILTER_INT:
+               if (ctsvc_ipc_unmarshal_int(ipc_data,&filter->value.i) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               break;
+       case CTSVC_FILTER_BOOL:
+               if (ctsvc_ipc_unmarshal_bool(ipc_data,&filter->value.b) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               break;
+       case CTSVC_FILTER_DOUBLE:
+               if (ctsvc_ipc_unmarshal_double(ipc_data,&filter->value.d) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               break;
+       case CTSVC_FILTER_LLI:
+               if (ctsvc_ipc_unmarshal_lli(ipc_data,&filter->value.l) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               break;
+       default:
+               break;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_ipc_marshal_attribute_filter(const ctsvc_attribute_filter_s* filter, pims_ipc_data_h ipc_data)
+{
+       if (ctsvc_ipc_marshal_int((filter->filter_type),ipc_data) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_marshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       if (ctsvc_ipc_marshal_int((filter->property_id),ipc_data) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_marshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       if (ctsvc_ipc_marshal_int((filter->match),ipc_data) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_marshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       switch(filter->filter_type)
+       {
+       case CTSVC_FILTER_STR:
+               if (ctsvc_ipc_marshal_string((filter->value.s),ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               break;
+       case CTSVC_FILTER_INT:
+               if (ctsvc_ipc_marshal_int((filter->value.i),ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               break;
+       case CTSVC_FILTER_BOOL:
+               if (ctsvc_ipc_marshal_bool((filter->value.b),ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               break;
+       case CTSVC_FILTER_DOUBLE:
+               if (ctsvc_ipc_marshal_double((filter->value.d),ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               break;
+       case CTSVC_FILTER_LLI:
+               if (ctsvc_ipc_marshal_lli((filter->value.l),ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               break;
+       default:
+               break;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+
+int ctsvc_ipc_unmarshal_record(const pims_ipc_data_h ipc_data, contacts_record_h* precord)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       ctsvc_record_s common = {0,};
+       ctsvc_record_s *precord_common = NULL;
+       ctsvc_ipc_marshal_record_plugin_cb_s *plugin_cb;
+
+       RETVM_IF( NULL == precord || NULL == ipc_data, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       if (ctsvc_ipc_unmarshal_record_common(ipc_data, &common) != CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_ipc_unmarshal_common fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       plugin_cb = __ctsvc_ipc_marshal_get_plugin_cb(common.r_type);
+       if (NULL == plugin_cb || NULL == plugin_cb->unmarshal_record) {
+               CTS_ERR("Invalid parameter");
+               free(common.properties_flags);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = contacts_record_create(common.view_uri, precord);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("create activity record fail");
+               free(common.properties_flags);
+               return ret;
+       }
+
+       precord_common = (ctsvc_record_s *)(*precord);
+       precord_common->property_max_count = common.property_max_count;
+       precord_common->properties_flags = common.properties_flags;
+       precord_common->property_flag = common.property_flag;
+
+       ret = plugin_cb->unmarshal_record(ipc_data, common.view_uri, *precord);
+       if( CONTACTS_ERROR_NONE != ret )
+       {
+               contacts_record_destroy(*precord,true);
+               *precord = NULL;
+               return CONTACTS_ERROR_IPC;
+       }
+
+       return ret;
+}
+
+int ctsvc_ipc_marshal_record(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       RETVM_IF(NULL == record || NULL == ipc_data, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       ctsvc_record_s *common = (ctsvc_record_s*)(record);
+
+       if (ctsvc_ipc_marshal_record_common(common, ipc_data) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("ctsvc_ipc_marshal_common fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       ctsvc_ipc_marshal_record_plugin_cb_s *plugin_cb = __ctsvc_ipc_marshal_get_plugin_cb(common->r_type);
+
+       RETVM_IF(NULL == plugin_cb || NULL == plugin_cb->marshal_record, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       int ret = plugin_cb->marshal_record(record, ipc_data);
+
+       return ret;
+}
+
+int ctsvc_ipc_marshal_record_get_primary_id(const contacts_record_h record,
+               unsigned int *property_id, int *id)
+{
+       RETVM_IF(NULL == record || NULL == property_id || NULL == id, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       ctsvc_record_s *temp = (ctsvc_record_s*)(record);
+
+       ctsvc_ipc_marshal_record_plugin_cb_s *plugin_cb = __ctsvc_ipc_marshal_get_plugin_cb(temp->r_type);
+
+       RETVM_IF(NULL == plugin_cb || NULL == plugin_cb->get_primary_id, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       int ret = plugin_cb->get_primary_id(record, property_id,id);
+
+       return ret;
+}
+
+int ctsvc_ipc_unmarshal_string(const pims_ipc_data_h ipc_data, char** ppbufchar)
+{
+       int ret = CONTACTS_ERROR_NONE;
+
+       void *tmp = NULL;
+       unsigned int size = 0;
+       char *str = NULL;
+
+       int length = 0;
+
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(ppbufchar==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+
+       tmp = pims_ipc_data_get(ipc_data,&size);
+       if ( tmp == NULL){
+               CTS_ERR("pims_ipc_data_get string fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       length = *(int*)tmp;
+
+       if(length == -1)
+       {
+               ret = CONTACTS_ERROR_NONE;
+               CTS_VERBOSE("string is null");
+               *ppbufchar = NULL;
+               return ret;
+       }
+
+       str = (char*)pims_ipc_data_get(ipc_data,&size);
+       if (str)
+       {
+               *ppbufchar = SAFE_STRDUP(str);
+       }
+
+       return ret;
+}
+
+int ctsvc_ipc_unmarshal_int(const pims_ipc_data_h data, int *pout)
+{
+       RETV_IF(data==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(pout==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+
+       unsigned int size = 0;
+       void *tmp = pims_ipc_data_get(data,&size);
+       if ( tmp == NULL)
+       {
+               CTS_ERR("pims_ipc_data_get int fail");
+               return CONTACTS_ERROR_NO_DATA;
+       }
+       else
+       {
+               *pout = *(int*)tmp;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_unmarshal_unsigned_int(const pims_ipc_data_h data, unsigned int *pout)
+{
+       RETV_IF(data==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(pout==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+
+       unsigned int size = 0;
+       void *tmp = pims_ipc_data_get(data,&size);
+       if ( tmp == NULL)
+       {
+               CTS_ERR("pims_ipc_data_get unsigned int fail");
+               return CONTACTS_ERROR_NO_DATA;
+       }
+       else
+       {
+               *pout = *(unsigned int*)tmp;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_unmarshal_bool(const pims_ipc_data_h data, bool *pout)
+{
+       RETV_IF(data==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(pout==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+
+       unsigned int size = 0;
+       void *tmp = pims_ipc_data_get(data,&size);
+       if ( tmp == NULL)
+       {
+               CTS_ERR("pims_ipc_data_get bool fail");
+               return CONTACTS_ERROR_NO_DATA;
+       }
+       else
+       {
+               *pout = *(bool*)tmp;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_unmarshal_lli(const pims_ipc_data_h data, long long int *pout)
+{
+       RETV_IF(data==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(pout==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+
+       unsigned int size = 0;
+       void *tmp = pims_ipc_data_get(data,&size);
+       if ( tmp == NULL)
+       {
+               CTS_ERR("pims_ipc_data_get lli fail");
+               return CONTACTS_ERROR_NO_DATA;
+       }
+       else
+       {
+               *pout = *(long long int*)tmp;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_unmarshal_long(const pims_ipc_data_h data, long *pout)
+{
+       RETV_IF(data==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(pout==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+
+       unsigned int size = 0;
+       void *tmp = pims_ipc_data_get(data, &size);
+       if ( tmp == NULL )
+       {
+               CTS_ERR("pims_ipc_data_get long fail");
+               return CONTACTS_ERROR_NO_DATA;
+       }
+       else
+       {
+               *pout = *(long*)tmp;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_unmarshal_double(const pims_ipc_data_h data, double *pout)
+{
+       RETV_IF(data==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(pout==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+
+       unsigned int size = 0;
+       void* tmp = pims_ipc_data_get(data,&size);
+       if ( tmp == NULL)
+       {
+               CTS_ERR("pims_ipc_data_get double fail");
+               return CONTACTS_ERROR_NO_DATA;
+       }
+       else
+       {
+               *pout = *(double*)tmp;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_unmarshal_record_common(const pims_ipc_data_h ipc_data, ctsvc_record_s* common)
+{
+       void *tmp = NULL;
+       unsigned int size = 0;
+       const char* str = NULL;
+
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       tmp = pims_ipc_data_get(ipc_data,&size);
+       if ( tmp == NULL)
+       {
+               CTS_ERR("pims_ipc_data_get fail");
+               return CONTACTS_ERROR_NO_DATA;
+       }
+       else
+       {
+               common->r_type = *(ctsvc_record_type_e*)tmp;
+       }
+
+       str = (char*)pims_ipc_data_get(ipc_data,&size);
+       common->view_uri = ctsvc_view_get_uri(str);
+       ctsvc_ipc_unmarshal_unsigned_int(ipc_data, &(common->property_max_count));
+
+       if (common->property_max_count > 0) {
+               unsigned char *tmp_properties_flags;
+               tmp_properties_flags = (unsigned char*)pims_ipc_data_get(ipc_data, &size);
+               if (NULL == tmp_properties_flags) {
+                       CTS_ERR("pims_ipc_data_get() return NULL");
+                       return CONTACTS_ERROR_IPC;
+               }
+               common->properties_flags  = calloc(common->property_max_count, sizeof(char));
+               if (common->properties_flags == NULL) {
+                       CTS_ERR("calloc fail");
+                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+               }
+               memcpy(common->properties_flags, tmp_properties_flags, sizeof(char)*common->property_max_count);
+       }
+       tmp = pims_ipc_data_get(ipc_data,&size);
+       RETVM_IF(NULL == tmp, CONTACTS_ERROR_NO_DATA, "pims_ipc_data_get() return NULL");
+       common->property_flag = *(unsigned char*)tmp;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_marshal_string(const char* bufchar, pims_ipc_data_h ipc_data)
+{
+       int ret = CONTACTS_ERROR_NONE;
+
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+
+       if( bufchar != NULL)
+       {
+               int length = strlen(bufchar);
+               if (pims_ipc_data_put(ipc_data,(void*)&length,sizeof(int)) != 0)
+               {
+                       ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               }
+
+               if ( pims_ipc_data_put(ipc_data,(void*)bufchar,length+1) != 0)
+               {
+                       ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                       return ret;
+               }
+       }
+       else
+       {
+               int length = -1;
+
+               if (pims_ipc_data_put(ipc_data,(void*)&length,sizeof(int)) != 0)
+               {
+                       ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               }
+       }
+       return ret;
+}
+
+int ctsvc_ipc_marshal_int(const int in, pims_ipc_data_h ipc_data)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+
+       if (pims_ipc_data_put(ipc_data,(void*)&in,sizeof(int)) != 0)
+       {
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_marshal_unsigned_int(const unsigned int in, pims_ipc_data_h ipc_data)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+
+       if (pims_ipc_data_put(ipc_data,(void*)&in,sizeof(unsigned int)) != 0)
+       {
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_marshal_bool(const bool in, pims_ipc_data_h ipc_data)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+
+       if (pims_ipc_data_put(ipc_data,(void*)&in,sizeof(bool)) != 0)
+       {
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_marshal_lli(const long long int in, pims_ipc_data_h ipc_data)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+
+       if (pims_ipc_data_put(ipc_data,(void*)&in,sizeof(long long int)) != 0)
+       {
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_marshal_long(const long in, pims_ipc_data_h ipc_data)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+
+       if (pims_ipc_data_put(ipc_data,(void*)&in,sizeof(long)) != 0)
+       {
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_marshal_double(const double in, pims_ipc_data_h ipc_data)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_INVALID_PARAMETER);
+
+       if (pims_ipc_data_put(ipc_data,(void*)&in,sizeof(double)) != 0)
+       {
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_marshal_record_common(const ctsvc_record_s* common, pims_ipc_data_h ipc_data)
+{
+
+       RETV_IF(NULL == common, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == ipc_data, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       if(pims_ipc_data_put(ipc_data,(void*)&common->r_type,sizeof(int)) < 0)
+       {
+               return CONTACTS_ERROR_NO_DATA;
+       }
+
+       int length = strlen(common->view_uri);
+       if (pims_ipc_data_put(ipc_data,(void*)common->view_uri,length+1) < 0)
+       {
+               CTS_ERR("_ctsvc_ipc_marshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (pims_ipc_data_put(ipc_data,(void*)&common->property_max_count,sizeof(unsigned int)) < 0)
+       {
+               return CONTACTS_ERROR_NO_DATA;
+       }
+
+       if (0 < common->property_max_count)
+       {
+               if (pims_ipc_data_put(ipc_data,(void*)common->properties_flags,sizeof(unsigned char)*common->property_max_count) < 0)
+               {
+                       CTS_ERR("_ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_NO_DATA;
+               }
+       }
+
+       if (pims_ipc_data_put(ipc_data,(void*)&common->property_flag,sizeof(char)) < 0)
+       {
+               return CONTACTS_ERROR_NO_DATA;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_unmarshal_query(const pims_ipc_data_h ipc_data, contacts_query_h *query)
+{
+       ctsvc_query_s *que = NULL;
+       unsigned int size = 0;
+       char* str = NULL;
+       unsigned int count = 0, i = 0;
+       int ret = CONTACTS_ERROR_NONE;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == ipc_data, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       // view_uri
+       str = (char*)pims_ipc_data_get(ipc_data,&size);
+
+       ret = contacts_query_create(str, query);
+       if (ret != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("contacts_query_create fail");
+               return ret;
+       }
+
+       que = (ctsvc_query_s *) *query;
+
+       if (ctsvc_ipc_unmarshal_unsigned_int(ipc_data,&count) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_unmarshal fail");
+               ret = CONTACTS_ERROR_INVALID_PARAMETER;
+               goto ERROR_RETURN;
+       }
+
+       if (count == 0)
+       {
+               que->filter = NULL;
+       }
+       else
+       {
+               ctsvc_composite_filter_s *filter = NULL;
+               filter = (ctsvc_composite_filter_s *)calloc(1, sizeof(ctsvc_composite_filter_s));
+               if (NULL == filter) {
+                       CTS_ERR("calloc fail");
+                       ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                       goto ERROR_RETURN;
+               }
+               filter->filter_type = CTSVC_FILTER_COMPOSITE;
+               filter->properties = (property_info_s *)ctsvc_view_get_all_property_infos(que->view_uri, &filter->property_count);
+               que->filter = filter;
+
+               // for filter_type
+               if (ctsvc_ipc_unmarshal_unsigned_int(ipc_data, &count) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+                       ret = CONTACTS_ERROR_INVALID_PARAMETER;
+                       goto ERROR_RETURN;
+               }
+
+               if (__ctsvc_ipc_unmarshal_composite_filter(ipc_data,que->filter) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+                       ret = CONTACTS_ERROR_INVALID_PARAMETER;
+                       goto ERROR_RETURN;
+               }
+       }
+
+       if (ctsvc_ipc_unmarshal_unsigned_int(ipc_data,&(que->projection_count)) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_unmarshal fail");
+               ret = CONTACTS_ERROR_INVALID_PARAMETER;
+               goto ERROR_RETURN;
+       }
+
+       if (que->projection_count > 0)
+       {
+               que->projection = (unsigned int*)malloc(sizeof(unsigned int)*que->projection_count);
+               if (que->projection == NULL)
+               {
+                       CTS_ERR("malloc fail");
+                       ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                       goto ERROR_RETURN;
+               }
+               for(i=0;i<que->projection_count;i++)
+               {
+                       if (ctsvc_ipc_unmarshal_unsigned_int(ipc_data,&(que->projection[i])) != CONTACTS_ERROR_NONE)
+                       {
+                               CTS_ERR("_ctsvc_ipc_unmarshal fail");
+                               ret = CONTACTS_ERROR_INVALID_PARAMETER;
+                               goto ERROR_RETURN;
+                       }
+               }
+       }
+       else
+       {
+               que->projection = NULL;
+       }
+
+       if (ctsvc_ipc_unmarshal_unsigned_int(ipc_data,&(que->sort_property_id)) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_unmarshal fail");
+               ret = CONTACTS_ERROR_INVALID_PARAMETER;
+               goto ERROR_RETURN;
+       }
+
+       if (ctsvc_ipc_unmarshal_bool(ipc_data,&(que->sort_asc)) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_unmarshal fail");
+               ret = CONTACTS_ERROR_INVALID_PARAMETER;
+               goto ERROR_RETURN;
+       }
+
+       if (ctsvc_ipc_unmarshal_bool(ipc_data,&(que->distinct)) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_unmarshal fail");
+               ret = CONTACTS_ERROR_INVALID_PARAMETER;
+               goto ERROR_RETURN;
+       }
+
+       return CONTACTS_ERROR_NONE;
+
+ERROR_RETURN:
+       contacts_query_destroy(*query);
+       *query = NULL;
+
+       return ret;
+}
+
+int ctsvc_ipc_marshal_query(const contacts_query_h query, pims_ipc_data_h ipc_data)
+{
+       ctsvc_query_s *que = NULL;
+       int i = 0;
+       int length = 0;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == ipc_data, CONTACTS_ERROR_INVALID_PARAMETER);
+       que = (ctsvc_query_s *)query;
+
+       //view_uri
+       length = strlen(que->view_uri);
+       if (pims_ipc_data_put(ipc_data,(void*)que->view_uri,length+1) < 0)
+       {
+               CTS_ERR("_ctsvc_ipc_marshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (que->filter)
+       {
+               if (ctsvc_ipc_marshal_int(1,ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+
+               if (__ctsvc_ipc_marshal_composite_filter(que->filter,ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+       else
+       {
+               if (ctsvc_ipc_marshal_int(0,ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+
+       if (ctsvc_ipc_marshal_unsigned_int(que->projection_count,ipc_data) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_marshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       for(i=0;i<que->projection_count;i++)
+       {
+               if (ctsvc_ipc_marshal_unsigned_int(que->projection[i],ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+
+       if (ctsvc_ipc_marshal_unsigned_int(que->sort_property_id,ipc_data) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_marshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (ctsvc_ipc_marshal_bool(que->sort_asc,ipc_data) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_marshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (ctsvc_ipc_marshal_bool(que->distinct,ipc_data) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_marshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       //properties // property_count
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_unmarshal_list(const pims_ipc_data_h ipc_data, contacts_list_h* list)
+{
+       int count = 0;
+       unsigned int deleted_count = 0;
+       contacts_record_h record;
+       int ret = CONTACTS_ERROR_NONE;
+
+       RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == ipc_data, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       if (contacts_list_create(list) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("contacts_list_create fail");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       if (ctsvc_ipc_unmarshal_int(ipc_data,&(count)) != CONTACTS_ERROR_NONE)
+       {
+               contacts_list_destroy(*list, true);
+               CTS_ERR("_ctsvc_ipc_unmarshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       unsigned int i = 0;
+       for(i=0;i<count;i++)
+       {
+               if (ctsvc_ipc_unmarshal_record(ipc_data,&record) != CONTACTS_ERROR_NONE )
+               {
+                       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+                       ret = CONTACTS_ERROR_INVALID_PARAMETER;
+                       goto ERROR_RETURN;
+               }
+
+               if (contacts_list_add(*list,record) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("contacts_list_add fail");
+                       ret = CONTACTS_ERROR_INVALID_PARAMETER;
+                       goto ERROR_RETURN;
+               }
+       }
+
+       if (ctsvc_ipc_unmarshal_unsigned_int(ipc_data,&deleted_count) != CONTACTS_ERROR_NONE) {
+               CTS_ERR("_ctsvc_ipc_unmarshal fail");
+               ret = CONTACTS_ERROR_INVALID_PARAMETER;
+               goto ERROR_RETURN;
+       }
+
+       i = 0;
+       for(i=0;i<deleted_count;i++)
+       {
+               if (ctsvc_ipc_unmarshal_record(ipc_data,&record) != CONTACTS_ERROR_NONE )
+               {
+                       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+                       ret = CONTACTS_ERROR_INVALID_PARAMETER;
+                       goto ERROR_RETURN;
+               }
+
+               if (ctsvc_list_append_deleted_record(*list,record) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("contacts_list_add fail");
+                       ret = CONTACTS_ERROR_INVALID_PARAMETER;
+                       goto ERROR_RETURN;
+               }
+       }
+
+       return CONTACTS_ERROR_NONE;
+
+ERROR_RETURN:
+       if (*list)
+       {
+               contacts_list_destroy(*list, true);
+               *list = NULL;
+       }
+
+       return ret;
+}
+
+int ctsvc_ipc_unmarshal_child_list(const pims_ipc_data_h ipc_data, contacts_list_h* list)
+{
+       unsigned int i = 0;
+       int count = 0;
+       unsigned int deleted_count = 0;
+       contacts_record_h record;
+
+       RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == ipc_data, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       if (ctsvc_ipc_unmarshal_int(ipc_data,&(count)) != CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       for(i=0;i<count;i++) {
+               if (ctsvc_ipc_unmarshal_record(ipc_data,&record) != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_record fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+
+               if (contacts_list_add(*list,record) != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("contacts_list_add fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+
+       if (ctsvc_ipc_unmarshal_unsigned_int(ipc_data,&deleted_count) != CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_ipc_unmarshal_unsigned_int fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       i = 0;
+       for(i=0;i<deleted_count;i++) {
+               if (ctsvc_ipc_unmarshal_record(ipc_data,&record) != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_record fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+
+               if (ctsvc_list_append_deleted_record(*list,record) != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_list_append_deleted_record fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_ipc_marshal_list(const contacts_list_h list, pims_ipc_data_h ipc_data)
+{
+       int count = 0;
+       unsigned int deleted_count = 0;
+       contacts_record_h record;
+
+       RETV_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == ipc_data, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       // count
+       if (contacts_list_get_count(list, &count) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("contacts_list_get_count fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       if (ctsvc_ipc_marshal_int(count,ipc_data) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_marshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       contacts_list_first(list);
+
+       unsigned int i = 0;
+       for(i=0;i<count;i++)
+       {
+               if (contacts_list_get_current_record_p(list,&record) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("contacts_list_get_count fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               if (ctsvc_ipc_marshal_record(record,ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               if ( contacts_list_next(list) == CONTACTS_ERROR_NO_DATA )
+               {
+                       break;
+               }
+       }
+
+       // count
+       if (ctsvc_list_get_deleted_count(list, &deleted_count) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("contacts_list_get_count fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       if (ctsvc_ipc_marshal_int(deleted_count,ipc_data) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("_ctsvc_ipc_marshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       i = 0;
+       for(i=0;i<deleted_count;i++)
+       {
+               if (ctsvc_list_get_deleted_nth_record_p(list, i, &record) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("contacts_list_get_count fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               if (ctsvc_ipc_marshal_record(record,ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("_ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/common/ipc/ctsvc_ipc_marshal.h b/common/ipc/ctsvc_ipc_marshal.h
new file mode 100644 (file)
index 0000000..bf32e75
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __ctsvc_ipc_marshal__
+#define __ctsvc_ipc_marshal__
+
+#include <pims-ipc-data.h>
+#include "ctsvc_struct.h"
+#include "contacts_record.h"
+
+/*
+ * record
+ * pims_ipc_data_h 의 경우 생성된 사항을 넘겨받아야함
+ * unmarshal_record의 경우 plugin에서 struct를 alloc하여 return
+ * marshal : 각 plugin에서 cal_common_s + other 같이 marshal
+ * unmarshal : cal_common_s 는 먼저 marshal 하여, view_uri 만 넘겨준 이후,
+ *              각 plug in에서 cal_common_s를 제외 한 사항에 대하여 unmarshal
+ */
+typedef int (*ctsvc_ipc_unmarshal_record_cb)(const pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h precord);
+typedef int (*ctsvc_ipc_marshal_record_cb)(const contacts_record_h record, pims_ipc_data_h ipc_data);
+typedef int (*ctsvc_ipc_marshal_record_get_primary_id_cb)(const contacts_record_h record, unsigned int *property_id, int *id);
+
+typedef struct {
+    ctsvc_ipc_unmarshal_record_cb unmarshal_record;
+    ctsvc_ipc_marshal_record_cb marshal_record;
+    ctsvc_ipc_marshal_record_get_primary_id_cb get_primary_id;
+} ctsvc_ipc_marshal_record_plugin_cb_s;
+
+int ctsvc_ipc_unmarshal_record(const pims_ipc_data_h ipc_data, contacts_record_h* precord);
+int ctsvc_ipc_marshal_record(const contacts_record_h record, pims_ipc_data_h ipc_data);
+int ctsvc_ipc_marshal_record_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+/*
+ * string
+ * char의 경우 NULL 설정의 이슈로 인하여, [int:string length]+[char*] 로 넘길 수 있도록 설정..
+ */
+int ctsvc_ipc_unmarshal_string(const pims_ipc_data_h ipc_data, char** ppbufchar);
+int ctsvc_ipc_unmarshal_bool(const pims_ipc_data_h data, bool *pout);
+int ctsvc_ipc_unmarshal_int(const pims_ipc_data_h data, int *pout);
+int ctsvc_ipc_unmarshal_unsigned_int(const pims_ipc_data_h data, unsigned int *pout);
+int ctsvc_ipc_unmarshal_lli(const pims_ipc_data_h data, long long int *pout);
+int ctsvc_ipc_unmarshal_long(const pims_ipc_data_h data, long *pout);
+int ctsvc_ipc_unmarshal_double(const pims_ipc_data_h data, double *pout);
+int ctsvc_ipc_unmarshal_record_common(const pims_ipc_data_h ipc_data, ctsvc_record_s* common);
+
+/*
+ * NULL 이슈로 ctsvc_ipc_unmarshal_string / ctsvc_ipc_marshal_string 는 pair 를 이루어야함.
+ */
+int ctsvc_ipc_marshal_string(const char* bufchar, pims_ipc_data_h ipc_data);
+int ctsvc_ipc_marshal_bool(const bool in, pims_ipc_data_h ipc_data);
+int ctsvc_ipc_marshal_int(const int in, pims_ipc_data_h ipc_data);
+int ctsvc_ipc_marshal_unsigned_int(const unsigned int in, pims_ipc_data_h ipc_data);
+int ctsvc_ipc_marshal_lli(const long long int in, pims_ipc_data_h ipc_data);
+int ctsvc_ipc_marshal_long(const long in, pims_ipc_data_h ipc_data);
+int ctsvc_ipc_marshal_double(const double in, pims_ipc_data_h ipc_data);
+int ctsvc_ipc_marshal_record_common(const ctsvc_record_s* common, pims_ipc_data_h ipc_data);
+
+/*
+ * filter, query
+ *
+ * marsharl : view_uri + other
+ * unmarshal : view_uri를 먼저 get 하고 난 이후 나머지를 ..
+ */
+//int ctsvc_ipc_unmarshal_filter(const pims_ipc_data_h ipc_data, contacts_filter_h *filter);
+//int ctsvc_ipc_marshal_filter(const contacts_filter_h filter, pims_ipc_data_h ipc_data);
+int ctsvc_ipc_unmarshal_query(const pims_ipc_data_h ipc_data, contacts_query_h *query);
+int ctsvc_ipc_marshal_query(const contacts_query_h query, pims_ipc_data_h ipc_data);
+int ctsvc_ipc_unmarshal_list(const pims_ipc_data_h ipc_data, contacts_list_h *list);
+int ctsvc_ipc_unmarshal_child_list(const pims_ipc_data_h ipc_data, contacts_list_h* list);
+int ctsvc_ipc_marshal_list(const contacts_list_h list, pims_ipc_data_h ipc_data);
+
+#endif /* __ctsvc_ipc_marshal__ */
diff --git a/common/ipc/ctsvc_ipc_messenger.c b/common/ipc/ctsvc_ipc_messenger.c
new file mode 100644 (file)
index 0000000..4fb0cae
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_messenger(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_messenger(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_messenger_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_messenger_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_messenger,
+       .marshal_record = __ctsvc_ipc_marshal_messenger,
+       .get_primary_id = __ctsvc_ipc_marshal_messenger_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_messenger(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_messenger_s* messenger_p = (ctsvc_messenger_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &messenger_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &messenger_p->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &messenger_p->type) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &messenger_p->label) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &messenger_p->im_id) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_messenger(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_messenger_s* messenger_p = (ctsvc_messenger_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(messenger_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_int((messenger_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((messenger_p->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((messenger_p->type),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((messenger_p->label),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((messenger_p->im_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_messenger_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_MESSENGER_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_my_profile.c b/common/ipc/ctsvc_ipc_my_profile.c
new file mode 100644 (file)
index 0000000..9c19013
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "ctsvc_view.h"
+
+static int __ctsvc_ipc_unmarshal_my_profile(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_my_profile(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_my_profile_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_my_profile_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_my_profile,
+       .marshal_record = __ctsvc_ipc_marshal_my_profile,
+       .get_primary_id = __ctsvc_ipc_marshal_my_profile_get_primary_id
+};
+
+static int __ctsvc_ipc_unmarshal_my_profile(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_my_profile_s* pmy_profile = (ctsvc_my_profile_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pmy_profile->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pmy_profile->changed_time) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pmy_profile->addressbook_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pmy_profile->display_name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pmy_profile->reverse_display_name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pmy_profile->uid) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pmy_profile->image_thumbnail_path) != CONTACTS_ERROR_NONE) break;
+
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pmy_profile->name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pmy_profile->note) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pmy_profile->company) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pmy_profile->numbers) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pmy_profile->emails) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pmy_profile->events) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pmy_profile->messengers) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pmy_profile->postal_addrs) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pmy_profile->urls) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pmy_profile->nicknames) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pmy_profile->profiles) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pmy_profile->relationships) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pmy_profile->images) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_child_list(ipc_data, (contacts_list_h*)&pmy_profile->extensions) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_my_profile(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_my_profile_s* pcontact = (ctsvc_my_profile_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(pcontact==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_int((pcontact->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((pcontact->changed_time),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((pcontact->addressbook_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->display_name),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->reverse_display_name),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->uid),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->image_thumbnail_path),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->name, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->note, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->company, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->numbers, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->emails, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->events, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->messengers, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->postal_addrs, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->urls, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->nicknames, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->profiles, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->relationships, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->images, ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_list( (contacts_list_h)pcontact->extensions, ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_my_profile_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_CONTACT_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
+
diff --git a/common/ipc/ctsvc_ipc_name.c b/common/ipc/ctsvc_ipc_name.c
new file mode 100644 (file)
index 0000000..845ff4b
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_name(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_name(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_name_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_name_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_name,
+       .marshal_record = __ctsvc_ipc_marshal_name,
+       .get_primary_id = __ctsvc_ipc_marshal_name_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_name(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_name_s* name_p = (ctsvc_name_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &name_p->is_default) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &name_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &name_p->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &name_p->language_type) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &name_p->first) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &name_p->last) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &name_p->addition) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &name_p->prefix) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &name_p->suffix) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &name_p->phonetic_first) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &name_p->phonetic_middle) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &name_p->phonetic_last) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &name_p->lookup) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &name_p->reverse_lookup) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_name(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_name_s* name_p = (ctsvc_name_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(name_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_bool((name_p->is_default),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((name_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((name_p->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((name_p->language_type),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((name_p->first),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((name_p->last),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((name_p->addition),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((name_p->prefix),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((name_p->suffix),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((name_p->phonetic_first),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((name_p->phonetic_middle),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((name_p->phonetic_last),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((name_p->lookup),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((name_p->reverse_lookup),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_name_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_NAME_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_nickname.c b/common/ipc/ctsvc_ipc_nickname.c
new file mode 100644 (file)
index 0000000..eefe7d8
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_nickname(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_nickname(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_nickname_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_nickname_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_nickname,
+       .marshal_record = __ctsvc_ipc_marshal_nickname,
+       .get_primary_id = __ctsvc_ipc_marshal_nickname_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_nickname(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_nickname_s* nickname_p = (ctsvc_nickname_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &nickname_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &nickname_p->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &nickname_p->type) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &nickname_p->label) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &nickname_p->nickname) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_nickname(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_nickname_s* nickname_p = (ctsvc_nickname_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(nickname_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do{
+               if (ctsvc_ipc_marshal_int((nickname_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((nickname_p->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((nickname_p->type),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((nickname_p->label),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((nickname_p->nickname),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_nickname_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_NICKNAME_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_note.c b/common/ipc/ctsvc_ipc_note.c
new file mode 100644 (file)
index 0000000..e65af48
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_note(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_note(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_note_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_note_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_note,
+       .marshal_record = __ctsvc_ipc_marshal_note,
+       .get_primary_id = __ctsvc_ipc_marshal_note_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_note(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_note_s*  note_p = (ctsvc_note_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &note_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &note_p->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &note_p->note) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_note(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_note_s* note_p = (ctsvc_note_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(note_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_int((note_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((note_p->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((note_p->note),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_note_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_NOTE_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_number.c b/common/ipc/ctsvc_ipc_number.c
new file mode 100644 (file)
index 0000000..86b6fd2
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_number(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_number(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_number_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_number_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_number,
+       .marshal_record = __ctsvc_ipc_marshal_number,
+       .get_primary_id = __ctsvc_ipc_marshal_number_get_primary_id
+};
+
+static int __ctsvc_ipc_unmarshal_number(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_number_s*  number_p = (ctsvc_number_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &number_p->is_default) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &number_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &number_p->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &number_p->type) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &number_p->label) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &number_p->number) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_number(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_number_s* number_p = (ctsvc_number_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(number_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_bool((number_p->is_default),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((number_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((number_p->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((number_p->type),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((number_p->label),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((number_p->number),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_number_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_NUMBER_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_person.c b/common/ipc/ctsvc_ipc_person.c
new file mode 100644 (file)
index 0000000..311feac
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_person(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_person(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_person_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_person_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_person,
+       .marshal_record = __ctsvc_ipc_marshal_person,
+       .get_primary_id = __ctsvc_ipc_marshal_person_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_person(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_person_s*  person_p = (ctsvc_person_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &person_p->is_favorite) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &person_p->has_phonenumber) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &person_p->has_email) != CONTACTS_ERROR_NONE) break;
+
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &person_p->person_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &person_p->name_contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &person_p->display_name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &person_p->display_name_index) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &person_p->image_thumbnail_path) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &person_p->ringtone_path) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &person_p->vibration) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &person_p->message_alert) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &person_p->status) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &person_p->link_count) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &person_p->addressbook_ids) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_person(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_person_s* person_p = (ctsvc_person_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(person_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_bool((person_p->is_favorite),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_bool((person_p->has_phonenumber),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_bool((person_p->has_email),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               if (ctsvc_ipc_marshal_int((person_p->person_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((person_p->name_contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((person_p->display_name),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((person_p->display_name_index),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((person_p->image_thumbnail_path),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((person_p->ringtone_path),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((person_p->vibration),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((person_p->message_alert),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((person_p->status),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((person_p->link_count),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((person_p->addressbook_ids),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_person_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_PERSON_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_phonelog.c b/common/ipc/ctsvc_ipc_phonelog.c
new file mode 100644 (file)
index 0000000..1e1718c
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_phonelog(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_phonelog(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_phonelog_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_phonelog_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_phonelog,
+       .marshal_record = __ctsvc_ipc_marshal_phonelog,
+       .get_primary_id = __ctsvc_ipc_marshal_phonelog_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_phonelog(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_phonelog_s* phonelog_p = (ctsvc_phonelog_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &phonelog_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &phonelog_p->address) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &phonelog_p->person_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &phonelog_p->log_time) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &phonelog_p->log_type) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &phonelog_p->extra_data1) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &phonelog_p->extra_data2) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &phonelog_p->sim_slot_no) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_phonelog(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_phonelog_s* phonelog_p = (ctsvc_phonelog_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(phonelog_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+
+       do {
+               if (ctsvc_ipc_marshal_int((phonelog_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((phonelog_p->address),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((phonelog_p->person_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((phonelog_p->log_time),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((phonelog_p->log_type),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((phonelog_p->extra_data1),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((phonelog_p->extra_data2),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((phonelog_p->sim_slot_no),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_phonelog_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_PHONELOG_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_profile.c b/common/ipc/ctsvc_ipc_profile.c
new file mode 100644 (file)
index 0000000..77b5996
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_profile(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_profile(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_profile_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_profile_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_profile,
+       .marshal_record = __ctsvc_ipc_marshal_profile,
+       .get_primary_id = __ctsvc_ipc_marshal_profile_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_profile(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_profile_s* profile_p = (ctsvc_profile_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &profile_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &profile_p->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &profile_p->uid) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &profile_p->text) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &profile_p->order) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &profile_p->service_operation) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &profile_p->mime) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &profile_p->app_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &profile_p->uri) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &profile_p->category) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &profile_p->extra_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_profile(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_profile_s* profile_p = (ctsvc_profile_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(profile_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_int((profile_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((profile_p->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((profile_p->uid),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((profile_p->text),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((profile_p->order),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((profile_p->service_operation),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((profile_p->mime),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((profile_p->app_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((profile_p->uri),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((profile_p->category),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((profile_p->extra_data),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_profile_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_PROFILE_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_relationship.c b/common/ipc/ctsvc_ipc_relationship.c
new file mode 100644 (file)
index 0000000..118fc1c
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_relationship(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_relationship(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_relationship_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_relationship_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_relationship,
+       .marshal_record = __ctsvc_ipc_marshal_relationship,
+       .get_primary_id = __ctsvc_ipc_marshal_relationship_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_relationship(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_relationship_s* relationship_p = (ctsvc_relationship_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &relationship_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &relationship_p->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &relationship_p->type) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &relationship_p->label) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &relationship_p->name) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_relationship(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_relationship_s* relationship_p = (ctsvc_relationship_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(relationship_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_int((relationship_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((relationship_p->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((relationship_p->type),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((relationship_p->label),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((relationship_p->name),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_relationship_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_RELATIONSHIP_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_result.c b/common/ipc/ctsvc_ipc_result.c
new file mode 100644 (file)
index 0000000..bc5d7a5
--- /dev/null
@@ -0,0 +1,240 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_result(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_result(const contacts_record_h record, pims_ipc_data_h ipc_data);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_result_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_result,
+       .marshal_record = __ctsvc_ipc_marshal_result,
+       .get_primary_id = NULL
+};
+
+
+static int __ctsvc_ipc_unmarshal_search_value(pims_ipc_data_h ipc_data, ctsvc_result_value_s* pvalue)
+{
+       if (ctsvc_ipc_unmarshal_int(ipc_data,&pvalue->property_id) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("ctsvc_ipc_unmarshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       if (ctsvc_ipc_unmarshal_int(ipc_data,&pvalue->type) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("ctsvc_ipc_unmarshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+
+       if (CTSVC_VIEW_CHECK_DATA_TYPE(pvalue->property_id, CTSVC_VIEW_DATA_TYPE_STR) == true)
+       {
+               if (ctsvc_ipc_unmarshal_string(ipc_data,&pvalue->value.s) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+       else if (CTSVC_VIEW_CHECK_DATA_TYPE(pvalue->property_id, CTSVC_VIEW_DATA_TYPE_BOOL) == true)
+       {
+               if (ctsvc_ipc_unmarshal_bool(ipc_data,&pvalue->value.b) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+       else if (CTSVC_VIEW_CHECK_DATA_TYPE(pvalue->property_id, CTSVC_VIEW_DATA_TYPE_INT) == true)
+       {
+               if (ctsvc_ipc_unmarshal_int(ipc_data,&pvalue->value.i) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+       else if (CTSVC_VIEW_CHECK_DATA_TYPE(pvalue->property_id, CTSVC_VIEW_DATA_TYPE_DOUBLE) == true)
+       {
+               if (ctsvc_ipc_unmarshal_double(ipc_data,&pvalue->value.d) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+       else if (CTSVC_VIEW_CHECK_DATA_TYPE(pvalue->property_id, CTSVC_VIEW_DATA_TYPE_LLI) == true)
+       {
+               if (ctsvc_ipc_unmarshal_lli(ipc_data,&pvalue->value.l) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+       else
+       {
+               ASSERT_NOT_REACHED("invalid parameter (property:%d)",pvalue->property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_ipc_marshal_search_value(const ctsvc_result_value_s* pvalue, pims_ipc_data_h ipc_data)
+{
+       if (ctsvc_ipc_marshal_int(pvalue->property_id,ipc_data) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("ctsvc_ipc_marshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       if (ctsvc_ipc_marshal_int(pvalue->type,ipc_data) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("ctsvc_ipc_marshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+
+
+       if (CTSVC_VIEW_CHECK_DATA_TYPE(pvalue->property_id, CTSVC_VIEW_DATA_TYPE_STR) == true)
+       {
+               if (ctsvc_ipc_marshal_string(pvalue->value.s,ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+       else if (CTSVC_VIEW_CHECK_DATA_TYPE(pvalue->property_id, CTSVC_VIEW_DATA_TYPE_BOOL) == true)
+       {
+               if (ctsvc_ipc_marshal_bool(pvalue->value.b,ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+       else if (CTSVC_VIEW_CHECK_DATA_TYPE(pvalue->property_id, CTSVC_VIEW_DATA_TYPE_INT) == true)
+       {
+               if (ctsvc_ipc_marshal_int(pvalue->value.i,ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+       else if (CTSVC_VIEW_CHECK_DATA_TYPE(pvalue->property_id, CTSVC_VIEW_DATA_TYPE_DOUBLE) == true)
+       {
+               if (ctsvc_ipc_marshal_double(pvalue->value.d,ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+       else if (CTSVC_VIEW_CHECK_DATA_TYPE(pvalue->property_id, CTSVC_VIEW_DATA_TYPE_LLI) == true)
+       {
+               if (ctsvc_ipc_marshal_lli(pvalue->value.l,ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+       else
+       {
+               ASSERT_NOT_REACHED("invalid parameter (property:%d)",pvalue->property_id);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+
+static int __ctsvc_ipc_unmarshal_result(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL, CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL, CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_result_s* result_p = (ctsvc_result_s*)record;
+
+       unsigned int count = 0;
+       if (ctsvc_ipc_unmarshal_unsigned_int(ipc_data, &count) != CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("ctsvc_ipc_unmarshal fail");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       unsigned int i = 0;
+       for ( i=0; i<count; i++ )
+       {
+               ctsvc_result_value_s* value_data = NULL;
+               value_data = calloc(1, sizeof(ctsvc_result_value_s));
+               if (value_data == NULL)
+               {
+                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+               }
+
+               if (__ctsvc_ipc_unmarshal_search_value(ipc_data, value_data) != CONTACTS_ERROR_NONE)
+               {
+                       CONTACTS_FREE(value_data);
+                       CTS_ERR("ctsvc_ipc_unmarshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               result_p->values = g_slist_append(result_p->values, value_data);
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_ipc_marshal_result(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_result_s* result_p = (ctsvc_result_s*)record;
+       RETV_IF(result_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       if (result_p->values)
+       {
+               unsigned int count = g_slist_length(result_p->values);
+               if (ctsvc_ipc_marshal_unsigned_int(count, ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+
+               GSList *cursor = result_p->values;
+               while (cursor)
+               {
+                       ctsvc_result_value_s* value_data = (ctsvc_result_value_s *)cursor->data;
+                       if (value_data == NULL)
+                       {
+                               cursor = g_slist_next(cursor);
+                               continue;
+                       }
+                       if (__ctsvc_ipc_marshal_search_value((const ctsvc_result_value_s*)value_data, ipc_data) != CONTACTS_ERROR_NONE)
+                       {
+                               CTS_ERR("ctsvc_ipc_marshal fail");
+                               return CONTACTS_ERROR_INVALID_PARAMETER;
+                       }
+                       cursor = g_slist_next(cursor);
+               }
+       }
+       else
+       {
+               if (ctsvc_ipc_marshal_int(0, ipc_data) != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_marshal fail");
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/common/ipc/ctsvc_ipc_sdn.c b/common/ipc/ctsvc_ipc_sdn.c
new file mode 100644 (file)
index 0000000..49399f6
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_sdn(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_sdn(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_sdn_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_sdn_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_sdn,
+       .marshal_record = __ctsvc_ipc_marshal_sdn,
+       .get_primary_id = __ctsvc_ipc_marshal_sdn_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_sdn(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_sdn_s*  sdn_p = (ctsvc_sdn_s*) record;
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &sdn_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &sdn_p->name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &sdn_p->number) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &sdn_p->sim_slot_no) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_sdn(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_sdn_s* sdn_p = (ctsvc_sdn_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(sdn_p==NULL,CONTACTS_ERROR_NO_DATA);
+       do {
+               if (ctsvc_ipc_marshal_int((sdn_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((sdn_p->name),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((sdn_p->number),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((sdn_p->sim_slot_no),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_sdn_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_SDN_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/ctsvc_ipc_simple_contact.c b/common/ipc/ctsvc_ipc_simple_contact.c
new file mode 100644 (file)
index 0000000..d231e09
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+
+static int __ctsvc_ipc_unmarshal_simple_contact(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_simple_contact(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_simple_contact_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_simple_contact_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_simple_contact,
+       .marshal_record = __ctsvc_ipc_marshal_simple_contact,
+       .get_primary_id = __ctsvc_ipc_marshal_simple_contact_get_primary_id
+};
+
+static int __ctsvc_ipc_unmarshal_simple_contact(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_simple_contact_s* pcontact = (ctsvc_simple_contact_s*) record;
+       do {
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &pcontact->is_favorite) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pcontact->changed_time) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &pcontact->has_phonenumber) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_bool(ipc_data, &pcontact->has_email) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pcontact->person_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pcontact->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pcontact->addressbook_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->image_thumbnail_path) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->ringtone_path) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->vibration) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->message_alert) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->display_name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->uid) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &pcontact->display_source_type) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_simple_contact(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_simple_contact_s* pcontact = (ctsvc_simple_contact_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(pcontact==NULL,CONTACTS_ERROR_NO_DATA);
+       do {
+               if (ctsvc_ipc_marshal_bool((pcontact->is_favorite),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((pcontact->changed_time),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_bool((pcontact->has_phonenumber),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_bool((pcontact->has_email),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((pcontact->person_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((pcontact->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((pcontact->addressbook_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->image_thumbnail_path),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->ringtone_path),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->vibration),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->message_alert),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->display_name),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((pcontact->uid),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((pcontact->display_source_type),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_simple_contact_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_CONTACT_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
+
diff --git a/common/ipc/ctsvc_ipc_speeddial.c b/common/ipc/ctsvc_ipc_speeddial.c
new file mode 100644 (file)
index 0000000..a94f622
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_speeddial(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_speeddial(const contacts_record_h record, pims_ipc_data_h ipc_data);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_speeddial_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_speeddial,
+       .marshal_record = __ctsvc_ipc_marshal_speeddial,
+       .get_primary_id = NULL
+};
+
+
+static int __ctsvc_ipc_unmarshal_speeddial(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_speeddial_s* speeddial_p = (ctsvc_speeddial_s*) record;
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &speeddial_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &speeddial_p->number_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &speeddial_p->person_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &speeddial_p->display_name) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &speeddial_p->image_thumbnail_path) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &speeddial_p->number_type) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &speeddial_p->label) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &speeddial_p->number) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &speeddial_p->dial_number) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_speeddial(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_speeddial_s* speeddial_p = (ctsvc_speeddial_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(speeddial_p==NULL,CONTACTS_ERROR_NO_DATA);
+       do {
+               if (ctsvc_ipc_marshal_int((speeddial_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((speeddial_p->number_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((speeddial_p->person_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((speeddial_p->display_name),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((speeddial_p->image_thumbnail_path),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((speeddial_p->number_type),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((speeddial_p->label),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((speeddial_p->number),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((speeddial_p->dial_number),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
diff --git a/common/ipc/ctsvc_ipc_updated_info.c b/common/ipc/ctsvc_ipc_updated_info.c
new file mode 100644 (file)
index 0000000..d4505b0
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_updated_info(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_updated_info(const contacts_record_h record, pims_ipc_data_h ipc_data);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_updated_info_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_updated_info,
+       .marshal_record = __ctsvc_ipc_marshal_updated_info,
+       .get_primary_id = NULL
+};
+
+
+static int __ctsvc_ipc_unmarshal_updated_info(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_updated_info_s*  updated_info_p = (ctsvc_updated_info_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data,&updated_info_p->changed_type) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data,&updated_info_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data,&updated_info_p->changed_ver) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data,&updated_info_p->addressbook_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_bool(ipc_data,&updated_info_p->image_changed) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data,&updated_info_p->last_changed_type) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_updated_info(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_updated_info_s* updated_info_p = (ctsvc_updated_info_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(updated_info_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+
+       do {
+               if (ctsvc_ipc_marshal_int((updated_info_p->changed_type),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((updated_info_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((updated_info_p->changed_ver),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((updated_info_p->addressbook_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_bool((updated_info_p->image_changed),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((updated_info_p->last_changed_type),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
diff --git a/common/ipc/ctsvc_ipc_url.c b/common/ipc/ctsvc_ipc_url.c
new file mode 100644 (file)
index 0000000..eee7905
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "ctsvc_internal.h"
+#include "ctsvc_ipc_marshal.h"
+#include "contacts_record.h"
+
+static int __ctsvc_ipc_unmarshal_url(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record);
+static int __ctsvc_ipc_marshal_url(const contacts_record_h record, pims_ipc_data_h ipc_data);
+static int __ctsvc_ipc_marshal_url_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id);
+
+ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_url_plugin_cb = {
+       .unmarshal_record = __ctsvc_ipc_unmarshal_url,
+       .marshal_record = __ctsvc_ipc_marshal_url,
+       .get_primary_id = __ctsvc_ipc_marshal_url_get_primary_id
+};
+
+
+static int __ctsvc_ipc_unmarshal_url(pims_ipc_data_h ipc_data, const char* view_uri, contacts_record_h record)
+{
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA);
+
+       ctsvc_url_s* url_p = (ctsvc_url_s*) record;
+
+       do {
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &url_p->id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &url_p->contact_id) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_int(ipc_data, &url_p->type) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &url_p->label) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_unmarshal_string(ipc_data, &url_p->url) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_unmarshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_url(const contacts_record_h record, pims_ipc_data_h ipc_data)
+{
+       ctsvc_url_s* url_p = (ctsvc_url_s*)record;
+       RETV_IF(ipc_data==NULL,CONTACTS_ERROR_NO_DATA);
+       RETV_IF(url_p==NULL,CONTACTS_ERROR_NO_DATA);
+
+       do {
+               if (ctsvc_ipc_marshal_int((url_p->id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((url_p->contact_id),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_int((url_p->type),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((url_p->label),ipc_data) != CONTACTS_ERROR_NONE) break;
+               if (ctsvc_ipc_marshal_string((url_p->url),ipc_data) != CONTACTS_ERROR_NONE) break;
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       CTS_ERR("_ctsvc_ipc_marshal fail");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_ipc_marshal_url_get_primary_id(const contacts_record_h record, unsigned int *property_id, int *id)
+{
+       *property_id = CTSVC_PROPERTY_URL_ID;
+       return contacts_record_get_int(record, *property_id, id );
+}
+
diff --git a/contacts-service2.manifest b/contacts-service2.manifest
new file mode 100644 (file)
index 0000000..c33981b
--- /dev/null
@@ -0,0 +1,68 @@
+<manifest>
+       <define>
+               <domain name="contacts-service" />
+               <provide>
+                       <label name="contacts-service::db"/>
+                       <label name="contacts-service::svc"/>
+                       <label name="contacts-service::phonelog"/>
+                       <label name="contacts-service::vconf"/>
+                       <label name="contacts-service::vconf-private"/>
+               </provide>
+               <request>
+                       <smack request="contacts-service::db" type="rwxatl"/>
+                       <smack request="contacts-service::svc" type="rwxatl"/>
+                       <smack request="contacts-service::phonelog" type="rwxatl"/>
+                       <smack request="contacts-service::vconf" type="rwxatl"/>
+                       <smack request="contacts-service::vconf-private" type="rwxatl"/>
+                       <smack request="sys-assert::core" type="rwxat"/>
+                       <smack request="libaccounts-svc" type="rw"/>
+                       <smack request="libaccounts-svc::db" type="rwl"/>
+                       <smack request="libaccounts-svc::check_read" type="r"/>
+                       <smack request="telephony_framework::api_sim" type="r"/>
+                       <smack request="telephony_framework::api_phonebook" type="rx"/>
+                       <smack request="telephony_framework::properties" type="rw"/>
+                       <smack request="system::vconf_system" type="r"/>
+                       <smack request="system::vconf_inhouse" type="r"/>
+                       <smack request="security-server::api-privilege-by-pid" type="w"/>
+                       <smack request="security-server::api-cookie-check" type="w"/>
+               </request>
+       </define>
+       <assign>
+               <filesystem path="/usr/lib/libcontacts-service2.so.0*" label="_" exec_label="none"/>
+               <filesystem path="/opt/usr/dbspace/.contacts-svc.db" label="contacts-service::db"/>
+               <filesystem path="/opt/usr/dbspace/.contacts-svc.db-journal" label="contacts-service::db"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_IPC_READY" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_AB_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_ACTIVITY_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_ACTIVITY_PHOTO_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_ADDRESS_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_COMPANY_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_DATA_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_DB_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_EMAIL_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_EVENT_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_GROUP_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_GROUP_RELATION_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_IMAGE_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_MESSENGER_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_MY_PROFILE_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_NAME_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_NICKNAME_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_NUMBER_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_NOTE_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_PERSON_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_PROFILE_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_RELATIONSHIP_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_SDN_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_SPEED_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_URL_CHANGED" label="contacts-service::svc"/>
+               <filesystem path="/opt/usr/data/contacts-svc/.CONTACTS_SVC_PLOG_CHANGED" label="contacts-service::phonelog"/>
+               <filesystem path="/opt/usr/data/contacts-svc/img/contact" label="contacts-service::svc" type="transmutable"/>
+               <filesystem path="/opt/usr/data/contacts-svc/img/group" label="contacts-service::svc" type="transmutable"/>
+               <filesystem path="/opt/usr/data/contacts-svc/img/logo" label="contacts-service::svc" type="transmutable"/>
+               <filesystem path="/opt/usr/data/contacts-svc/img/vcard" label="contacts-service" type="transmutable"/>
+       </assign>
+       <request>
+               <domain name="contacts-service" />
+       </request>
+</manifest>
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644 (file)
index 6bb3db3..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-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
-  * Git: pkgs/c/contacts-service
-  * Tag: contacts-service_0.6.1-9
-
- -- Youngjae Shin <yj99.shin@samsung.com>  Mon, 09 Apr 2012 11:51:00 +0900
diff --git a/debian/compat b/debian/compat
deleted file mode 100644 (file)
index 7ed6ff8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-5
diff --git a/debian/contacts-service-bin.install.in b/debian/contacts-service-bin.install.in
deleted file mode 100644 (file)
index 5549ed0..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-@PREFIX@/bin/*
-/etc/*
diff --git a/debian/contacts-service-bin.postinst.in b/debian/contacts-service-bin.postinst.in
deleted file mode 100755 (executable)
index a853e91..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-
-if [ ! -d /opt/dbspace ]
-then
-       mkdir -p /opt/dbspace
-fi
-
-contacts-svc-helper schema
-
-if [ "$USER" = "root" ]
-then
-# Change file owner
-   chown :6005 /opt/dbspace/.contacts-svc.db
-   chown :6005 /opt/dbspace/.contacts-svc.db-journal
-
-   chown root:root @PREFIX@/bin/contacts-svc-helper*
-   chown root:root /etc/rc.d/init.d/contacts-svc-helper.sh
-fi
-
-# Change file permissions
-# chmod 755 /usr/bin/contacts-svc-helper
-
-chmod 660 /opt/dbspace/.contacts-svc.db
-chmod 660 /opt/dbspace/.contacts-svc.db-journal
-
-chmod 755 /etc/rc.d/init.d/contacts-svc-helper.sh
-
-vconftool set -t int file/private/contacts-service/default_lang 1
diff --git a/debian/control b/debian/control
deleted file mode 100644 (file)
index 3d3eb07..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-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, libtapi-dev, libicu-dev, libsystemd-daemon-dev
-Standards-Version: 3.7.2
-Homepage: N/A
-
-Package: libcontacts-service-dev
-Section: devel
-Architecture: any
-Depends: libcontacts-service (= ${Source-Version}), libglib2.0-dev
-Description: contacts service Library (development)
-XB-Generate-Docs: yes
-
-Package: libcontacts-service
-Section: libs
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
-Recommends: contacts-service-bin (= ${Source-Version})
-Description: contacts service Library (Library)
-
-Package: contacts-service-bin
-Section: devel
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}
-Description: contacts service binary : contacts-svc-helper
-
-Package: libcontacts-service-dbg
-Section: debug
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, libcontacts-service (= ${Source-Version})
-Description: contacts service Library (unstripped)
diff --git a/debian/copyright b/debian/copyright
deleted file mode 100644 (file)
index 74c3188..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the Apache License version 2.0.
-
-The full text of the Apache 2.0 can be found in
-/usr/share/common-licenses.
diff --git a/debian/dirs b/debian/dirs
deleted file mode 100644 (file)
index ca882bb..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/bin
-usr/sbin
diff --git a/debian/docs b/debian/docs
deleted file mode 100644 (file)
index a0f0008..0000000
+++ /dev/null
@@ -1 +0,0 @@
-CMakeLists.txt
diff --git a/debian/libcontacts-service-dev.install.in b/debian/libcontacts-service-dev.install.in
deleted file mode 100644 (file)
index 1bcdd80..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-@PREFIX@/lib/*.so
-@PREFIX@/include/contacts-svc/*.h
-@PREFIX@/lib/pkgconfig/contacts-service.pc
-
diff --git a/debian/libcontacts-service.install.in b/debian/libcontacts-service.install.in
deleted file mode 100644 (file)
index 348fb98..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-@PREFIX@/lib/*.so.*
-/opt/*
diff --git a/debian/libcontacts-service.postinst.in b/debian/libcontacts-service.postinst.in
deleted file mode 100755 (executable)
index 5f04744..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-
-if [ "$USER" = "root" ]
-then
-# Change file owner
-   chown root:root @PREFIX@/lib/libcontacts-service.so.*
-       #db_contact
-   chown :6005 -R /opt/data/contacts-svc/img
-   chown :6005 /opt/data/contacts-svc/.CONTACTS_SVC_*_CHANGED
-       #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/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
deleted file mode 100755 (executable)
index 5b1c2fe..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/usr/bin/make -f
-# -*- makefile -*-
-# Sample debian/rules that uses debhelper.
-# This file was originally written by Joey Hess and Craig Small.
-# As a special exception, when this file is copied by dh-make into a
-# dh-make output file, you may use that output file without restriction.
-# This special exception was added by Craig Small in version 0.37 of dh-make.
-
-# Uncomment this to turn on verbose mode.
-#export DH_VERBOSE=1
-
-CFLAGS += -Wall
-LDFLAGS ?=
-PREFIX ?= /usr
-DATADIR ?= /opt
-
-ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
-       CFLAGS += -O0
-else
-       CFLAGS += -O2
-endif
-
-LDFLAGS += -Wl,--hash-style=both -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed
-
-configure: configure-stamp
-configure-stamp:
-       dh_testdir
-       # Add here commands to configure the package.
-       CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" cmake . -DCMAKE_INSTALL_PREFIX=$(PREFIX)
-
-       touch configure-stamp
-
-build: build-stamp
-
-build-stamp: configure-stamp
-       dh_testdir
-
-       # Add here commands to compile the package.
-       $(MAKE)
-
-       for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
-               cat $$f > $${f%.in}; \
-               sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \
-               sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \
-       done
-
-
-       touch $@
-
-clean:
-       dh_testdir
-       dh_testroot
-       rm -f build-stamp configure-stamp
-
-       # 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 contacts-svc-helper
-
-       for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
-               rm -f $${f%.in}; \
-       done
-
-       dh_clean
-
-install: build
-       dh_testdir
-       dh_testroot
-       dh_prep
-       dh_installdirs
-
-       # Add here commands to install the package.
-       $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
-       mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/
-       mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc5.d/
-       ln -s ../init.d/contacts-svc-helper.sh $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/S50contacts-svc-helper
-       ln -s ../init.d/contacts-svc-helper.sh $(CURDIR)/debian/tmp/etc/rc.d/rc5.d/S50contacts-svc-helper
-
-# Build architecture-independent files here.
-binary-indep: build install
-# We have nothing to do by default.
-
-# Build architecture-dependent files here.
-binary-arch: build install
-       dh_testdir
-       dh_testroot
-#      dh_installchangelogs
-#      dh_installdocs
-       dh_installexamples
-       dh_install --sourcedir=debian/tmp
-#      dh_installmenu
-#      dh_installdebconf
-#      dh_installlogrotate
-#      dh_installemacsen
-#      dh_installpam
-#      dh_installmime
-#      dh_python
-#      dh_installinit
-#      dh_installcron
-#      dh_installinfo
-       dh_installman
-       dh_link
-       dh_strip --dbg-package=libcontacts-service-dbg
-       dh_compress
-       dh_fixperms
-#      dh_perl
-       dh_makeshlibs
-       dh_installdeb
-       dh_shlibdeps
-       dh_gencontrol
-       dh_md5sums
-       dh_builddeb
-
-binary: binary-indep binary-arch
-.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/doc/contacts_doc.h b/doc/contacts_doc.h
new file mode 100644 (file)
index 0000000..7a2b7e8
--- /dev/null
@@ -0,0 +1,878 @@
+#ifndef __TIZEN_SOCIAL_CONTACTS_DOC_H__
+#define __TIZEN_SOCIAL_CONTACTS_DOC_H__
+
+
+/**
+ * @ingroup CAPI_SOCIAL_FRAMEWORK
+ * @defgroup CAPI_SOCIAL_CONTACTS_SVC_MODULE Contacts
+ *
+ * @brief The Contacts Service API provides methods for managing contact information for people.
+ * A contact object is always associated with a specific address book.
+ * A person object is an aggregation of one or more contacts associated with the same person.
+ *
+ *
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_MODULE_HEADER Required Header
+ *  \#include <contacts.h>
+ *
+ *
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_MODULE_OVERVIEW Overview
+ * The Contacts-service provides functions for managing contact information for people.
+ * A contact object is always associated with a specific address book.
+ * A person object is an aggregation of one or more contacts associated with the same person.
+ *
+ * Contacts-service has a relationship between Entities.
+ * @image html Contact_structure.png "Figure: Contact structure"
+ *
+ * There are three same contacts made from different address book.
+ * Person1 is an aggregation of Contact1, Contact2 and Contact3.
+ *
+ * The contacts-service provides an interface to manage the information
+ * <table>
+ * <tr>
+ * <td>
+ *     - Managing contacts information stored in database <br>
+ *     - Aggregating contacts information from various accounts <br>
+ *     - Notifying changes of contacts information <br>
+ *     - Searching contacts information <br>
+ *     - vCard supports <br>
+ * </td>
+ * </tr>
+ * </table>
+ *
+ *
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_MODULE_ENTITIES Entities
+ * Contacts-Service manages information related to following entities.
+ * - Contact
+ *     - Information for individuals, like name, phone number, email, address, job, instant messenger, company, etc.
+ * - Account
+ *     - Accounts are handled by account module. Contacts-service should use account ID which is created the module
+ *     - Exceptionally, Local device address book has no account and its related account ID is zero.
+ *     - Each account can create only one address book.
+ * - Address book
+ *     - Represents where contacts and groups should belong to
+ *     - Created by one of contacts sources below
+ *             - Local device, which has no account
+ *             - Service providers such as Google or Yahoo, with account
+ *             - Applications like ChatON, Joyn, Facebook, etc.
+ * - Group
+ *     - Grouped contacts on a same address book
+ *     - Groups and contacts have many-to-many relationship
+ * - Person
+ *     - A virtual contact that keeps merged information of contacts linked together
+ *     - When more than one contact from different sources designate same individual, then instead of showing each contacts separately, by Person concept, they can be shown and managed as one virtual contact.
+ *     - Every contact becomes to be linked to at least one person.
+ * - My profile
+ *     - My information which has almost same properties as contact information but it has no properties such as group relation, ringtone and message alert.
+ *     - Single entry can be available on each address book
+ * - Activity
+ *     - Social activities are stored.
+ * - Speed Dial
+ *             - Shortcut dialing number key information
+ * - Phone Log
+ *     - Call or message logs are stored
+ *
+ *
+ * @subsection CAPI_SOCIAL_CONTACTS_SVC_MODULE_ENTITIES_RELATIONSHIP Relationship between entities
+ * Contacts-service has a relationship between Entities.
+ * @image html Relationship_between_entities.png "Figure: Relationship between entities"
+ *
+ *
+ * @subsection CAPI_SOCIAL_CONTACTS_SVC_MODULE_RELATIONSHIP_BETWEEN_CONTACT_AND_PERSON Relationship between Contact and Person
+ * Person will be created automatically when inserting a contact record. Cannot create person record directly.
+ *
+ * Sample code: Insert a contact record
+ *
+ * @code
+ * // create contact record
+ * contacts_record_h contact = NULL;
+ * contacts_record_create(_contacts_contact._uri, &contact);
+ *
+ * // add name
+ * contacts_record_h name = NULL;
+ * contacts_record_create(_contacts_name._uri, &name);
+ * contacts_record_set_str(name, _contacts_name.first, “test”);
+ * contacts_record_add_child_record(contact, _contacts_contact.name, name);
+ *
+ * // add number
+ * contacts_record_h number = NULL;
+ * contacts_record_create(_contacts_number._uri, &number);
+ * contacts_record_set_str(name, _contacts_number.number, “1234”);
+ * contacts_record_add_child_record(contact, _contacts_contact.number, number);
+ *
+ * // insert to database
+ * int contact_id = 0;
+ * contacts_db_insert_record(contact, &contact_id);
+ *
+ * // destroy record
+ * contacts_record_destroy(contact, true);
+ * @endcode
+ *
+ * @image html Creating_a_person_record.png "Figure: Creating a person record"
+ *
+ * Person record can be link to another person. Even though contacts address book is different, link is possible.
+ *
+ * Sample code: Link contact
+ * @code
+ * int person_id1 = ... // acquire ID of Person1 record
+ * int person_id2 = ... // acquire ID of Person2 record
+ *
+ * contacts_person_link_person(person_id1, person_id2);
+ * @endcode
+ *
+ * @image html Link_person.png "Figure: Link person"
+ *
+ * Contact record can be separate from person record. New person will be created when unlinking contact record.
+ *
+ * Sample code: Unlink contact
+ * @code
+ * int person_id1 = ... // acquire ID of Person1 record
+ * int contact_id3 = ... // acquire ID of Contact3 record
+ *
+ * contacts_person_unlink_contact(person_id1, contact_id3);
+ * @endcode
+ *
+ * @image html Unlink_contact.png "Figure: Unlink contact"
+ *
+ *
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_MODULE_VIEWS Views
+ * To access and handle entities, views are provided.
+ * According to data-view declarations, generic access functions are used (contacts_db_insert_record(), contacts_record_get_int(), …).
+ * Data-View is almost same as database “VIEW” which limits access and guarantees the performance by offering various views for the proper purpose.
+ * “Record” represents a single row of the data-views. <br>
+ * A data-view is a structure, which has property elements.
+ * For example, the _contacts_contact view describes the properties of the contact record.
+ * Its properties include name, company, nickname of the contact and many more.
+ *
+ * <table>
+ * <caption> Table: Contact editable views </caption>
+ * <tr>
+ *     <th>View (Editable)</th>
+ *     <th>Description</th>
+ * </tr>
+ * <tr>        <td>    _contacts_address_book  </td>   <td>    Describes the properties of the address book            </td>   </tr>
+ * <tr>        <td>    _contacts_group </td>   <td>    Describes the properties of the group           </td>   </tr>
+ * <tr>        <td>    _contacts_person        </td>   <td>    Describes the properties of the person          </td>   </tr>
+ * <tr>        <td>    _contacts_simple_contact        </td>   <td>    Describes the properties of the contact         </td>   </tr>
+ * <tr>        <td>    _contacts_contact       </td>   <td>    Describes the properties of the contact         </td>   </tr>
+ * <tr>        <td>    _contacts_my_profile    </td>   <td>    Describes the properties of the my profile              </td>   </tr>
+ * <tr>        <td>    _contacts_name  </td>   <td>    Describes the properties of the contacts name           </td>   </tr>
+ * <tr>        <td>    _contacts_number        </td>   <td>    Describes the properties of the contacts number         </td>   </tr>
+ * <tr>        <td>    _contacts_email </td>   <td>    Describes the properties of the contacts email          </td>   </tr>
+ * <tr>        <td>    _contacts_address       </td>   <td>    Describes the properties of the contacts address                </td>   </tr>
+ * <tr>        <td>    _contacts_note  </td>   <td>    Describes the properties of the contacts note           </td>   </tr>
+ * <tr>        <td>    _contacts_url   </td>   <td>    Describes the properties of the contacts url            </td>   </tr>
+ * <tr>        <td>    _contacts_event </td>   <td>    Describes the properties of the contacts birthday and anniversary               </td>   </tr>
+ * <tr>        <td>    _contacts_group_relation        </td>   <td>    Describes the properties of the contacts group relation         </td>   </tr>
+ * <tr>        <td>    _contacts_relationship  </td>   <td>    Describes the properties of the contacts relationship           </td>   </tr>
+ * <tr>        <td>    _contacts_image </td>   <td>    Describes the properties of the contacts image          </td>   </tr>
+ * <tr>        <td>    _contacts_company       </td>   <td>    Describes the properties of the contacts company                </td>   </tr>
+ * <tr>        <td>    _contacts_nickname      </td>   <td>    Describes the properties of the contacts nickname               </td>   </tr>
+ * <tr>        <td>    _contacts_messenger     </td>   <td>    Describes the properties of the contacts messenger              </td>   </tr>
+ * <tr>        <td>    _contacts_extension     </td>   <td>    Describes the properties of the extension               </td>   </tr>
+ * <tr>        <td>    _contacts_sdn   </td>   <td>    Describes the properties of the service describe number         </td>   </tr>
+ * <tr>        <td>    _contacts_profile       </td>   <td>    Describes the properties of the profile         </td>   </tr>
+ * <tr>        <td>    _contacts_activity_photo        </td>   <td>    Describes the properties of the photo of contacts activity              </td>   </tr>
+ * <tr>        <td>    _contacts_activity      </td>   <td>    Describes the properties of the contacts activity               </td>   </tr>
+ * <tr>        <td>    _contacts_speeddial     </td>   <td>    Describes the properties of the speed dial              </td>   </tr>
+ * <tr>        <td>    _contacts_phone_log     </td>   <td>    Describes the properties of the log             </td>   </tr>
+ * </table>
+ *
+ * <table>
+ * <caption> Table: Contact read only views </caption>
+ * <tr>
+ *     <th>View (Read only)</th>
+ *     <th>Description</th>
+ *     </tr>
+ *     <tr>    <td>    _contacts_contact_updated_info  </td>   <td>    used when identifying contact changes depending on version.     </td>   </tr>
+ *     <tr>    <td>    _contacts_my_profile_updated_info       </td>   <td>    used when identifying my profile changes depending on version.  </td>   </tr>
+ *     <tr>    <td>    _contacts_group_updated_info    </td>   <td>    used when identifying group changes depending on version.       </td>   </tr>
+ *     <tr>    <td>    _contacts_group_member_updated_info     </td>   <td>    used when identifying group member changes depending on version.        </td>   </tr>
+ *     <tr>    <td>    _contacts_grouprel_updated_info </td>   <td>    used when identifying group relation profile changes depending on version.      </td>   </tr>
+ *     <tr>    <td>    _contacts_person_contact        </td>   <td>    used when querying to merge information of person and contact   </td>   </tr>
+ *     <tr>    <td>    _contacts_person_number </td>   <td>    used when querying to merge information of person and number    </td>   </tr>
+ *     <tr>    <td>    _contacts_person_email  </td>   <td>    used when querying to merge information of person and email     </td>   </tr>
+ *     <tr>    <td>    _contacts_person_grouprel       </td>   <td>    used when querying to merge information of person and group relation    </td>   </tr>
+ *     <tr>    <td>    _contacts_person_group_assigned </td>   <td>    used when querying to information of person who assigned group  </td>   </tr>
+ *     <tr>    <td>    _contacts_person_group_not_assigned     </td>   <td>    used when querying to information of person who not assigned group      </td>   </tr>
+ *     <tr>    <td>    _contacts_person_phone_log      </td>   <td>    used when querying to merge information of person and phone log </td>   </tr>
+ *     <tr>    <td>    _contacts_person_usage  </td>   <td>    used when querying to information of person usage       </td>   </tr>
+ *     <tr>    <td>    _contacts_contact_number        </td>   <td>    used when querying to merge information of contact and number   </td>   </tr>
+ *     <tr>    <td>    _contacts_contact_email </td>   <td>    used when querying to merge information of contact and email    </td>   </tr>
+ *     <tr>    <td>    _contacts_contact_grouprel      </td>   <td>    used when querying to merge information of contact and group relation   </td>   </tr>
+ *     <tr>    <td>    _contacts_contact_activity      </td>   <td>    used when querying to merge information of contact and activity </td>   </tr>
+ *     <tr>    <td>    _contacts_phone_log_stat        </td>   <td>    used when querying to information of phone log status   </td>   </tr>
+ * </table>
+ *
+ *
+ * @subsection CAPI_SOCIAL_CONTACTS_SVC_MODULE_VIEWS_PROPERTIES Properties
+ * Property elements have their data types and name. <br>
+ * Record types which have *_id as their properties, hold identifiers of other records - e.g. name, number and email views hold ID of their corresponding contacts in contact_id property (as children of the corresponding contacts record). <br>
+ * A type of some property is ‘record’.
+ * It means that the parent record can have child records.
+ * For example, a contact record has 'name', 'number' and 'email' properties, which means that records of those types can be children of contact type records.<br>
+ * In contacts_view.h headear file, view macros are found and below figure shows what macro means.
+ *
+ * @image html Properties.png "Figure: Properties"
+ *
+ * Sample code: Create a contact record then set caller ID
+ * @code
+ * contacts_record_h contact = NULL;
+ * contacts_record_create(_contacts_contact._uri, &contact);
+ *
+ * // set image to _contacts_contact view.
+ * contacts_record_h image = NULL;
+ * contacts_record_create(_contacts_image._uri, &image);
+ *
+ * char *resource_path = app_get_resource_path();
+ * char caller_id_path[1024] = {0};
+ * snprintf(caller_id_path, sizeof(caller_id_path), "%s/caller_id.jpg", resource_path);
+ * free(resource_path);
+ * contacts_record_set_str(image, _contacts_image.path, caller_id_path);
+ *
+ * // add image record to contact
+ * contacts_record_add_child_record(contact, _contacts_contact.image, image);
+ * @endcode
+ *
+ *
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_MODULE_RECORDS Records
+ * In contacts-service, one of basic concept is a record.
+ * It may be helpful to know that a record represents an actual record in the internal database, but in general,
+ * you can think of a record as a piece of information, like an address, phone number or group of contacts.
+ * A record can be a complex set of data, containing other data, e.g. an address record contains country, region, and street, among others.<br>
+ * Also, the contained data can be a reference to another record.
+ * For example, a contact record contains the 'address' property, which is a reference to an address record.
+ * An address record belongs to a contact record - its 'contact_id' property is set to identifier of the corresponding contact (more on IDs later).
+ * In this case, the address is the contact's child record and the contact is the parent record.<br>
+ * Effectively, a record can be a node in a tree or graph of relations between records.
+ *
+ *
+ * @subsection CAPI_SOCIAL_CONTACTS_SVC_MODULE_RECORDS_URI URI
+ * Each record type has a special structure defined for it, called 'view', which contains identifiers of its properties. <br>
+ * Every view has a special field - _uri - that uniquely identifies the view.
+ * In many cases you need to use the _uri value to indicate what type of record you wish to create or operate on.
+ *
+ * APIs which needs _uri
+ * @code
+ * API int contacts_record_create( const char* view_uri, ... )
+ * API int contacts_filter_create( const char* view_uri, ... )
+ * API int contacts_query_create( const char* view_uri, ... )
+ * API int contacts_db_get_record( const char* view_uri, ... )
+ * API int contacts_db_delete_record( const char* view_uri, ... )
+ * API int contacts_db_get_all_records( const char* view_uri, ... )
+ * API int contacts_db_delete_records(const char* view_uri, ... )
+ * API int contacts_db_add_changed_cb( const char* view_uri, ... )
+ * API int contacts_db_remove_changed_cb( const char* view_uri, ... )
+ * API int contacts_db_get_changes_by_version( const char* view_uri, ... )
+ * API int contacts_db_search_records(const char* view_uri, ... )
+ * API int contacts_db_search_records_with_range(const char* view_uri, ... )
+ * API int contacts_db_get_count( const char* view_uri, ... )
+ * @endcode
+ *
+ *
+ * @subsection CAPI_SOCIAL_CONTACTS_SVC_MODULE_RECORDS_HANDLE Record handle
+ * To use a record, you must obtain its handle.
+ * There are many ways to obtains it, including creating a new record and referring to child records of a record. <br>
+ * When creating a record, you need to specify what type of record you want to create.
+ * This is where you should use the URI property.
+ *
+ * Sample code: Creates a contact record
+ * @code
+ * contacts_record_h contact = NULL;
+ * contacts_record_create(_contacts_contact._uri, &contact);
+ * @endcode
+ *
+ * Sample code: Gets a contact record with id
+ * @code
+ * contacts_record_h contact = NULL;
+ * contacts_db_get_record(_contacts_contact._uri, id, &contact);
+ * @endcode
+ *
+ *
+ * @subsection CAPI_SOCIAL_CONTACTS_SVC_MODULE_RECORDS_BASIC_TYPES Basic types
+ * A record can have basic properties of five types: integer, string, boolean, long integer, lli (long long int), double.
+ * Each property of basic type has functions to operate on it:
+ *
+ * <table>
+ * <caption> Table: Setter and getter functions </caption>
+ * <tr>
+ *    <th>Property type</th>
+ *    <th>Setter</th>
+ *    <th>Getter</th>
+ * </tr>
+ * <tr>
+ *    <td> string </td>
+ *    <td> @ref contacts_record_set_str </td>
+ *    <td> @ref contacts_record_get_str </td>
+ * </tr>
+ * <tr>
+ *    <td> integer </td>
+ *    <td> @ref contacts_record_set_int </td>
+ *    <td> @ref contacts_record_get_int </td>
+ * </tr>
+ * <tr>
+ *    <td> boolean </td>
+ *    <td> @ref contacts_record_set_bool </td>
+ *    <td> @ref contacts_record_get_bool </td>
+ * </tr>
+ * <tr>
+ *    <td> long long integer </td>
+ *    <td> @ref contacts_record_set_lli </td>
+ *    <td> @ref contacts_record_get_lli </td>
+ * </tr>
+ * <tr>
+ *    <td> double </td>
+ *    <td> @ref contacts_record_set_double </td>
+ *    <td> @ref contacts_record_get_double </td>
+ * </tr>
+ * </table>
+ *
+ * Above functions also require specifying which property you wish to get/set.
+ * Every getter and setter functions need record and property id.
+ * You can make property id by combine data-view name and property name.
+ * (.e.g. property id of a contact display_name property : _contacts_contact.display_name)
+ *
+ * Sample code : Sets the ‘ringtone_path’ property of a contact record.
+ * @code
+ * char *resource_path = app_get_resource_path();
+ * char ringtone_path[1024] = {0};
+ * snprintf(ringtone_path, sizeof(ringtone_path), "%s/ringtone.mp3", resource_path);
+ * free(resource_path);
+ * contacts_record_set_str(contact, _contacts_contact.ringtone_path, ringtone_path);
+ * @endcode
+ *
+ * Note on returned values ownership: string getter function have the "_p" postfix.
+ * It means that the returned value should not be freed by the application, as it is a pointer to data in an existing record.
+ *
+ * Sample code: Two ways of getting string property
+ * @code
+ * contacts_record_get_str(record, _contacts_person.display_name, &display_name);
+ * contacts_record_get_str_p(record, _contacts_person.display_name, &display_name);
+ * @endcode
+ * In the first case, the returned string should be freed by the application.
+ * In second one, display_name value will freed automatically when destroying record handle.
+ *
+ *
+ * @subsection CAPI_SOCIAL_CONTACTS_SVC_MODULE_RECORDS_CHILD Child
+ * A record can have properties of type 'record' called child records.
+ * A record can contain several records of a given type. For example, a ‘contact record’(parent) can contain many ‘address records’(children).
+ * The code below inserts an address record into a contact record.
+ * Note that it is not necessary to insert all records - just the contact record needs to be inserted into the database, it is enough for all information to be stored.
+ * Both records are then destroyed.
+ *
+ * Sample code: Add child record
+ * @code
+ * contacts_record_h address = NULL;
+ * contacts_record_h image = NULL;
+ * int contact_id = 0;
+ *
+ * // image, address record can be child record of contact record
+ * contacts_record_create(_contacts_contact._uri, &contact);
+ *
+ * contacts_record_create(_contacts_image._uri, &image);
+ * char *resource_path = app_get_resource_path();
+ * char caller_id_path[1024] = {0};
+ * snprintf(caller_id_path, sizeof(caller_id_path), "%s/caller_id.jpg", resource_path);
+ * free(resource_path);
+ * contacts_record_set_str(image, _contacts_image.path, caller_id_path);
+ * contacts_record_add_child_record(contact, _contacts_contact.image, image);
+ *
+ * contacts_record_create(_contacts_address._uri, &address);
+ * contacts_record_set_str(address, _contacts_address.country, "Korea");
+ * contacts_record_add_child_record(contact, _contacts_contact.address, address);
+ *
+ * // insert contact to DBs
+ * contacts_db_insert_record(contact, &contact_id);
+ * contacts_record_destroy(contact, true);
+ * @endcode
+ *
+ *
+ * @subsection CAPI_SOCIAL_CONTACTS_SVC_MODULE_RECORDS_RECORD_ID_PROPERTY Record id property
+ * ID is unique number which can identify a record Therefore, if you know the id of a record, you can directly handle the record.
+ * The id is read-only property, which is available after the record has been inserted into the database.
+ *
+ * Sample code: Gets a contact record with id
+ * @code
+ * contacts_record_h contact = NULL;
+ * contacts_record_create(_contacts_contact._uri, &contact);
+ *
+ * contacts_record_h name = NULL;
+ * contacts_record_create(_contacts_name._uri, &name);
+ * contacts_record_set_str(name, _contacts_name.first, “first name”);
+ * contacts_record_add_child_record(contact, _contacts_contact.name, name);
+ *
+ * int contact_id = 0;
+ * contacts_db_insert_record(contact, &contact_id); // contact_id is unique number of contact record
+ * contacts_record_destroy(contact, true); // contact is no longer usable
+ *
+ * contacts_db_get_record(_contacts_contact._uri, contact_id, &contact); // contact is now a handle to the same record as before
+ * char *display_name = NULL;
+ * contacts_record_get_str(contact, _contacts_contact.display_name, &display_name);
+ * contacts_record_destroy(contact, true); // contact is no longer usable
+ * @endcode
+ *
+ * Identifiers can also be used to establish a relation between two records. The following code sets an address record's 'contact_id' property to the id of the contact. contact_id make relate between the address record and the contact which is identified by the contact_id. After that is done, the address becomes one of the addresses connected to the contact. The address is now the contact's child record, the contact is the parent record.
+ *
+ * Sample code: Insert a address record with contact_id
+ * @code
+ * int contact_id = ... // acquire id of created contact
+ * int address_id = 0;
+ * contacts_record_create(_contacts_address._uri, &address);
+ * contacts_record_set_int(address, _contacts_address.contact_id, contact_id);
+ * // set other address properties
+ * // ...
+ * contacts_db_insert_record(address, &address_id);
+ * @endcode
+ *
+ * Having a record handle, you can access all records of a specific type related to the given record.
+ *
+ * Sample code: Gets a contact record
+ * @code
+ * int contact_id = ... // acquire id of created contact
+ * int address_num = 0;
+ * int i = 0;
+ * contacts_db_get_record(_contacts_contact._uri, contact_id, &contact);
+ * contacts_record_get_child_record_count(contact, _contacts_contact.address, &address_num);
+ * for(i=0; i<address_num; i++) {
+ *     contacts_record_h address = NULL;
+ *     contacts_record_get_child_record_at_p(contact, _contacts_contact.address, i, &address);
+ *     contacts_record_set_str(address, _contacts_address.country, "Korea");
+ * }
+ * contacts_db_update_record(contact);
+ * contacts_record_destroy(contact, true);
+ * @endcode
+ *
+ * This example is to change a country of addresses which are child records of a contact. Each address can be traversed by using contacts_record_get_child_record_at_p(). It is possible to apply the changes by updating the contact which is the parent record.
+ *
+ *
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_MODULE_LISTS Lists
+ * The contacts-service provides functions which can handle list of same type records. Lists concept is based on standard doubly linked list.
+ *
+ * To operate a list, you must obtain its handle. The handle is provided during creation of the list. List handle must destroy after use.
+ * @code
+ * API int contacts_list_create( contacts_list_h* contacts_list );
+ * API int contacts_list_destroy( contacts_list_h contacts_list, bool delete_child );
+ * @endcode
+ *
+ * If ‘delete_child’ parameter is the true, child resources will destroy automatically.
+ *
+ * Sample code: Create a list handle
+ * @code
+ * // get list handle with query
+ * contacts_list_h list = NULL;
+ * contacts_list_create(&list);
+ *
+ * // use list
+ * //  ...
+ *
+ * contacts_list_destroy(list, true);
+ * @endcode
+ *
+ * Sample code: Gets person list handle from database.
+ * @code
+ * // get list handle with query
+ * contacts_list_h list = NULL;
+ * contacts_db_get_all_records(_contacts_person._uri, 0, 0, &list);
+ *
+ * // use list
+ * // ...
+ *
+ * contacts_list_destroy(list, true);
+ * @endcode
+ *
+ *
+ * @subsection CAPI_SOCIAL_CONTACTS_SVC_MODULE_LISTS_CURSOR Cursor
+ * The list can be traversed by using cursor.
+ * @code
+ * API int contacts_list_first( contacts_list_h contacts_list );
+ * API int contacts_list_last( contacts_list_h contacts_list );
+ * API int contacts_list_next( contacts_list_h contacts_list );
+ * API int contacts_list_prev( contacts_list_h contacts_list );
+ * @endcode
+ *
+ * You can get a record of current cursor.
+ * @code
+ * API int contacts_list_get_current_record_p( contacts_list_h contacts_list, contacts_record_h* record );
+ * @endcode
+ *
+ * Sample code: Loop list
+ * @code
+ * contacts_list_h list = NULL;
+ * contacts_record_h record = NULL;
+ * contacts_db_get_all_records(_contacts_person._uri, 0, 0, &list);
+ * do {
+ *     contacts_list_get_current_record_p(list, &record);
+ *     if (NULL == record)
+ *                     break;
+ *     char *name = NULL;
+ *     contacts_record_get_str_p(record, _contacts_person.display_name, &name);
+ *     printf(“name=%s\n”, name);
+ * } while (CONTACTS_ERROR_NONE == contacts_list_next(list));
+ * contacts_list_destroy(list, true); // destroy child records automatically
+ * @endcode
+ *
+ *
+ * @subsection CAPI_SOCIAL_CONTACTS_SVC_MODULE_LISTS_ADD_REMOVE Add / Remove
+ * The contacts-service provides functions for adding/removing child record on list.
+ * @code
+ * API int contacts_list_add( contacts_list_h contacts_list, contacts_record_h record );
+ * API int contacts_list_remove( contacts_list_h contacts_list, contacts_record_h record );
+ * @endcode
+ *
+ * Sample code: Adds records to the list
+ * @code
+ * contacts_record_h group1 = NULL;
+ * contacts_record_create(_contacts_group._uri, &group1);
+ * contacts_record_set_str(group1, _contacts_group.name, “group test1”);
+ *
+ * contacts_record_h group2 = NULL;
+ * contacts_record_create(_contacts_group._uri, &group2);
+ * contacts_record_set_str(group2, _contacts_group.name, “group test2”);
+ *
+ * contacts_list_h list = NULL;
+ * contacts_list_create(&list);
+ *
+ * // Adds records to the list
+ * contacts_list_add(list, group1);
+ * contacts_list_add(list, group2);
+ *
+ * contacts_db_insert_records(list, NULL, NULL);
+ * contacts_list_destroy(list, true);
+ * @endcode
+ *
+ *
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_MODULE_BULK_APIS Bulk APIs
+ * Bulk APIs provide to insert/update/delete multiple records. There is no limit of record count on bulk API, but it cause a process to hang during the api is operated. Bulk APIs guarantee atomicity. That is, the api operations either all, or nothing.
+ *
+ * @code
+ * API int contacts_db_insert_records( contacts_list_h record_list, int **ids, int *count);
+ * API int contacts_db_update_records( contacts_list_h record_list);
+ * API int contacts_db_delete_records(const char* view_uri, int record_id_array[], int count);
+ * API int contacts_db_replace_records( contacts_list_h list, int record_id_array[], int count );
+ * @endcode
+ *
+ * Sample code: Insert two contact records using bulk API.
+ * @code
+ * contacts_record_h contact1;
+ * contacts_record_create(_contacts_contact.uri, &contact1);
+ *
+ * // fill contact record
+ * // ...
+ *
+ * contacts_record_h contact2;
+ * contacts_record_create(_contacts_contact._uri, &contact2);
+ *
+ * // fill contact record
+ * // ...
+ *
+ * contacts_list_h list = NULL;
+ * contacts_list_create(&list);
+ *
+ * contacts_list_add(list, contact1);
+ * contacts_list_add(list, contact2);
+ *
+ * int **ids = NULL;
+ * int count = 0;
+ *
+ * // Insert conact records using bulk API
+ * contacts_db_insert_records(list, &ids, &count);
+ *
+ * // use ids
+ * // ...
+ *
+ * contacts_list_destroy(list, true);
+ * free(ids);
+ * @endcode
+ *
+ *
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_MODULE_FILTER_AND_QUERIES Queries
+ * Queries are used to retrieve data which satisfies given criteria, like an integer property being greater than a given value, or a string property containing a given substring. Query needs a filter which can set the condition for search. The contacts-service provides query APIs for sorting, set projection and removing duplicated results.
+ *
+ *
+ * @subsection CAPI_SOCIAL_CONTACTS_SVC_MODULE_FILTER_AND_QUERIES_FILTER Filter
+ * The contacts Filter API provides the set of definitions and interfaces that enable application developers to make filters to set query. <br>
+ * When creating a filter, you need to specify what type of filter you want to create using _uri property. Filter handle must destroy after use.
+ * @code
+ * API int contacts_filter_create( const char* view_uri, contacts_filter_h* filter );
+ * API int contacts_filter_destroy( contacts_filter_h filter );
+ * @endcode
+ *
+ * Sample code: Set filter condition to contain a given substring.
+ * @code
+ * contacts_filter_add_str(filter, _contacts_person.display_name, CONTACTS_MATCH_CONTAINS, “1234”);
+ * @endcode
+ *
+ * Sample code: Set filter condition to property value is true.
+ * @code
+ * contacts_filter_add_bool(filter, _contacts_person.is_favorite, true);
+ * @endcode
+ *
+ * Conditions can be added to a filter. The conditions SHOULD be joined by using a AND and OR logical operator.
+ *
+ * Sample code: Creates composite filter with OR operator.
+ * @code
+ * contacts_filter_add_str(filter1, _contacts_person.display_name, CONTACTS_MATCH_CONTAINS, “1234”);
+ * contacts_filter_add_operator(filter1, CONTACTS_FILTER_OPERATOR_OR);
+ * contacts_filter_add_str(filter1, _contacts_person.display_name, CONTACTS_MATCH_CONTAINS, “5678”);
+ * @endcode
+ *
+ * Additionally, filters can join each other by using a AND and OR logical operator.
+ *
+ * Sample code: Creates joined filter with AND operator.
+ * @code
+ * contacts_filter_add_str(filter1, _contacts_person.display_name, CONTACTS_MATCH_CONTAINS, “1234”);
+ * contacts_filter_add_operator(filter1, CONTACTS_FILTER_OPERATOR_OR);
+ * contacts_filter_add_str(filter1, _contacts_person.display_name, CONTACTS_MATCH_CONTAINS, “5678”);
+ *
+ * contacts_filter_add_bool(filter2, _contacts_person.is_fovorite, true);
+ *
+ * contacts_filter_add_operator(filter1, CONTACTS_FILTER_OPERATOR_AND);
+ * contacts_filter_add_filter(filter1, filter2);
+ * @endcode
+ *
+ * Operator precedence in filters is determined by the order in which the conditions and filters are added. For example, if the following sequence is added:
+ * <table>
+ * <caption> Table: Filter and conditions </caption>
+ * <tr>
+ *     <th> Filter with conditions </th>
+ *     <th> Result </th>
+ * </tr>
+ * <tr>
+ *     <td>
+ *             Contidion C1 <br>
+ *             OR <br>
+ *             Contidion C2 <br>
+ *             AND <br>
+ *             Condition C3
+ *     </td>
+ *     <td> (C1 OR C2) AND C3 </td>
+ * </tr>
+ * <tr>
+ *     <td>
+ *             Filter F1: <br>
+ *                     Condition C1 <br>
+ *                     OR <br>
+ *                     Condition C2 <br><br>
+ *             Filter F2: <br>
+ *                     Condition C3 <br>
+ *                     OR <br>
+ *                     Condition C4 <br><br>
+ *             Filter F3: <br>
+ *                     Condition C5 <br>
+ *                     AND <br>
+ *                     F1 <br>
+ *                     AND <br>
+ *                     F2
+ *     </td>
+ *     <td>
+ *             (C5 AND F1) AND F2 <br>
+ *             Which is: <br>
+ *             (C5 AND (C1 OR C2)) AND (C3 OR C4)
+ *     </td>
+ * </tr>
+ * </table>
+ *
+ * Sample code: Create a filter which will accept addresses with their contact's id equal to a given id (integer filter), or their country property equal to "Korea" (string filter). Create a query and add the filter to it. Results are received in a list.
+ * @code
+ * contacts_filter_h filter = NULL;
+ * contacts_list_h list = NULL;
+ * contacts_query_h query = NULL;
+ *
+ * contacts_filter_create(_contacts_address._uri, &filter);
+ * contacts_filter_add_int(filter, _contacts_address.contact_id, CONTACTS_MATCH_EQUAL, id);
+ * contacts_filter_add_operator(filter, CONTACTS_FILTER_OPERATOR_OR);
+ * contacts_filter_add_str(filter, _contacts_address.country, CONTACTS_MATCH_EXACTLY, "Korea");
+ * contacts_query_create(_contacts_address._uri, &query);
+ * contacts_query_set_filter(query, filter);
+ *
+ * contacts_db_get_records_with_query(query, 0, 0, &list);
+ *
+ * contacts_filter_destroy(filter);
+ * contacts_query_destroy(query);
+ *
+ * // use the list
+ * // ...
+ *
+ * contacts_list_destroy(list, true);
+ *
+ * @endcode
+ *
+ *
+ * @subsection CAPI_SOCIAL_CONTACTS_SVC_MODULE_FILTER_AND_QUERIES_SORT Sort
+ * Query results list can sort by property id.
+ * @code
+ * API int contacts_query_set_sort(contacts_query_h query, unsigned int property_id, bool is_ascending);
+ * @endcode
+ *
+ * Sample code: Sort to query result by person id
+ * @code
+ * contacts_filter_add_str(filter, _contacts_person.display_name, CONTACTS_MATCH_CONTAINS, “Joe”);
+ * contacts_query_set_filter(query, filter);
+ * contacts_query_set_sort(query, _contacts_person.id, true);
+ *
+ * contacts_db_get_records_with_query(query, 0, 0, &list);
+ *
+ * contacts_query_destroy(query);
+ * contacts_filter_destroy(filter);
+ * contacts_list_destroy(person_list, true);
+ * @endcode
+ *
+ *
+ * @subsection CAPI_SOCIAL_CONTACTS_SVC_MODULE_FILTER_AND_QUERIES_PROJECTION Projection
+ * Projection allows you to query the Data for just those specific properties of a record that you actually need, at lower latency and cost than retrieving the entire properties.
+ * @code
+ * API int contacts_query_set_projection(contacts_query_h query, unsigned int property_ids[], int count)
+ * @endcode
+ *
+ * Sample code: Creates a filter which will get only person id, display name, image thumbnail path from the person record with its vibration path has “test” (string filter). Create a query and add the filter to it. Results are received in a list.
+ * @code
+ * contacts_filter_add_str (filter, _contacts_person.vibration, CONTACTS_MATCH_CONTAINS, "test");
+ * contacts_query_set_filter(query, filter);
+ *
+ * //set projections to get
+ * unsigned int person_projection[] = {
+ *     _contacts_person.id,
+ *             _contacts_person.display_name,
+ *             _contacts_person.image_thumbnail_path,
+ *     };
+ *     contacts_query_set_projection(query, person_projection, sizeof(person_projection)/sizeof(int));
+ *
+ *     contacts_db_get_records_with_query(query, 0, 0, &person_list);
+ *
+ * // use list
+ * // ...
+ *
+ * contacts_query_destroy(query);
+ * contacts_filter_destroy(filter);
+ * contacts_list_destroy(person_list, true);
+ * @endcode
+ *
+ *
+ *
+ * @subsection CAPI_SOCIAL_CONTACTS_SVC_MODULE_FILTER_AND_QUERIES_DISTINCT Distinct
+ * If you query to some read-only view with set projection, result list can contain duplicates. You can remove duplicates using _contacts_query_set_distinct.
+ * @code
+ * API int contacts_query_set_distinct(contacts_query_h query, bool set)
+ * endcode
+ *
+ * Sample code: Remove duplicates
+ * @code
+ * unsigned int projection[] = {
+ *     _contacts_person_number.person_id,
+ *             _contacts_person_number.display_name,
+ *     };
+ *     contacts_filter_create(_contacts_person_number._uri, &filter);
+ *     contacts_filter_add_bool(filter, _contacts_person_number.has_phonenumber, true);
+ *
+ * contacts_query_create(_contacts_person_number._uri, &query);
+ *     contacts_query_set_projection(query, projection, sizeof(projection)/sizeof(int));
+ *     contacts_query_set_filter(query, filter);
+ *
+ * // set distinct (remove duplicats)
+ * contacts_query_set_distinct(query, true);
+ *
+ * contacts_db_get_records_with_query(query, 0, 0, &list);
+ *
+ * // use list
+ * // ...
+ *
+ * contacts_list_destroy(list, true);
+ * contacts_query_destroy(query);
+ * contacts_filter_destroy(filter);
+ * @endcode
+ *
+ *
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_MODULE_DATABASE_CHANGE_NOTIFICATIONS Database Change Notifications
+ * Applications add/remove callback function to detect/ignore the contacts DB changes with contacts_db_add_changed_cb() / contacts_db_remove_changed_cb(). <br>
+ * Clients wait contacts change notification on client side. <br>
+ * If contacts is changed by another module, server publishes notification. The notification will be broadcast to subscribed modules. Finally, user callback function is called with user data.
+ *
+ * Sample code: Register person changes notification callback
+ * @code
+ * // callback function
+ * static void __person_changed_ cb(const char *view_uri, void *user_data)
+ * {
+ *     // jobs for callback
+ * }
+ * // add changed noti callback
+ * contacts_db_add_changed_cb(_contacts_person._uri,  __person_changed_cb,  NULL);
+ * @endcode
+ *
+ *
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_MODULE_VCARD vCard
+ * Contacts-service provides methods for parsing and making vCard . vCard APIs based on vCard v3.0 specification. For more information about vCard, refer to rfc2426 (http://www.ietf.org/rfc/rfc2426.txt)
+ *
+ *
+ * @subsection CAPI_SOCIAL_CONTACTS_SVC_MODULE_VCARD_PARSING_VCARD Parsing vCard
+ * There are two ways for parsing vCard.
+ *
+ * Sample code: Parsing vCard from stream then insert to database.
+ * @code
+ * // make contact record list from vcard stream
+ * contacts_list_h list = NULL;
+ * contacts_vcard_parse_to_contacts(vcard_stream, &list);
+ *
+ * int *ids = NULL;
+ * int count = 0;
+ * contacts_db_insert_records(list, &ids, &count);
+ *
+ * // use ids, count
+ * // ...
+ *
+ * free(ids);
+ * contacts_list_destroy(list, true);
+ * @endcode
+ *
+ * Sample code: Parsing vCard from file then insert to database
+ * @code
+ * // called to get a record handle of _contacts_contact view
+ * static bool __vcard_parse_cb(contacts_record_h record, void *user_data)
+ * {
+ *     int id = 0;
+ *     contacts_db_insert_record(record, &id);
+ *
+ *     // return false to break out of the loop
+ *     // return true to continue with the next iteration of the loop
+ *     return true;
+ *     }
+ *
+ * // parse vCard from file
+ * char *resource_path = app_get_resource_path();
+ * char vcard_path[1024] = {0};
+ * snprintf(vcard_path, sizeof(vcard_path), "%s/vcard.vcf", resource_path);
+ * free(resource_path);
+ * contacts_vcard_parse_to_contact_foreach(vcard_path, __vcard_parse_cb, NULL);
+ * @endcode
+ *
+ *
+ * @subsection CAPI_SOCIAL_CONTACTS_SVC_MODULE_VCARD_MAKING_VCARD_STREAM Making vCard stream
+ * You can make vcard stream from contact, person or my profile record.
+ *
+ * Sample code: Makes vCard stream using contact record.
+ * @code
+ * contacts_record_h contact;
+ * char *vcard_stream = NULL;
+ *
+ * contacts_db_get_record(_contacts_contact._uri, contact_id, &contact);
+ * contacts_vcard_make_from_contact(contact, &vcard_stream);
+ *
+ * // use the vcard stream
+ * // ...
+ *
+ * free(vcard_stream);
+ * contacts_record_destroy(contact, true);
+ * @endcode
+ *
+ */
+
+#endif //__TIZEN_SOCIAL_CONTACTS_DOC_H__
+
diff --git a/doc/images/Contact_structure.png b/doc/images/Contact_structure.png
new file mode 100644 (file)
index 0000000..9d2a615
Binary files /dev/null and b/doc/images/Contact_structure.png differ
diff --git a/doc/images/Creating_a_person_record.png b/doc/images/Creating_a_person_record.png
new file mode 100644 (file)
index 0000000..3fb830a
Binary files /dev/null and b/doc/images/Creating_a_person_record.png differ
diff --git a/doc/images/Link_person.png b/doc/images/Link_person.png
new file mode 100644 (file)
index 0000000..8af4d5b
Binary files /dev/null and b/doc/images/Link_person.png differ
diff --git a/doc/images/Properties.png b/doc/images/Properties.png
new file mode 100644 (file)
index 0000000..5192e03
Binary files /dev/null and b/doc/images/Properties.png differ
diff --git a/doc/images/Relationship_between_entities.png b/doc/images/Relationship_between_entities.png
new file mode 100644 (file)
index 0000000..35a77ef
Binary files /dev/null and b/doc/images/Relationship_between_entities.png differ
diff --git a/doc/images/Unlink_contact.png b/doc/images/Unlink_contact.png
new file mode 100644 (file)
index 0000000..2a27c7e
Binary files /dev/null and b/doc/images/Unlink_contact.png differ
diff --git a/doc/images/contacts_structure.png b/doc/images/contacts_structure.png
new file mode 100644 (file)
index 0000000..f00a9fe
Binary files /dev/null and b/doc/images/contacts_structure.png differ
diff --git a/helper/CMakeLists.txt b/helper/CMakeLists.txt
deleted file mode 100755 (executable)
index 1de9483..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src)
-LINK_DIRECTORIES(${CMAKE_BINARY_DIR})
-
-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 libsystemd-daemon)
-
-UNSET(EXTRA_CFLAGS)
-FOREACH(flag ${helper_pkgs_CFLAGS})
-       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
-
-ADD_EXECUTABLE(${TARGET} ${SRCS})
-SET_TARGET_PROPERTIES(${TARGET} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS})
-TARGET_LINK_LIBRARIES(${TARGET} ${PROJECT_NAME} ${helper_pkgs_LDFLAGS})
-
-INSTALL(TARGETS ${TARGET} DESTINATION bin)
-INSTALL(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/contacts-svc-helper.sh DESTINATION /etc/rc.d/init.d)
diff --git a/helper/contacts-svc-helper.sh b/helper/contacts-svc-helper.sh
deleted file mode 100755 (executable)
index 8966589..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/contacts-svc-helper &
diff --git a/helper/helper-socket.c b/helper/helper-socket.c
deleted file mode 100755 (executable)
index a9aae70..0000000
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * Contacts Service Helper
- *
- * 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 <unistd.h>
-#include <stdlib.h>
-#include <glib.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <errno.h>
-#include <contacts-svc.h>
-#include <sd-daemon.h>
-
-#include "internal.h"
-#include "cts-schema.h"
-#include "cts-sqlite.h"
-#include "cts-socket.h"
-#include "helper-socket.h"
-#include "sim.h"
-#include "normalize.h"
-#include "utils.h"
-
-
-static inline int helper_safe_write(int fd, char *buf, int buf_size)
-{
-       int ret, writed=0;
-       while (buf_size) {
-               ret = write(fd, buf+writed, buf_size);
-               if (-1 == ret) {
-                       if (EINTR == errno)
-                               continue;
-                       else
-                               return ret;
-               }
-               writed += ret;
-               buf_size -= ret;
-       }
-       return writed;
-}
-
-
-static inline int helper_safe_read(int fd, char *buf, int buf_size)
-{
-       int ret, read_size=0;
-       while (buf_size) {
-               ret = read(fd, buf+read_size, buf_size);
-               if (-1 == ret) {
-                       if (EINTR == errno)
-                               continue;
-                       else
-                               return ret;
-               }
-               read_size += ret;
-               buf_size -= ret;
-       }
-       return read_size;
-}
-
-
-static void helper_discard_msg(GIOChannel *src, int size)
-{
-       gsize len;
-       GError *gerr = NULL;
-       char dummy[CTS_SQL_MAX_LEN];
-
-       while (size) {
-               if (sizeof(dummy) < size) {
-                       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 -= len;
-               }
-               else {
-                       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 -= len;
-               }
-       }
-}
-
-int helper_socket_return(GIOChannel *src, int value, int attach_num, int *attach_size)
-{
-       int ret;
-       cts_socket_msg msg={0};
-
-       h_retvm_if(CTS_ERR_SOCKET_FAILED == value, value, "Socket has problems");
-       h_retvm_if(CTS_REQUEST_MAX_ATTACH < attach_num, CTS_ERR_ARG_INVALID,
-                       "Invalid msg(attach_num = %d)", attach_num);
-
-       msg.type = CTS_REQUEST_RETURN_VALUE;
-       msg.val = value;
-       msg.attach_num = attach_num;
-
-       memcpy(msg.attach_sizes, attach_size, attach_num * sizeof(int));
-
-       HELPER_DBG("fd = %d, MSG_TYPE=%d, MSG_VAL=%d, MSG_ATTACH_NUM=%d,"
-                       "MSG_ATTACH1=%d, MSG_ATTACH2=%d, MSG_ATTACH3=%d, MSG_ATTACH4=%d",
-                       g_io_channel_unix_get_fd(src), msg.type, msg.val, msg.attach_num,
-                       msg.attach_sizes[0], msg.attach_sizes[1], msg.attach_sizes[2],
-                       msg.attach_sizes[3]);
-
-       ret = helper_safe_write(g_io_channel_unix_get_fd(src), (char *)&msg, sizeof(msg));
-       h_retvm_if(-1 == ret, CTS_ERR_SOCKET_FAILED,
-                       "helper_safe_write() Failed(errno = %d)", errno);
-
-       return CTS_SUCCESS;
-}
-
-static void helper_handle_import_sim(GIOChannel *src)
-{
-       int ret;
-
-       ret = helper_sim_read_pb_record(src);
-       if (CTS_SUCCESS != ret) {
-               ERR("helper_sim_read_pb_record() Failed(%d)", ret);
-               helper_socket_return(src, ret, 0, NULL);
-       }
-}
-
-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)
-{
-       int ret=CTS_SUCCESS;
-       gsize len;
-       GError *gerr = NULL;
-       char receiver[CTS_SQL_MAX_LEN];
-
-       g_io_channel_read_chars(src, receiver, read_size, &len, &gerr);
-       if (gerr) {
-               ERR("g_io_channel_read_chars() Failed(%s)", gerr->message);
-               g_error_free(gerr);
-               return CTS_ERR_SOCKET_FAILED;
-       }
-       HELPER_DBG("Receiver = %s(%d), read_size = %d", receiver, len, read_size);
-
-       if (len) {
-               receiver[len] = '\0';
-               ret = helper_normalize_str(receiver, dest, dest_size);
-               h_retvm_if(ret < CTS_SUCCESS, ret, "helper_normalize_str() Failed(%d)", ret);
-               HELPER_DBG("Normalized text of %s = %s(%d)", receiver, dest, strlen(dest));
-       }
-       return ret;
-}
-
-static int helper_collation(GIOChannel *src, int read_size,
-               char *dest, int dest_size)
-{
-       int ret = CTS_SUCCESS;
-       gsize len;
-       GError *gerr = NULL;
-       char receiver[CTS_SQL_MAX_LEN];
-
-       g_io_channel_read_chars(src, receiver, read_size, &len, &gerr);
-       if (gerr) {
-               ERR("g_io_channel_read_chars() Failed(%s)", gerr->message);
-               g_error_free(gerr);
-               return CTS_ERR_SOCKET_FAILED;
-       }
-       HELPER_DBG("Receiver = %s(%d), read_size = %d", receiver, len, read_size);
-
-       if (len) {
-               receiver[len] = '\0';
-               ret = helper_collation_str(receiver, dest, dest_size);
-               h_retvm_if(ret < CTS_SUCCESS, ret, "helper_collation_str() Failed(%d)", ret);
-               HELPER_DBG("Sortkey of %s : %s, %d", receiver, dest, strlen(dest));
-       }
-       return ret;
-}
-
-static void helper_handle_normalize_str(GIOChannel *src, int size)
-{
-       HELPER_FN_CALL;
-       int str_len, ret;
-       char normalized_str[CTS_SQL_MAX_LEN];
-
-       ret = helper_normalize(src, size, normalized_str, sizeof(normalized_str));
-       if (ret < CTS_SUCCESS) {
-               ERR("helper_normalize() Failed(%d)", ret);
-               helper_socket_return(src, ret, 0, NULL);
-               return;
-       }
-       str_len = strlen(normalized_str);
-
-       ret = helper_socket_return(src, CTS_SUCCESS, 1, &str_len);
-       h_retm_if(CTS_SUCCESS != ret, "helper_socket_return() Failed(%d)", ret);
-       ret = helper_safe_write(g_io_channel_unix_get_fd(src), normalized_str, str_len);
-       h_retm_if(-1 == ret, "helper_safe_write() Failed(errno = %d)", errno);
-}
-
-static void helper_handle_normalize_name(GIOChannel *src, int* sizes)
-{
-       HELPER_FN_CALL;
-       int fd, ret;
-       int lang_type = 0;
-       int msg_size_buf[CTS_REQUEST_MAX_ATTACH]={0};
-       char normalized_first[CTS_SQL_MAX_LEN], normalized_last[CTS_SQL_MAX_LEN];
-       char sortkey[CTS_SQL_MAX_LEN];
-
-       if (sizes[CTS_NN_FIRST])
-       {
-               ret = helper_normalize(src, sizes[CTS_NN_FIRST], normalized_first,
-                               sizeof(normalized_first));
-               if (ret < CTS_SUCCESS) {
-                       ERR("helper_normalize() Failed(%d)", ret);
-                       helper_discard_msg(src, sizes[CTS_NN_LAST] + sizes[CTS_NN_SORTKEY]);
-                       helper_socket_return(src, ret, 0, NULL);
-                       return;
-               }
-               lang_type = ret;
-
-               msg_size_buf[CTS_NN_FIRST] = strlen(normalized_first);
-       }
-
-       if (sizes[CTS_NN_LAST])
-       {
-               ret = helper_normalize(src, sizes[CTS_NN_LAST], normalized_last,
-                               sizeof(normalized_last));
-               if (ret < CTS_SUCCESS) {
-                       ERR("helper_normalize() Failed(%d)", ret);
-                       helper_discard_msg(src, sizes[CTS_NN_SORTKEY]);
-                       helper_socket_return(src, ret, 0, NULL);
-                       return;
-               }
-               if (lang_type < ret) lang_type = ret;
-
-               msg_size_buf[CTS_NN_LAST] = strlen(normalized_last);
-       }
-
-       if (sizes[CTS_NN_SORTKEY])
-       {
-               ret = helper_collation(src, sizes[CTS_NN_SORTKEY], sortkey, sizeof(sortkey));
-               if (ret < CTS_SUCCESS) {
-                       ERR("helper_collation() Failed(%d)", ret);
-                       helper_socket_return(src, ret, 0, NULL);
-               }
-               msg_size_buf[CTS_NN_SORTKEY] = strlen(sortkey);
-       }
-
-       ret = helper_socket_return(src, lang_type, 3, msg_size_buf);
-       h_retm_if(CTS_SUCCESS != ret, "helper_socket_return() Failed(%d)", ret);
-
-       fd = g_io_channel_unix_get_fd(src);
-       ret = helper_safe_write(fd, normalized_first, msg_size_buf[0]);
-       h_retm_if(-1 == ret, "helper_safe_write() Failed(errno = %d)", errno);
-       ret = helper_safe_write(fd, normalized_last, msg_size_buf[1]);
-       h_retm_if(-1 == ret, "helper_safe_write() Failed(errno = %d)", errno);
-       ret = helper_safe_write(fd, sortkey, msg_size_buf[2]);
-       h_retm_if(-1 == ret, "helper_safe_write() Failed(errno = %d)", errno);
-}
-
-static gboolean request_handler(GIOChannel *src, GIOCondition condition,
-               gpointer data)
-{
-       int ret;
-       cts_socket_msg msg={0};
-       HELPER_FN_CALL;
-
-       if (G_IO_HUP & condition) {
-               close(g_io_channel_unix_get_fd(src));
-               return FALSE;
-       }
-
-       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, attach3 = %d",
-                       msg.attach_num, msg.attach_sizes[CTS_NN_FIRST],
-                       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);
-                       helper_socket_return(src, CTS_ERR_MSG_INVALID, 0, NULL);
-               }
-               else
-                       helper_handle_normalize_str(src, msg.attach_sizes[0]);
-               break;
-       case CTS_REQUEST_NORMALIZE_NAME:
-               if (CTS_NN_ATTACH_NUM != msg.attach_num) {
-                       ERR("Invalid CTS_NN_ATTACH_NUM = %d", msg.attach_num);
-                       helper_socket_return(src, CTS_ERR_MSG_INVALID, 0, NULL);
-               }else if (!msg.attach_sizes[CTS_NN_FIRST] && !msg.attach_sizes[CTS_NN_LAST]) {
-                       ERR("No attach names(CTS_NN_FIRST size = %d, CTS_NN_LAST size = %d ",
-                                       msg.attach_sizes[CTS_NN_FIRST], msg.attach_sizes[CTS_NN_LAST]);
-                       helper_socket_return(src, CTS_ERR_MSG_INVALID, 0, NULL);
-               }
-               else
-                       helper_handle_normalize_name(src, msg.attach_sizes);
-               break;
-       default:
-               ERR("Unknown request type(%d)", msg.type);
-               break;
-       }
-       return TRUE;
-}
-
-static gboolean socket_handler(GIOChannel *src,
-               GIOCondition condition, gpointer data)
-{
-       GIOChannel *channel;
-       int client_sockfd, sockfd = (int)data;
-       struct sockaddr_un clientaddr;
-       socklen_t client_len = sizeof(clientaddr);
-
-       HELPER_FN_CALL;
-
-       client_sockfd = accept(sockfd, (struct sockaddr *)&clientaddr, &client_len);
-       h_retvm_if(-1 == client_sockfd, TRUE, "accept() Failed(errno = %d)", errno);
-
-       channel = g_io_channel_unix_new(client_sockfd);
-       g_io_add_watch(channel, G_IO_IN|G_IO_HUP, request_handler, NULL);
-       g_io_channel_unref(channel);
-
-       return TRUE;
-}
-
-int helper_socket_init(void)
-{
-       int sockfd, ret;
-       struct sockaddr_un addr;
-       GIOChannel *gio;
-
-       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);
-
-               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);
-
-               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);
-       }
-
-       gio = g_io_channel_unix_new(sockfd);
-       g_io_add_watch(gio, G_IO_IN, socket_handler, (gpointer)sockfd);
-
-       return CTS_SUCCESS;
-}
diff --git a/helper/helper-socket.h b/helper/helper-socket.h
deleted file mode 100755 (executable)
index 9e68698..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Contacts Service Helper
- *
- * 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_HELPER_SOCKET_H__
-#define __CTS_HELPER_SOCKET_H__
-
-int helper_socket_init(void);
-int helper_socket_return(GIOChannel *src, int value, int attach_num, int *attach_size);
-
-#endif // __CTS_HELPER_SOCKET_H__
-
-
diff --git a/helper/internal.h b/helper/internal.h
deleted file mode 100755 (executable)
index 740fe93..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Contacts Service Helper
- *
- * 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_HELPER_INTERNAL_H__
-#define __CTS_HELPER_INTERNAL_H__
-
-#include <stdio.h>
-
-#ifndef API
-#define API __attribute__ ((visibility("default")))
-#endif
-
-// Additional Error
-enum {
-       CTS_ERR_NO_DB_FILE = -10000,
-};
-
-// DBUS Information
-#define CTS_DBUS_SERVICE "org.tizen.contacts.service"
-
-#define HELPER_DLOG_OUT
-//#define HELPER_DEBUGGING
-
-#ifdef HELPER_DLOG_OUT
-#define LOG_TAG "CONTACTS_SVC_HELPER"
-#include <dlog.h>
-#define DLOG(prio, fmt, arg...) \
-       do { SLOG(prio, LOG_TAG, fmt, ##arg); } while (0)
-#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
-#define PRT(prio, fmt, arg...) \
-       do { fprintf((prio?stderr:stdout),"[Contacts-svc-helper]" fmt"\n", ##arg); } while (0)
-#define INFO(fmt, arg...) PRT(0, fmt, ##arg)
-#define ERR(fmt, arg...) PRT(1,"%s(%d): " fmt, __FUNCTION__, __LINE__, ##arg)
-#define DBG(fmt, arg...) \
-       do { \
-               printf("\x1b[105;37m[Contacts-svc-helper]\x1b[0m(%s)" fmt "\n", __FUNCTION__, ##arg); \
-       } while (0)
-#endif //HELPER_DLOG_OUT
-
-#ifdef HELPER_DEBUGGING
-#define HELPER_FN_CALL DBG(">>>>>>>> called")
-#define HELPER_FN_END DBG("<<<<<<<< ended")
-#define HELPER_DBG(fmt, arg...) DBG("(%d) " fmt, __LINE__, ##arg)
-#else /* HELPER_DEBUGGING */
-#define HELPER_FN_CALL
-#define HELPER_FN_END
-#define HELPER_DBG(fmt, arg...)
-#endif /* HELPER_DEBUGGING */
-
-#define h_warn_if(expr, fmt, arg...) do { \
-       if (expr) { \
-               ERR(fmt, ##arg); \
-       } \
-} while (0)
-#define h_ret_if(expr) do { \
-       if (expr) { \
-               ERR("(%s)", #expr); \
-               return; \
-       } \
-} while (0)
-#define h_retv_if(expr, val) do { \
-       if (expr) { \
-               ERR("(%s)", #expr); \
-               return (val); \
-       } \
-} while (0)
-#define h_retm_if(expr, fmt, arg...) do { \
-       if (expr) { \
-               ERR(fmt, ##arg); \
-               return; \
-       } \
-} while (0)
-#define h_retvm_if(expr, val, fmt, arg...) do { \
-       if (expr) { \
-               ERR(fmt, ##arg); \
-               return (val); \
-       } \
-} while (0)
-
-#endif // __CTS_HELPER_INTERNAL_H__
-
diff --git a/helper/localize.c b/helper/localize.c
deleted file mode 100755 (executable)
index b7be1f6..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Contacts Service Helper
- *
- * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Youngjae Shin <yj99.shin@samsung.com>
- *          Donghee Ye <donghee.ye@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 "internal.h"
-#include "cts-normalize.h"
-#include "localize.h"
-
-/* korean -Hangul Jamo extended A*/
-#define CTS_JAMO_A_START (UChar)0xA960
-#define CTS_JAMO_A_END (UChar)0xA97F
-
-/* korean -Hangul Jamo extended B*/
-#define CTS_JAMO_B_START (UChar)0xD7B0
-#define CTS_JAMO_B_END (UChar)0xD7FF
-
-/* korean -Hangul Compatability */
-#define CTS_HAN_C_START (UChar)0x3130
-#define CTS_HAN_C_END (UChar)0x318F
-
-/* korean -Hangul halfwidth */
-#define CTS_HAN_HALF_START (UChar)0xFFA0
-#define CTS_HAN_HALF_END (UChar)0xFFDC
-
-static const char hangul_compatibility_choseong[] = {
-       0x31, 0x32, 0x34, 0x37, 0x38, 0x39, 0x40, 0x41,
-       0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
-       0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x65, 0x66, 0x6E,
-       0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-       0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80,
-       0x81, 0x84, 0x85, 0x86, 0x00};
-static const unsigned char hangul_jamo_choseong[] = {
-       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x1A, 0x06, 0x07,           // to choseong 0x1100~0x115F
-       0x08, 0x21, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-       0x10, 0x11, 0x12, 0x14, 0x15, 0x1C, 0x1D, 0x1E, 0x20,
-       0x22, 0x23, 0x27, 0x29, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
-       0x32, 0x36, 0x40, 0x47, 0x4C, 0x57, 0x58, 0x59, 0x00};
-
-static const char hangul_compatibility_jungseong[] = {
-       0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,
-       0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E,
-       0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x87, 0x88,
-       0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x00};
-static const unsigned char hangul_jamo_jungseong[] = {
-       0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,   // to jungseong 0x1160~0x11A7
-       0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
-       0x73, 0x74, 0x75, 0x60, 0x84, 0x85, 0x88, 0x91, 0x92,
-       0x94, 0x9E, 0xA1, 0x00};
-
-static const char hangul_compatibility_jongseong[] = {
-       0x33, 0x35, 0x36, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E,
-       0x3F, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
-       0x6F, 0x70, 0x82, 0x83, 0x00};
-static const unsigned char hangul_jamo_jongseong[] = {
-       0xAA, 0xAC, 0xAD, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5,   // to jongseong 0x11A8~0x11FF
-       0xC7, 0xC8, 0xCC, 0xCE, 0xD3, 0xD7, 0xD9, 0xDF, 0xF1, 0xF2, 0x00};
-
-static inline bool is_hangul(UChar src)
-{
-       if ((0x1100 == (src & 0xFF00))       /* korean -Hangul Jamo*/
-                       || CTS_COMPARE_BETWEEN(CTS_JAMO_A_START, src, CTS_JAMO_A_END)
-                       || CTS_COMPARE_BETWEEN(CTS_JAMO_B_START, src, CTS_JAMO_B_END)
-                       || CTS_COMPARE_BETWEEN(CTS_HAN_C_START, src, CTS_HAN_C_END)
-                       || CTS_COMPARE_BETWEEN(CTS_HAN_HALF_START, src, CTS_HAN_HALF_END))
-               return true;
-       else
-               return FALSE;
-}
-
-static inline void hangul_compatibility2jamo(UChar *src)
-{
-       int unicode_value1 = 0;
-       int unicode_value2 = 0;
-
-       unicode_value1 = (0xFF00 & (*src)) >> 8;
-       unicode_value2 = (0xFF & (*src));
-
-       /* korean -Hangul Jamo halfwidth*/
-       if (CTS_COMPARE_BETWEEN(CTS_HAN_HALF_START, *src, CTS_HAN_HALF_END)) {
-               unicode_value1 = 0x31;
-
-               if (unicode_value2 < 0xBF)
-                       unicode_value2 -= 0x70;
-               else if (unicode_value2 < 0xC8)
-                       unicode_value2 -= 0x73;
-               else if (unicode_value2 < 0xD0)
-                       unicode_value2 -= 0x75;
-               else if (unicode_value2 < 0xD8)
-                       unicode_value2 -= 0x77;
-               else
-                       unicode_value2 -= 0x79;
-
-               (*src) = unicode_value1 << 8 | unicode_value2;
-       }
-
-       if (CTS_COMPARE_BETWEEN(CTS_HAN_C_START, *src, CTS_HAN_C_END))
-       {
-               char *pos;
-               if (NULL != (pos = strchr(hangul_compatibility_choseong, unicode_value2)))
-               {
-                       unicode_value1 = 0x11;
-                       unicode_value2 = hangul_jamo_choseong[pos - hangul_compatibility_choseong];
-                       (*src) = unicode_value1 << 8 | unicode_value2;
-               }
-               else if (NULL != (pos = strchr(hangul_compatibility_jungseong, unicode_value2)))
-               {
-                       unicode_value1 = 0x11;
-                       unicode_value2 = hangul_jamo_jungseong[pos - hangul_compatibility_jungseong];
-                       (*src) = unicode_value1 << 8 | unicode_value2;
-               }
-               else if (NULL != (pos = strchr(hangul_compatibility_jongseong, unicode_value2)))
-               {
-                       unicode_value1 = 0x11;
-                       unicode_value2 = hangul_jamo_jongseong[pos - hangul_compatibility_jongseong];
-                       (*src) = unicode_value1 << 8 | unicode_value2;
-               }
-       }
-}
-
-int helper_check_language(UChar *word)
-{
-       int type;
-
-       if (CTS_COMPARE_BETWEEN('0', word[0], '9')) {
-               type = CTS_LANG_NUMBER;
-       }
-       else if (CTS_COMPARE_BETWEEN(0x41, word[0], 0x7A)) {  /* english */
-               type = CTS_LANG_ENGLISH;
-       }
-       else if (is_hangul(word[0])){
-               type = CTS_LANG_KOREAN;
-       }
-       else
-               type = CTS_LANG_OTHERS;
-
-       return type;
-}
-
-void helper_extra_normalize(UChar *word, int32_t word_size)
-{
-       int i;
-       for (i=0;i<word_size;i++) {
-               if (is_hangul(word[i])) {
-                       hangul_compatibility2jamo(&word[i]);
-               }
-       }
-}
-
-int helper_get_language_type(const char *system_lang)
-{
-       int type;
-
-       h_retv_if(NULL == system_lang, CTS_LANG_OTHERS);
-
-       if (!strncmp(system_lang, "ko", sizeof("ko") - 1))
-               type = CTS_LANG_KOREAN;
-       else if (!strncmp(system_lang, "en", sizeof("en") - 1))
-               type = CTS_LANG_ENGLISH;
-       else
-               type = CTS_LANG_OTHERS;
-
-       return type;
-}
-
diff --git a/helper/localize.h b/helper/localize.h
deleted file mode 100755 (executable)
index 9bcef54..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Contacts Service Helper
- *
- * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Youngjae Shin <yj99.shin@samsung.com>
- *          Donghee Ye <donghee.ye@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_HELPER_LOCALIZE_H__
-#define __CTS_HELPER_LOCALIZE_H__
-
-#include <unicode/utypes.h>
-
-int helper_check_language(UChar *word);
-int helper_get_language_type(const char *system_lang);
-void helper_extra_normalize(UChar *word, int32_t word_size);
-
-#endif // __CTS_HELPER_LOCALIZE_H__
diff --git a/helper/main.c b/helper/main.c
deleted file mode 100755 (executable)
index ec63e8b..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Contacts Service Helper
- *
- * 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 <glib.h>
-#include <string.h>
-#include <contacts-svc.h>
-
-#include "internal.h"
-#include "schema-recovery.h"
-#include "helper-socket.h"
-#include "utils.h"
-#include "sqlite.h"
-
-int main(int argc, char **argv)
-{
-       int ret;
-       GMainLoop *cts_helper_loop = NULL;
-
-       helper_check_schema();
-       if (2 <= argc && !strcmp(argv[1], "schema"))
-               return CTS_SUCCESS;
-
-       cts_helper_loop = g_main_loop_new (NULL, FALSE);
-       h_retvm_if(NULL == cts_helper_loop, CTS_ERR_FAIL, "g_main_loop_new() Failed");
-
-       ret = contacts_svc_connect();
-       h_retvm_if(CTS_SUCCESS != ret, ret, "contacts_svc_connect() Failed(%d)", ret);
-
-       helper_socket_init();
-       helper_init_configuration();
-
-       g_main_loop_run(cts_helper_loop);
-
-       helper_final_configuration();
-       ret = contacts_svc_disconnect();
-       h_retvm_if(CTS_SUCCESS != ret, ret, "contacts_svc_disconnect() Failed(%d)", ret);
-
-       g_main_loop_unref(cts_helper_loop);
-       return CTS_SUCCESS;
-}
diff --git a/helper/normalize.c b/helper/normalize.c
deleted file mode 100755 (executable)
index fd1e394..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Contacts Service Helper
- *
- * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Youngjae Shin <yj99.shin@samsung.com>
- *          Donghee Ye <donghee.ye@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 <string.h>
-#include <unicode/ustring.h>
-#include <unicode/unorm.h>
-#include <unicode/ucol.h>
-#include <contacts-svc.h>
-#include <vconf.h>
-#include <vconf-keys.h>
-
-#include "internal.h"
-#include "cts-sqlite.h"
-#include "localize.h"
-#include "normalize.h"
-#include "utils.h"
-
-#define array_sizeof(a) (sizeof(a) / sizeof(a[0]))
-
-int helper_unicode_to_utf8(char *src, int src_len, char *dest, int dest_size)
-{
-       int32_t size = 0;
-       UErrorCode status = 0;
-       UChar *unicode_src = (UChar *)src;
-
-       u_strToUTF8(dest, dest_size, &size, unicode_src, -1, &status);
-       h_retvm_if(U_FAILURE(status), CTS_ERR_ICU_FAILED,
-                       "u_strToUTF8() Failed(%s)", u_errorName(status));
-
-       dest[size]='\0';
-       return CTS_SUCCESS;
-}
-
-static inline int check_utf8(char c)
-{
-       if ((c & 0xff) < (128 & 0xff))
-               return 1;
-       else if ((c & (char)0xe0) == (char)0xc0)
-               return 2;
-       else if ((c & (char)0xf0) == (char)0xe0)
-               return 3;
-       else if ((c & (char)0xf8) == (char)0xf0)
-               return 4;
-       else if ((c & (char)0xfc) == (char)0xf8)
-               return 5;
-       else if ((c & (char)0xfe) == (char)0xfc)
-               return 6;
-       else
-               return CTS_ERR_FAIL;
-}
-
-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*2];
-       UChar result[CTS_SQL_MAX_LEN*2];
-       int i = 0;
-       int j = 0;
-       int str_len = strlen(src);
-       int char_len = 0;
-
-       for (i=0;i<str_len;i+=char_len) {
-               char char_src[10];
-               char_len = check_utf8(src[i]);
-               memcpy(char_src, &src[i], char_len);
-               char_src[char_len] = '\0';
-
-               u_strFromUTF8(tmp_result, array_sizeof(tmp_result), NULL, char_src, -1, &status);
-               h_retvm_if(U_FAILURE(status), CTS_ERR_ICU_FAILED,
-                               "u_strFromUTF8() Failed(%s)", u_errorName(status));
-
-               u_strToLower(tmp_result, array_sizeof(tmp_result), tmp_result, -1, NULL, &status);
-               h_retvm_if(U_FAILURE(status), CTS_ERR_ICU_FAILED,
-                               "u_strToLower() Failed(%s)", u_errorName(status));
-
-               size = unorm_normalize(tmp_result, -1, UNORM_NFD, 0,
-                               (UChar *)result, array_sizeof(result), &status);
-               h_retvm_if(U_FAILURE(status), CTS_ERR_ICU_FAILED,
-                               "unorm_normalize(%s) Failed(%s)", char_src, u_errorName(status));
-
-               if (0 == i)
-                       type = helper_check_language(result);
-               helper_extra_normalize(result, size);
-
-               u_strToUTF8(&dest[j], dest_size-j, &size, result, -1, &status);
-               h_retvm_if(U_FAILURE(status), CTS_ERR_ICU_FAILED,
-                               "u_strToUTF8() Failed(%s)", u_errorName(status));
-               j += size;
-               dest[j++] = 0x01;
-       }
-       dest[j]='\0';
-       HELPER_DBG("src(%s) is transformed(%s)", src, dest);
-       return type;
-}
-
-int helper_collation_str(const char *src, char *dest, int dest_size)
-{
-       HELPER_FN_CALL;
-       int32_t size = 0;
-       UErrorCode status = 0;
-       UChar tmp_result[CTS_SQL_MAX_LEN];
-       UCollator *collator;
-       const char *region;
-
-       region = vconf_get_str(VCONFKEY_REGIONFORMAT);
-       HELPER_DBG("region %s", region);
-       collator = ucol_open(region, &status);
-       h_retvm_if(U_FAILURE(status), CTS_ERR_ICU_FAILED,
-                       "ucol_open() Failed(%s)", u_errorName(status));
-
-       if (U_FAILURE(status)){
-               ERR("ucol_setAttribute Failed(%s)", u_errorName(status));
-               ucol_close(collator);
-               return CTS_ERR_ICU_FAILED;
-       }
-
-       u_strFromUTF8(tmp_result, array_sizeof(tmp_result), NULL, src, -1, &status);
-       if (U_FAILURE(status)){
-               ERR("u_strFromUTF8 Failed(%s)", u_errorName(status));
-               ucol_close(collator);
-               return CTS_ERR_ICU_FAILED;
-       }
-       size = ucol_getSortKey(collator, tmp_result, -1, (uint8_t *)dest, dest_size);
-       ucol_close(collator);
-       dest[size]='\0';
-
-       return CTS_SUCCESS;
-}
-
-API int cts_helper_normalize_name(char dest[][CTS_SQL_MAX_LEN])
-{
-       int lang_type=0;
-       int ret=CTS_ERR_NO_DATA;
-       int sizes[CTS_NN_MAX]={0};
-       char normalized_first[CTS_SQL_MAX_LEN];
-       char normalized_last[CTS_SQL_MAX_LEN];
-
-       sizes[CTS_NN_FIRST] = strlen(dest[CTS_NN_FIRST]);
-       sizes[CTS_NN_LAST] = strlen(dest[CTS_NN_LAST]);
-
-       if (sizes[CTS_NN_FIRST]) {
-               ret = helper_normalize_str(dest[CTS_NN_FIRST], normalized_first,
-                               sizeof(normalized_first));
-               h_retvm_if(ret < CTS_SUCCESS, ret, "helper_normalize_str() Failed(%d)", ret);
-               lang_type = ret;
-
-               sizes[CTS_NN_FIRST] = strlen(normalized_first);
-       }
-
-       if (sizes[CTS_NN_LAST]) {
-               ret = helper_normalize_str(dest[CTS_NN_LAST], normalized_last,
-                               sizeof(normalized_first));
-               h_retvm_if(ret < CTS_SUCCESS, ret, "helper_normalize_str() Failed(%d)", ret);
-               if (lang_type < ret) lang_type = ret;
-
-               sizes[CTS_NN_LAST] = strlen(normalized_last);
-       }
-
-       if (sizes[CTS_NN_FIRST])
-               snprintf(dest[CTS_NN_FIRST], sizeof(dest[CTS_NN_FIRST]), "%s", normalized_first);
-       if (sizes[CTS_NN_LAST])
-               snprintf(dest[CTS_NN_LAST], sizeof(dest[CTS_NN_LAST]), "%s", normalized_last);
-
-       return lang_type;
-}
-
diff --git a/helper/normalize.h b/helper/normalize.h
deleted file mode 100755 (executable)
index 666c11f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Contacts Service Helper
- *
- * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Youngjae Shin <yj99.shin@samsung.com>
- *          Donghee Ye <donghee.ye@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_HELPER_NORMALIZE_H__
-#define __CTS_HELPER_NORMALIZE_H__
-
-#include "cts-normalize.h"
-
-int helper_normalize_str(const char *src, char *dest, int dest_size);
-int helper_collation_str(const char *src, char *dest, int dest_size);
-int helper_unicode_to_utf8(char *src, int src_len, char *dest, int dest_size);
-
-#endif // __CTS_HELPER_NORMALIZE_H__
-
diff --git a/helper/schema-recovery.c b/helper/schema-recovery.c
deleted file mode 100755 (executable)
index 851aa24..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Contacts Service Helper
- *
- * 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 <sys/stat.h>
-#include <db-util.h>
-#include <sqlite3.h>
-#include <contacts-svc.h>
-
-#include "internal.h"
-#include "sqlite.h"
-#include "schema.h"
-#include "schema-recovery.h"
-#include "cts-schema.h"
-
-static inline int helper_check_db_file(void)
-{
-       int fd = open(CTS_DB_PATH, O_RDONLY);
-       h_retvm_if(-1 == fd, CTS_ERR_NO_DB_FILE,
-                       "DB file(%s) is not exist", CTS_DB_PATH);
-
-       close(fd);
-       return CTS_SUCCESS;
-}
-
-static inline int remake_db_file()
-{
-       int ret, fd;
-       char *errmsg;
-       sqlite3 *db;
-
-       ret = helper_db_open(&db);
-       h_retvm_if(CTS_SUCCESS != ret, ret, "helper_db_open() Failed(%d)", ret);
-
-       ret = sqlite3_exec(db, schema_query, NULL, 0, &errmsg);
-       if (SQLITE_OK != ret) {
-               ERR("remake contacts DB file is Failed : %s", errmsg);
-               sqlite3_free(errmsg);
-       }
-
-       helper_db_close();
-
-       fd = open(CTS_DB_PATH, O_CREAT | O_RDWR, 0660);
-       h_retvm_if(-1 == fd, CTS_ERR_FAIL, "open Failed");
-
-       fchown(fd, getuid(), CTS_SECURITY_FILE_GROUP);
-       fchmod(fd, CTS_SECURITY_DEFAULT_PERMISSION);
-       close(fd);
-
-       fd = open(CTS_DB_JOURNAL_PATH, O_CREAT | O_RDWR, 0660);
-       h_retvm_if(-1 == fd, CTS_ERR_FAIL, "open Failed");
-
-       fchown(fd, getuid(), CTS_SECURITY_FILE_GROUP);
-       fchmod(fd, CTS_SECURITY_DEFAULT_PERMISSION);
-       close(fd);
-
-       return CTS_SUCCESS;
-}
-
-int helper_check_schema(void)
-{
-       if (CTS_ERR_NO_DB_FILE == helper_check_db_file())
-               remake_db_file();
-
-       return CTS_SUCCESS;
-}
-
diff --git a/helper/sim.c b/helper/sim.c
deleted file mode 100755 (executable)
index a65a1c6..0000000
+++ /dev/null
@@ -1,981 +0,0 @@
-/*
- * Contacts Service Helper
- *
- * 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 <string.h>
-#include <tapi_common.h>
-#include <ITapiSim.h>
-#include <ITapiPhonebook.h>
-#include <TapiUtility.h>
-#include <contacts-svc.h>
-
-#include "cts-addressbook.h"
-#include "helper-socket.h"
-#include "internal.h"
-#include "normalize.h"
-#include "sqlite.h"
-#include "utils.h"
-#include "sim.h"
-
-#define CTS_SIM_EVENT_NUM 2
-#define CTS_TAPI_SIM_PB_MAX 0xFFFF
-#define CTS_MIN(a, b) (a>b)?b:a
-
-#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_sim_data = NULL;
-static TapiHandle *handle;
-static int helper_register_tapi_cnt = 0;
-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];
-
-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_deinit(void)
-{
-       int ret;
-       if (1 == helper_register_tapi_cnt) {
-               ret = tel_deinit(handle);
-               h_retvm_if(TAPI_API_SUCCESS != ret, CTS_ERR_TAPI_FAILED,
-                               "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)
-{
-       int ret;
-
-       ret = helper_insert_SDN_contact((char *)pb2g_data->name, (char *)pb2g_data->number);
-       h_retvm_if(ret != CTS_SUCCESS, ret, "helper_insert_SDN_contact() Failed(%d)", ret);
-
-       return ret;
-}
-
-static int helper_insert_2g_contact(TelSimPbRecord_t *pb2g_data)
-{
-       int ret, found_id;
-       char uid[32];
-       CTSstruct *contact;
-       GSList *numbers=NULL;
-       CTSvalue *name_val, *number_val, *base;
-
-       h_retvm_if(pb2g_data->index <= 0, CTS_ERR_ARG_INVALID, "The index(%d) is invalid", pb2g_data->index);
-
-       snprintf(uid, sizeof(uid), "SIM:%s-%s-%s-%d",
-                       TAPI_imsi.szMcc, TAPI_imsi.szMnc, TAPI_imsi.szMsin, pb2g_data->index);
-       HELPER_DBG("UID = %s", uid);
-
-       found_id = contacts_svc_find_contact_by(CTS_FIND_BY_UID, uid);
-
-       contact = contacts_svc_struct_new(CTS_STRUCT_CONTACT);
-
-       base = contacts_svc_value_new(CTS_VALUE_CONTACT_BASE_INFO);
-       if (base) {
-               contacts_svc_value_set_str(base, CTS_BASE_VAL_UID_STR, uid);
-               contacts_svc_struct_store_value(contact, CTS_CF_BASE_INFO_VALUE, base);
-               contacts_svc_value_free(base);
-       }
-
-       name_val = contacts_svc_value_new(CTS_VALUE_NAME);
-       if (name_val) {
-               contacts_svc_value_set_str(name_val, CTS_NAME_VAL_DISPLAY_STR, (char *)pb2g_data->name);
-               contacts_svc_struct_store_value(contact, CTS_CF_NAME_VALUE, name_val);
-               contacts_svc_value_free(name_val);
-       }
-
-       number_val = contacts_svc_value_new(CTS_VALUE_NUMBER);
-       if (number_val) {
-               contacts_svc_value_set_str(number_val, CTS_NUM_VAL_NUMBER_STR,
-                               (char *)pb2g_data->number);
-               contacts_svc_value_set_int(number_val, CTS_NUM_VAL_TYPE_INT, CTS_NUM_TYPE_CELL);
-               contacts_svc_value_set_bool(number_val, CTS_NUM_VAL_DEFAULT_BOOL, true);
-       }
-       numbers = g_slist_append(numbers, number_val);
-
-       contacts_svc_struct_store_list(contact, CTS_CF_NUMBER_LIST, numbers);
-       contacts_svc_value_free(number_val);
-       g_slist_free(numbers);
-
-       if (0 < found_id) {
-               CTSstruct *temp;
-               ret = contacts_svc_get_contact(found_id, &temp);
-               if (CTS_SUCCESS == ret) {
-                       contacts_svc_struct_merge(temp, contact);
-                       contacts_svc_struct_free(contact);
-                       contact = temp;
-                       ret = contacts_svc_update_contact(contact);
-                       h_warn_if(ret < CTS_SUCCESS, "contacts_svc_update_contact() Failed(%d)", ret);
-               } else {
-                       ERR("contacts_svc_get_contact() Failed(%d)", ret);
-               }
-       } else {
-               ret = contacts_svc_insert_contact(CTS_ADDRESSBOOK_INTERNAL, contact);
-               h_warn_if(ret < CTS_SUCCESS, "contacts_svc_insert_contact() Failed(%d)", ret);
-       }
-       contacts_svc_struct_free(contact);
-
-       return ret;
-}
-
-static inline GSList* helper_insert_3g_contact_num(GSList *numbers, char *number)
-{
-       CTSvalue *value;
-
-       value = contacts_svc_value_new(CTS_VALUE_NUMBER);
-       if (value) {
-               contacts_svc_value_set_str(value, CTS_NUM_VAL_NUMBER_STR, number);
-               //contacts_svc_value_set_int(value, CTS_NUM_VAL_TYPE_INT, CTS_NUM_TYPE_CELL);
-       }
-       return g_slist_append(numbers, value);
-}
-
-static inline GSList* helper_insert_3g_contact_email(GSList *emails, char *email)
-{
-       CTSvalue *value;
-
-       value = contacts_svc_value_new(CTS_VALUE_EMAIL);
-       if (value)
-               contacts_svc_value_set_str(value, CTS_EMAIL_VAL_ADDR_STR, email);
-       return g_slist_append(emails, value);
-}
-
-static int helper_insert_3g_contact(TelSimPbRecord_t *pb3g_data)
-{
-       int ret, found_id;
-       char uid[32];
-       CTSstruct *contact;
-       CTSvalue *name_val=NULL, *number_val, *base;
-       GSList *numbers=NULL, *emails=NULL;
-
-       h_retvm_if(pb3g_data->index <= 0, CTS_ERR_ARG_INVALID, "The index(%d) is invalid", pb3g_data->index);
-
-       snprintf(uid, sizeof(uid), "SIM:%s-%s-%s-%d",
-                       TAPI_imsi.szMcc, TAPI_imsi.szMnc, TAPI_imsi.szMsin, pb3g_data->index);
-       HELPER_DBG("UID = %s", uid);
-       found_id = contacts_svc_find_contact_by(CTS_FIND_BY_UID, uid);
-
-       contact = contacts_svc_struct_new(CTS_STRUCT_CONTACT);
-
-       base = contacts_svc_value_new(CTS_VALUE_CONTACT_BASE_INFO);
-       if (base) {
-               contacts_svc_value_set_str(base, CTS_BASE_VAL_UID_STR, uid);
-               contacts_svc_struct_store_value(contact, CTS_CF_BASE_INFO_VALUE, base);
-               contacts_svc_value_free(base);
-       }
-
-       if (*pb3g_data->name) {
-               name_val = contacts_svc_value_new(CTS_VALUE_NAME);
-               if (name_val)
-                       contacts_svc_value_set_str(name_val, CTS_NAME_VAL_FIRST_STR, (char *)pb3g_data->name);
-
-               contacts_svc_struct_store_value(contact, CTS_CF_NAME_VALUE, name_val);
-       }
-
-       if (*pb3g_data->number) {
-               number_val = contacts_svc_value_new(CTS_VALUE_NUMBER);
-               if (number_val) {
-                       contacts_svc_value_set_str(number_val, CTS_NUM_VAL_NUMBER_STR, (char *)pb3g_data->number);
-                       //contacts_svc_value_set_int(number_val, CTS_NUM_VAL_TYPE_INT, CTS_NUM_TYPE_CELL);
-                       contacts_svc_value_set_bool(number_val, CTS_NUM_VAL_DEFAULT_BOOL, true);
-               }
-               numbers = g_slist_append(numbers, number_val);
-       }
-
-       numbers = helper_insert_3g_contact_num(numbers, (char *)pb3g_data->anr1);
-       numbers = helper_insert_3g_contact_num(numbers, (char *)pb3g_data->anr2);
-       numbers = helper_insert_3g_contact_num(numbers, (char *)pb3g_data->anr3);
-       contacts_svc_struct_store_list(contact, CTS_CF_NUMBER_LIST, numbers);
-
-       emails = helper_insert_3g_contact_email(emails, (char *)pb3g_data->email1);
-       emails = helper_insert_3g_contact_email(emails, (char *)pb3g_data->email2);
-       emails = helper_insert_3g_contact_email(emails, (char *)pb3g_data->email3);
-       emails = helper_insert_3g_contact_email(emails, (char *)pb3g_data->email4);
-       contacts_svc_struct_store_list(contact, CTS_CF_EMAIL_LIST, emails);
-
-       if (0 < found_id) {
-               CTSstruct *temp;
-               ret = contacts_svc_get_contact(found_id, &temp);
-               if (CTS_SUCCESS == ret) {
-                       contacts_svc_struct_merge(temp, contact);
-                       contacts_svc_struct_free(contact);
-                       contact = temp;
-                       ret = contacts_svc_update_contact(contact);
-                       h_warn_if(ret < CTS_SUCCESS, "contacts_svc_update_contact() Failed(%d)", ret);
-               } else {
-                       ERR("contacts_svc_get_contact() Failed(%d)", ret);
-               }
-       } else {
-               ret = contacts_svc_insert_contact(CTS_ADDRESSBOOK_INTERNAL, contact);
-               h_warn_if(ret < CTS_SUCCESS, "contacts_svc_insert_contact() Failed(%d)", ret);
-       }
-
-       contacts_svc_struct_free(contact);
-       return ret;
-}
-
-static void helper_sim_read_record_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_SDN == sim_info->phonebook_type &&
-                               TAPI_SIM_PB_INVALID_INDEX == sec_rt) {
-                       HELPER_DBG("Index = %d", sim_info->index);
-                       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;
-               }
-               ERR("SIM phonebook access Failed(%d)", sec_rt);
-               goto ERROR_RETURN;
-       }
-
-       switch (sim_info->phonebook_type) {
-       case TAPI_SIM_PB_SDN:
-               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:
-               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:
-               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:
-       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(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 {
-               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_sim_data = NULL;
-                       memset(&TAPI_imsi, 0x00, sizeof(TelSimImsiInfo_t));
-               }
-
-               helper_deregister_tapi_deinit();
-               helper_trim_memory();
-       }
-       return;
-
-ERROR_RETURN:
-       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_sim_data = NULL;
-               memset(&TAPI_imsi, 0x00, sizeof(TelSimImsiInfo_t));
-       }
-       helper_deregister_tapi_deinit();
-       helper_trim_memory();
-       return;
-}
-
-static void helper_sim_aync_response_pb_count(TapiHandle *handle, int result, void *data, void *user_data)
-{
-       HELPER_FN_CALL;
-       int ret = CTS_SUCCESS;
-       TelSimPbAccessResult_t access_rt = result;
-       TelSimPbStorageInfo_t *sim_info = data;
-
-       if (NULL == sim_info) {
-               ERR("sim_info is NULL");
-               ret = CTS_ERR_TAPI_FAILED;
-               goto ERROR_RETURN;
-       }
-
-       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) {
-       case TAPI_SIM_PB_SDN:
-               if (sim_info->UsedRecordCount) {
-                       HELPER_DBG("SDN count = %d", sim_info->UsedRecordCount);
-                       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;
-                               goto ERROR_RETURN;
-                       }
-               }
-               break;
-       case TAPI_SIM_PB_ADN:
-       case TAPI_SIM_PB_3GSIM:
-               if (sim_info->UsedRecordCount) {
-                       HELPER_DBG("ADN count = %d", sim_info->UsedRecordCount);
-                       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;
-                               goto ERROR_RETURN;
-                       }
-                       ret = contacts_svc_begin_trans();
-                       if (CTS_SUCCESS != ret) {
-                               ERR("contacts_svc_begin_trans() Failed(%d)", ret);
-                               goto ERROR_RETURN;
-                       }
-               } else {
-                       ret = CTS_ERR_NO_DATA;
-                       goto ERROR_RETURN;
-               }
-               break;
-       case TAPI_SIM_PB_FDN:
-       default:
-               ERR("Unknown storage type(%d)", sim_info->StorageFileType);
-               ret = CTS_ERR_FAIL;
-               goto ERROR_RETURN;
-       }
-
-       return;
-
-ERROR_RETURN:
-       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;
-       int sim_pb_inited;
-       TelSimPbList_t pb_list = {0};
-       TelSimCardType_t cardInfo;
-
-       h_retvm_if(NULL != helper_sim_data, CTS_ERR_ENV_INVALID,
-                       "Helper is already processing with sim");
-
-       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;
-
-       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();
-}
-
-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
-               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;
-       }
-
-       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;
-
-       h_retvm_if(NULL != helper_sim_data, CTS_ERR_ENV_INVALID,
-                       "Helper is already processing with sim");
-
-       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) {
-                       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;
-       }
-
-       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)
-{
-       HELPER_FN_CALL;
-       int ret, card_changed = 0;
-       TelSimCardStatus_t sim_status;
-
-       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_init();
-       h_retvm_if(TAPI_API_SUCCESS != ret, ret,
-                       "helper_register_tapi_init() Failed(%d)", ret);
-
-       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) {
-               ret = helper_delete_SDN_contact();
-               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) {
-               ret = helper_delete_SDN_contact();
-               if(CTS_SUCCESS != ret) {
-                       ERR("helper_delete_SDN_contact() Failed(%d)", ret);
-                       goto ERROR_RETURN;
-               }
-
-               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
deleted file mode 100755 (executable)
index c94934c..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Contacts Service Helper
- *
- * 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_HELPER_SIM_H__
-#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);
-
-
-#endif // __CTS_HELPER_SIM_H__
-
diff --git a/helper/sqlite.c b/helper/sqlite.c
deleted file mode 100755 (executable)
index 65bbefd..0000000
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Contacts Service Helper
- *
- * 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 <unistd.h>
-#include <string.h>
-#include <db-util.h>
-#include <fcntl.h>
-
-#include "cts-errors.h"
-#include "cts-schema.h"
-#include "cts-sqlite.h"
-#include "cts-utils.h"
-
-#include "internal.h"
-#include "normalize.h"
-#include "utils.h"
-
-static sqlite3 *helper_db;
-
-int helper_db_open(sqlite3 **db)
-{
-       HELPER_FN_CALL;
-       int ret;
-
-       if (!helper_db)
-       {
-               ret = db_util_open(CTS_DB_PATH, &helper_db, 0);
-               h_retvm_if(ret != SQLITE_OK, CTS_ERR_DB_NOT_OPENED,
-                               "db_util_open() Failed(%d)", ret);
-       }
-       if (db)
-               *db = helper_db;
-       return CTS_SUCCESS;
-}
-
-int helper_db_close(void)
-{
-       if (helper_db)
-       {
-               db_util_close(helper_db);
-               helper_db = NULL;
-       }
-
-       return CTS_SUCCESS;
-}
-
-int helper_begin_trans(void)
-{
-       int ret = -1;
-
-       ret = sqlite3_exec(helper_db, "BEGIN IMMEDIATE TRANSACTION",
-                       NULL, NULL, NULL);
-
-       while (SQLITE_BUSY == ret) {
-               sleep(1);
-               ret = sqlite3_exec(helper_db, "BEGIN IMMEDIATE TRANSACTION",
-                               NULL, NULL, NULL);
-       }
-
-       if (SQLITE_OK != ret)
-       {
-               ERR("sqlite3_exec() Failed(%d)", ret);
-               return CTS_ERR_DB_FAILED;
-       }
-       return CTS_SUCCESS;
-}
-
-#define CTS_COMMIT_TRY_MAX 3
-int helper_end_trans(bool success)
-{
-       int ret = -1, i=0;
-       char *errmsg = NULL;
-
-       if (success) {
-               ret = sqlite3_exec(helper_db, "COMMIT TRANSACTION",
-                               NULL, NULL, &errmsg);
-               if (SQLITE_OK != ret)
-               {
-                       ERR("sqlite3_exec(COMMIT) Failed(%d, %s)", ret, errmsg);
-                       sqlite3_free(errmsg);
-
-                       while (SQLITE_BUSY == ret && i<CTS_COMMIT_TRY_MAX) {
-                               i++;
-                               sleep(1);
-                               ret = sqlite3_exec(helper_db, "COMMIT TRANSACTION",
-                                               NULL, NULL, NULL);
-                       }
-                       if (SQLITE_OK != ret) {
-                               ERR("sqlite3_exec() Failed(%d)", ret);
-                               sqlite3_exec(helper_db, "ROLLBACK TRANSACTION",
-                                               NULL, NULL, NULL);
-                               return CTS_ERR_DB_FAILED;
-                       }
-               }
-       }
-       else {
-               sqlite3_exec(helper_db, "ROLLBACK TRANSACTION", NULL, NULL, NULL);
-       }
-
-       return CTS_SUCCESS;
-}
-
-int helper_update_default_language(int prev_lang, int new_lang)
-{
-       int ret;
-       sqlite3* db = NULL;
-       char *errmsg = NULL;
-       char query[CTS_SQL_MIN_LEN] = {0};
-
-       ret = helper_db_open(&db);
-       h_retvm_if(CTS_SUCCESS != ret, ret, "helper_db_open() Failed(%d)", ret);
-
-       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 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);
-       if (SQLITE_OK != ret)
-       {
-               ERR("sqlite3_exec(%s) Failed(%d, %s)", query, ret, errmsg);
-               sqlite3_free(errmsg);
-               helper_end_trans(false);
-               return CTS_ERR_DB_FAILED;
-       }
-
-       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);
-       if (SQLITE_OK != ret)
-       {
-               ERR("sqlite3_exec(%s) Failed(%d, %s)", query, ret, errmsg);
-               sqlite3_free(errmsg);
-               helper_end_trans(false);
-               return CTS_ERR_DB_FAILED;
-       }
-
-       ret = helper_set_default_language(new_lang);
-       if (CTS_SUCCESS != ret) {
-               helper_end_trans(false);
-               return ret;
-       }
-       ret = helper_end_trans(true);
-       helper_db_close();
-
-       return ret;
-}
-
-int helper_insert_SDN_contact(const char *name, const char *number)
-{
-       int ret;
-       sqlite3* db = NULL;
-       sqlite3_stmt* stmt = NULL;
-       char query[CTS_SQL_MIN_LEN] = {0};
-
-       ret = helper_db_open(&db);
-       h_retvm_if(CTS_SUCCESS != ret, ret, "helper_db_open() Failed(%d)", ret);
-
-       snprintf(query, sizeof(query), "INSERT INTO %s(name, number) VALUES(?,?)",
-                       CTS_TABLE_SIM_SERVICES);
-
-       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
-       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) {
-               ERR("sqlite3_step() Failed(%d)", ret);
-               sqlite3_finalize(stmt);
-               helper_db_close();
-               return CTS_ERR_DB_FAILED;
-       }
-       sqlite3_finalize(stmt);
-
-       helper_db_close();
-       return CTS_SUCCESS;
-}
-
-int helper_delete_SDN_contact(void)
-{
-       int ret;
-       sqlite3* db = NULL;
-       sqlite3_stmt* stmt = NULL;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       ret = helper_db_open(&db);
-       h_retvm_if(CTS_SUCCESS != ret, ret, "helper_db_open() Failed(%d)", ret);
-
-       snprintf(query, sizeof(query), "DELETE FROM %s", CTS_TABLE_SIM_SERVICES);
-
-       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
-       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) {
-               ERR("sqlite3_step() Failed(%d)", ret);
-               sqlite3_finalize(stmt);
-               helper_db_close();
-               return CTS_ERR_DB_FAILED;
-       }
-       sqlite3_finalize(stmt);
-
-       helper_db_close();
-       return CTS_SUCCESS;
-}
-
-static inline int helper_get_display_name(char *display, char *first,
-               char *last, char *dest, int dest_size)
-{
-       if (display) {
-               snprintf(dest, dest_size, "%s", display);
-       }
-       else {
-               if (NULL == first && NULL == last)
-                       return CTS_ERR_NO_DATA;
-               if (!last)
-                       snprintf(dest, dest_size, "%s", first);
-               else if (!first)
-                       snprintf(dest, dest_size, "%s", last);
-               else if (CTS_ORDER_NAME_FIRSTLAST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
-                       snprintf(dest, dest_size, "%s %s", first, last);
-               else
-                       snprintf(dest, dest_size, "%s, %s", last, first);
-       }
-       return CTS_SUCCESS;
-}
-
-int helper_update_collation()
-{
-       int ret;
-       sqlite3* db = NULL;
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MIN_LEN] = {0};
-       char sortkey[CTS_SQL_MIN_LEN];
-       char dest[CTS_SQL_MIN_LEN];
-
-       ret = helper_db_open(&db);
-       h_retvm_if(CTS_SUCCESS != ret, ret, "helper_db_open() Failed(%d)", ret);
-
-       ret = helper_begin_trans();
-       if(CTS_SUCCESS != ret) {
-               ERR("helper_begin_trans() Failed(%d)", ret);
-               helper_db_close();
-               return ret;
-       }
-
-       snprintf(query, sizeof(query),
-                       "SELECT contact_id, data2, data3, data5 FROM %s WHERE datatype = %d",
-                       CTS_TABLE_DATA, CTS_DATA_NAME);
-       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
-       if(SQLITE_OK != ret) {
-               ERR("sqlite3_prepare_v2(%s) Failed(%s)", query, sqlite3_errmsg(db));
-               helper_end_trans(false);
-               helper_db_close();
-               return CTS_ERR_DB_FAILED;
-       }
-
-       while (SQLITE_ROW == (ret = sqlite3_step(stmt))) {
-               cts_stmt update_stmt = NULL;
-               int contact_id = sqlite3_column_int(stmt, 0);
-               char *first = (char*)sqlite3_column_text(stmt, 1);
-               char *last = (char*)sqlite3_column_text(stmt, 2);
-               char *display = (char*)sqlite3_column_text(stmt, 3);
-
-               ret = helper_get_display_name(display, first, last, dest, sizeof(dest));
-               if (CTS_SUCCESS != ret)
-                       continue;
-
-               ret = helper_collation_str(dest, sortkey, sizeof(sortkey));
-               if (CTS_SUCCESS != ret) {
-                       ERR("helper_collation_str() Failed(%d)", ret);
-                       sqlite3_finalize(stmt);
-                       helper_end_trans(false);
-                       helper_db_close();
-                       return CTS_ERR_DB_FAILED;
-               }
-               snprintf(query, sizeof(query), "UPDATE %s SET %s=? WHERE contact_id=%d",
-                               CTS_TABLE_DATA, CTS_SCHEMA_DATA_NAME_SORTING_KEY,
-                               contact_id);
-               ret = sqlite3_prepare_v2(db, query, strlen(query), &update_stmt, NULL);
-               if(SQLITE_OK != ret) {
-                       ERR("sqlite3_prepare_v2(%s) Failed(%s)", query, sqlite3_errmsg(db));
-                       sqlite3_finalize(stmt);
-                       helper_end_trans(false);
-                       helper_db_close();
-                       return CTS_ERR_DB_FAILED;
-               }
-
-               sqlite3_bind_text(update_stmt, 1, sortkey, strlen(sortkey), SQLITE_STATIC);
-               HELPER_DBG("query : %s", query);
-               ret = sqlite3_step(update_stmt);
-               if (SQLITE_DONE != ret) {
-                       ERR("sqlite3_exec(%s) Failed(%d, %s)", query, ret, sqlite3_errmsg(db));
-                       sqlite3_finalize(stmt);
-                       sqlite3_finalize(update_stmt);
-                       helper_end_trans(false);
-                       helper_db_close();
-                       return CTS_ERR_DB_FAILED;
-               }
-               sqlite3_finalize(update_stmt);
-       }
-
-       if (SQLITE_ROW != ret && SQLITE_DONE != ret) {
-               ERR("sqlite3_step() Failed(%d)", ret);
-               sqlite3_finalize(stmt);
-               helper_end_trans(false);
-               helper_db_close();
-               return CTS_ERR_DB_FAILED;
-       }
-
-       sqlite3_finalize(stmt);
-
-       ret = helper_end_trans(true);
-       if (CTS_SUCCESS == ret) {
-               int fd = open(CTS_NOTI_CONTACT_CHANGED_DEF, O_TRUNC | O_RDWR);
-               if (0 <= fd)
-                       close(fd);
-       }
-       helper_db_close();
-
-       return ret;
-}
diff --git a/helper/utils.c b/helper/utils.c
deleted file mode 100755 (executable)
index 8cb968a..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Contacts Service Helper
- *
- * 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 <malloc.h>
-#include <contacts-svc.h>
-#include <vconf.h>
-#include <vconf-keys.h>
-
-#include "cts-utils.h"
-#include "internal.h"
-#include "sim.h"
-#include "sqlite.h"
-#include "normalize.h"
-#include "localize.h"
-#include "utils.h"
-
-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 = VCONFKEY_CONTACTS_SVC_NAME_DISPLAY_ORDER;
-
-static int default_language = -1;
-static int system_language = -1;
-
-static inline int helper_get_system_language(void)
-{
-       return system_language;
-}
-
-inline int helper_set_default_language(int lang)
-{
-       int ret = vconf_set_int(CTS_VCONF_DEFAULT_LANGUAGE, lang);
-       h_retvm_if(ret<0, CTS_ERR_VCONF_FAILED, "vconf_set_int() Failed(%d)", ret);
-
-       default_language = lang;
-       return CTS_SUCCESS;
-}
-
-static void helper_change_language_cb(keynode_t *key, void *data)
-{
-       int ret = -1;
-       const char *langset;
-
-       langset = vconf_keynode_get_str(key);
-       if (!default_language) {
-               ret = vconf_get_int(CTS_VCONF_DEFAULT_LANGUAGE, &default_language);
-               h_retm_if(ret<0, "vconf_get_int() Failed(%d)", ret);
-       }
-
-       system_language = helper_get_language_type(langset);
-       if (system_language != default_language)
-               ret = helper_update_default_language(default_language, system_language);
-}
-
-static void helper_update_collation_cb(keynode_t *key, void *data)
-{
-       helper_update_collation();
-}
-
-static void helper_tapi_sim_complete_cb(keynode_t *key, void *data)
-{
-       int ret, init_stat;
-       init_stat = vconf_keynode_get_int(key);
-       if (VCONFKEY_TELEPHONY_SIM_PB_INIT_COMPLETED == init_stat) {
-               ret = helper_sim_read_SDN(NULL);
-               h_warn_if(CTS_SUCCESS != ret, "helper_sim_read_SDN() Failed(%d)", ret);
-
-               vconf_ignore_key_changed(HELPER_VCONF_TAPI_SIM_PB_INIT, helper_tapi_sim_complete_cb);
-       }
-}
-
-void helper_final_configuration(void)
-{
-       int ret = -1;
-
-       ret = vconf_ignore_key_changed(HELPER_VCONF_SYSTEM_LANGUAGE, helper_change_language_cb);
-       h_retm_if(ret<0,"vconf_ignore_key_changed(%s) Failed(%d)",HELPER_VCONF_SYSTEM_LANGUAGE,ret);
-
-       ret = vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, helper_update_collation_cb);
-       h_retm_if(ret<0,"vconf_ignore_key_changed(%s) Failed(%d)",VCONFKEY_REGIONFORMAT,ret);
-
-       ret = vconf_ignore_key_changed(HELPER_VCONF_DISPLAY_ORDER, helper_update_collation_cb);
-       h_retm_if(ret<0,"vconf_ignore_key_changed(%s) Failed(%d)",VCONFKEY_REGIONFORMAT,ret);
-}
-
-int helper_init_configuration(void)
-{
-       int ret, sim_stat=-1;
-       const char *langset;
-
-       ret = vconf_get_int(CTS_VCONF_DEFAULT_LANGUAGE, &default_language);
-       if (ret < 0) {
-               ERR("vconf_get_int(%s) Failed(%d)",CTS_VCONF_DEFAULT_LANGUAGE ,ret);
-               default_language = 0;
-       }
-
-       ret = vconf_notify_key_changed(HELPER_VCONF_SYSTEM_LANGUAGE,
-                       helper_change_language_cb, NULL);
-       h_retvm_if(ret<0, CTS_ERR_VCONF_FAILED, "vconf_notify_key_changed(%s) Failed(%d)",
-                       HELPER_VCONF_SYSTEM_LANGUAGE, ret);
-
-       ret = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT,
-                       helper_update_collation_cb, NULL);
-       h_retvm_if(ret<0, CTS_ERR_VCONF_FAILED, "vconf_notify_key_changed(%s) Failed(%d)",
-                       VCONFKEY_REGIONFORMAT, ret);
-
-       ret = vconf_notify_key_changed(HELPER_VCONF_DISPLAY_ORDER,
-                       helper_update_collation_cb, NULL);
-       h_retvm_if(ret<0, CTS_ERR_VCONF_FAILED, "vconf_notify_key_changed(%s) Failed(%d)",
-                       HELPER_VCONF_DISPLAY_ORDER, ret);
-
-       langset = vconf_get_str(HELPER_VCONF_SYSTEM_LANGUAGE);
-       h_warn_if(NULL == langset, "vconf_get_str(%s) return NULL", HELPER_VCONF_SYSTEM_LANGUAGE);
-
-       system_language = helper_get_language_type(langset);
-       if (system_language != default_language) {
-               ERR("system lang(%s, %d), default lang(%d)", langset, system_language, default_language);
-               helper_update_default_language(default_language, system_language);
-       }
-
-       ret = vconf_get_int(HELPER_VCONF_TAPI_SIM_PB_INIT, &sim_stat);
-       if (VCONFKEY_TELEPHONY_SIM_PB_INIT_COMPLETED == sim_stat) {
-               ret = helper_sim_read_SDN(NULL);
-               h_warn_if(CTS_SUCCESS != ret, "helper_sim_read_SDN() Failed(%d)", ret);
-       } else {
-               ret = vconf_notify_key_changed(HELPER_VCONF_TAPI_SIM_PB_INIT,
-                               helper_tapi_sim_complete_cb, NULL);
-               h_retvm_if(ret<0, CTS_ERR_VCONF_FAILED, "vconf_notify_key_changed(%s) Failed(%d)",
-                               HELPER_VCONF_TAPI_SIM_PB_INIT, ret);
-       }
-
-       return CTS_SUCCESS;
-}
-
-void helper_trim_memory(void)
-{
-       malloc_trim(0);
-       sqlite3_release_memory(-1);
-}
diff --git a/helper/utils.h b/helper/utils.h
deleted file mode 100755 (executable)
index fe27385..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Contacts Service Helper
- *
- * 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_HELPER_UTILS_H__
-#define __CTS_HELPER_UTILS_H__
-
-int helper_init_configuration(void);
-void helper_final_configuration(void);
-
-int helper_get_default_language(void);
-int helper_set_default_language(int lang);
-
-void helper_trim_memory(void);
-
-#endif // __CTS_HELPER_UTILS_H__
-
diff --git a/image/SLP_ContactsService_PG_image001.PNG b/image/SLP_ContactsService_PG_image001.PNG
deleted file mode 100755 (executable)
index 36ff225..0000000
Binary files a/image/SLP_ContactsService_PG_image001.PNG and /dev/null differ
diff --git a/include/ContactsService_PG.h b/include/ContactsService_PG.h
deleted file mode 100755 (executable)
index 49a344f..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * 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.
- *
- */
-
-/**
- *
- * @ingroup   SLP_PG
- * @defgroup  CONTACTS_SVC_PG Contacts Service
-
-
-<h1 class="pg">Introduction</h1>
-       <h2 class="pg">Purpose of this document</h2>
-
-The purpose of this document is to describe how applications can use contacts-service APIs for handling contact's information. This document gives programming guidelines to application engineers and examples of using contact data.
-
-       <h2 class="pg">Scope</h2>
-
-The scope of this document is limited to Contacts-service API usage.
-
-
-<h1 class="pg">Contacts Service Architecture</h1>
-       <h2 class="pg"> Overview</h2>
-
-Contacts-service is responsible for inserting, deleting, and updating contact data in order to accommodate the needs for application's contact data.
-Users can access contacts data without knowing DB schema, SQLite, relations of data
-
-@image html SLP_ContactsService_PG_image001.PNG
-
-
-       <h2 class="pg">Sub-Components</h2>
-
-Contacts-svc-helper is a process for contacts-servcie. The process wait requests of contacts-service library and respond immediately
-
-
-
-<h1 class="pg">Contacts Service Features</h1>
-       - Similar to Sqlite3
-       - Handle information of Contact
-       - Handle information of Group
-       - Handle information of Phone log
-
-       <h2 class="pg">Similar to Sqlite3</h2>
-Contacts-service API is similar to Sqlite3.
-
-       <h2 class="pg">Handle information of Contact</h2>
-Contacts-service supports to insert/update/delete/get/search information of contact.
-The Information of contact includes name, numbers, emails, addresses, company, messenger, events, group relation information, web sites and favorite information.
-
-       <h2 class="pg">Handle information of Group</h2>
-Contacts-service supports to insert/update/delete/get information of contact.
-
-       <h2 class="pg">Handle information of Group</h2>
-Contacts-service supports to insert/update/delete/get information of Phone log.
-
-<h1 class="pg">Contacts Service API Description</h1>
-
-you can refer @ref CONTACTS_SVC
-
-
-
-<h1 class="pg">Sample Code</h1>
-
-       <h2 class="pg">Connect to Contact Database</h2>
-
-Before using contact information from contacts service API, caller module should connect to the contact database, and after finishing with the contact information, should disconnect from the contact database
-
-@code
-int contacts_svc_connect(void);
-
-int contacts_svc_disconnect(void);
-@endcode
-
-
-       <h2 class="pg">Insert information of contact</h2>
-
-@code
-
-void insert_test(void)
-{
-   CTSstruct *contact;
-   CTSvalue *name, *number1, *number2;
-   GSList *numbers=NULL;
-   contact = contacts_svc_struct_new(CTS_STRUCT_CONTACT);
-
-   name = contacts_svc_value_new(CTS_VALUE_CONTACT_BASE_INFO);
-   if(name) {
-      contacts_svc_value_set_str(name, CTS_BASE_VAL_IMG_PATH_STR, "test.vcf");
-   }
-   contacts_svc_struct_store_value(contact, CTS_CF_BASE_INFO_VALUE, name);
-   contacts_svc_value_free(name);
-
-
-   name = contacts_svc_value_new(CTS_VALUE_NAME);
-   if(name) {
-      contacts_svc_value_set_str(name, CTS_NAME_VAL_FIRST_STR, "Gil-Dong");
-      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);
-
-   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);
-   }
-   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);
-
-   contacts_svc_insert_contact(0, contact);
-   contacts_svc_struct_free(contact);
-}
-@endcode
-
-
-       <h2 class="pg">Get contact</h2>
-
-@code
-void get_contact(CTSstruct *contact)
-{
-   int index=0, ret=-1;
-   CTSvalue *value=NULL;
-   GSList *get_list, *cursor;
-
-   if(!contact) {
-      index = contacts_svc_find_contact_by(CTS_FIND_BY_NUMBER, "0123456789");
-      if(index > CTS_SUCCESS)
-        ret = contacts_svc_get_contact(index, &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);
-
-   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));
-      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_insert_favorite(contacts_svc_value_get_int(cursor->data, CTS_NUM_VAL_ID_INT));
-   }
-
-   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));
-   }
-
-
-   if(index)
-      contacts_svc_struct_free(contact);
-
-}
-@endcode
-
-
-       <h2 class="pg">Get contact list</h2>
-
-@code
-void get_contact_list(void)
-{
-   CTSiter *iter = NULL;
-   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);
-}
-@endcode
-
-
-       <h2 class="pg">Delete contact </h2>
-
-@code
-
-void delete_test(void)
-{
-   //get contact
-   int index=0, ret=-1;
-   CTSstruct *contact;
-
-   if(!contact) {
-      index = contacts_svc_find_contact_by(CTS_FIND_BY_NUMBER, "0123456789");
-      if(index > CTS_SUCCESS)
-        ret = contacts_svc_get_contact(index, &contact);
-      if(ret < 0)
-      {
-         printf("No found record\n");
-         return;
-      }
-   }
-
-   contacts_svc_delete_contact(index);
-
-   contacts_svc_struct_free(contact);
-
-}
-
-@endcode
-
-       <h2 class="pg">Search contacts by name </h2>
-
-@code
-void search_contacts_by_name(void)
-{
-   int ret;
-   CTSiter *iter = NULL;
-   ret = contacts_svc_get_list_with_str(CTS_LIST_CONTACTS_WITH_NAME,
-      "Hong", &iter);
-   if(CTS_SUCCESS != ret) return;
-
-   while(CTS_SUCCESS == contacts_svc_iter_next(iter))
-   {
-      CTSvalue *row_info = NULL;
-      const char *first, *last, *display;
-      row_info = contacts_svc_iter_get_info(iter);
-
-      printf("(%8d)", contacts_svc_value_get_int(row_info, CTS_LIST_CONTACT_ID_INT));
-
-      display = contacts_svc_value_get_str(row_info, CTS_LIST_CONTACT_DISPLAY_STR);
-      if(display)
-         printf("%s :", display);
-      else
-      {
-         first = contacts_svc_value_get_str(row_info, CTS_LIST_CONTACT_FIRST_STR);
-         last = contacts_svc_value_get_str(row_info, 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(row_info, CTS_LIST_CONTACT_IMG_PATH_STR));
-      printf("\n");
-      contacts_svc_value_free(row_info);
-   }
-   contacts_svc_iter_remove(iter);
-}
-@endcode
-
- * @}
- */
-
diff --git a/include/contacts-svc-struct.head b/include/contacts-svc-struct.head
deleted file mode 100755 (executable)
index d60a0d1..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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 __CONTACTS_SVC_STRUCT_H__
-#define __CONTACTS_SVC_STRUCT_H__
-
-#include <stdbool.h>
-#include <glib.h>
-
-/**
- * @defgroup   CONTACTS_SVC_STRUCT Structs & values
- * @ingroup    CONTACTS_SVC
- * @addtogroup CONTACTS_SVC_STRUCT
- * @{
- *
- * This interface provides methods to handle Structs (= collection of values)
- * and values of contacts service (individual properties of a contact).
- *
- * @section sec1 Properties and Policies
- * - Memory always has to be freed by its creator, unless stated otherwise.
- * \n contacts_svc_struct_store_XXX means "copy".
- * But If list has a same start with contacts struct(#CTSstruct), it is not "copy"(just appendix)
- * - Contacts structs(#CTSstruct) own data stored in them.(User cannot free each value in struct)
- * - Contacts_svc_value_XXXX is called by reference.
- * \n But Contacts_svc_value_set_str() is called by value for the data in contacts struct(#CTSstruct).
- * - All "char *" strings use UTF-8 encoding.
- *
- */
-
diff --git a/include/contacts-svc-struct.tail b/include/contacts-svc-struct.tail
deleted file mode 100755 (executable)
index 6ea9abc..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-
-/**
- * @}
- */
-
-#endif //__CONTACTS_SVC_STRUCT_H__
diff --git a/include/contacts-svc-sub.tail b/include/contacts-svc-sub.tail
deleted file mode 100755 (executable)
index d2263ff..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-
-#endif //__CONTACTS_SVC_SUB_H__
diff --git a/include/contacts-svc.head b/include/contacts-svc.head
deleted file mode 100755 (executable)
index fcb5cd5..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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 __CONTACTS_SVC_H__
-#define __CONTACTS_SVC_H__
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#include <contacts-svc-struct.h>
-#include <contacts-svc-sub.h>
-
-/**
- * This header file contains the declaration & description of Contacts Service.
- *
- * @defgroup   CONTACTS_SVC Contacts Service
- * @ingroup    PIMS_SVC
- * @brief   Contacts Service
- *
- * Contacts Service supports APIs that insert, delete, and update contact data
- * in order to accommodate the needs for application's contact data processing.
- *
- * @section Header To use Them:
- * @code
- * #include <contacts-svc.h>
- * @endcode
- *
- */
-
-/**
- * @addtogroup CONTACTS_SVC
- * @{
- */
-
diff --git a/include/contacts-svc.tail b/include/contacts-svc.tail
deleted file mode 100644 (file)
index cddb7e1..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-
-/**
- * @}
- */
-#ifdef __cplusplus
-   }
-#endif
-
-#endif //__CONTACTS_SVC_H__
similarity index 52%
rename from src/cts-im.c
rename to include/contacts.h
index 5a21bf9..67b7245 100755 (executable)
@@ -3,8 +3,6 @@
  *
  * 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
  * limitations under the License.
  *
  */
-#include "cts-internal.h"
-#include "cts-im.h"
+#ifndef __TIZEN_SOCIAL_CONTACTS_H__
+#define __TIZEN_SOCIAL_CONTACTS_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;
-}
+#include <contacts_errors.h>
+#include <contacts_service.h>
+#include <contacts_views.h>
+#include <contacts_types.h>
+#include <contacts_record.h>
+#include <contacts_list.h>
+#include <contacts_filter.h>
+#include <contacts_query.h>
+#include <contacts_db.h>
+#include <contacts_setting.h>
+#include <contacts_person.h>
+#include <contacts_group.h>
+#include <contacts_sim.h>
+#include <contacts_vcard.h>
+#include <contacts_activity.h>
+#include <contacts_phone_log.h>
+#include <contacts_db_status.h>
 
-API int contacts_svc_set_im_status(cts_im_type type,
-               const char *im_id, cts_im_status status)
-{
-       return CTS_SUCCESS;
-}
+#endif //__TIZEN_SOCIAL_CONTACTS_H__
 
diff --git a/include/contacts_activity.h b/include/contacts_activity.h
new file mode 100644 (file)
index 0000000..2c2e4e0
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CONTACTS_ACTIVITY_H__
+#define __TIZEN_SOCIAL_CONTACTS_ACTIVITY_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_activity.h
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CONTACTS_SVC_ACTIVITY_MODULE Activity
+ *
+ * @brief The contacts activity API provides the set of definitions and interfaces that enable application developers to delete activities by @a contact_id and @a account_id. \n
+ *        For more details, see @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity.
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_ACTIVITY_MODULE_HEADER Required Header
+ *  \#include <contacts.h>
+ *
+ * <BR>
+ * @{
+ */
+
+/**
+ * @brief Deletes an activity record from the contacts database by contact ID.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ *
+ * @param[in]  contact_id  The contact ID to delete
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value (#contacts_error_e)
+ *
+ * @retval  #CONTACTS_ERROR_NONE                  Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY         Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE         FS Full
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED     Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_DB                    Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                   IPC error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see  contacts_connect()
+ */
+int contacts_activity_delete_by_contact_id(int contact_id);
+
+/**
+ * @brief Deletes an activity record from the contacts database by account ID.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ *
+ * @param[in]  account_id    The account ID to delete
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see  contacts_connect()
+ */
+int contacts_activity_delete_by_account_id(int account_id);
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__TIZEN_SOCIAL_CONTACTS_ACTIVITY_H__
+
diff --git a/include/contacts_db.h b/include/contacts_db.h
new file mode 100755 (executable)
index 0000000..3be9f37
--- /dev/null
@@ -0,0 +1,1188 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CONTACTS_DB_H__
+#define __TIZEN_SOCIAL_CONTACTS_DB_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_db.h
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CONTACTS_SVC_DATABASE_MODULE Database
+ *
+ * @brief The contacts database API provides the set of definitions and interfaces that enable application developers to handle contacts database.
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_DATABASE_MODULE_HEADER Required Header
+ *  \#include <contacts.h>
+ *
+ * <BR>
+ * @{
+ */
+
+/**
+ * @brief Enumeration for contact change state.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum
+{
+       CONTACTS_CHANGE_INSERTED,       /**< Inserted */
+       CONTACTS_CHANGE_UPDATED,        /**< Updated */
+       CONTACTS_CHANGE_DELETED,        /**< Deleted */
+} contacts_changed_e;
+
+/**
+ * @brief Called when the designated view changes.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   view_uri    The view URI
+ * @param[in]   user_data   The user data passed from the callback registration function
+ *
+ * @pre                The callback must be registered using contacts_db_add_changed_cb.
+ *
+ * @see contacts_db_add_changed_cb()
+ */
+typedef void (*contacts_db_changed_cb)(const char* view_uri, void* user_data);
+
+/**
+ * @brief Inserts a record to the contacts database.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ * @privilege %http://tizen.org/privilege/callhistory.write
+ *
+ * @remarks
+ * %http://tizen.org/privilege/contact.write is needed for record which is created with @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact, \n @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile,
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial. \n\n
+ * %http://tizen.org/privilege/callhistory.write is needed for record which is created with @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log.
+ *
+ * @param[in]   record                 The record handle
+ * @param[out]  id                     The ID of inserted record
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ * @post       contacts_db_changed_cb() callback wil be called upon success.
+ *
+ * @see contacts_connect()
+ * @see contacts_db_update_record()
+ * @see contacts_db_delete_record()
+ * @see contacts_db_get_record()
+ */
+int contacts_db_insert_record( contacts_record_h record, int *id );
+
+/**
+ * @brief Gets a record from the contacts database.
+ *
+ * @details This function creates a new contact handle from the contacts database by the given @a record_id. \n
+ *          @a record will be created, which is filled with contact information.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ * @privilege %http://tizen.org/privilege/callhistory.read
+ *
+ * @remarks %http://tizen.org/privilege/contact.read is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_simple_contact, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_sdn. \n\n
+ * %http://tizen.org/privilege/callhistory.read        is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log.
+ *
+ * @remarks You must release @a record using contacts_record_destroy().
+ *
+ * @param[in]   view_uri    The view URI of a record
+ * @param[in]   record_id   The record ID to get from database
+ * @param[out]  record      The record handle associated with the record ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ * @see contacts_record_destroy()
+ */
+int contacts_db_get_record( const char* view_uri, int record_id, contacts_record_h* record );
+
+/**
+ * @brief Updates a record in the contacts database.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ * @privilege %http://tizen.org/privilege/callhistory.write
+ *
+ * @remarks %http://tizen.org/privilege/contact.write is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact, \n @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile,
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial. \n\n
+ * %http://tizen.org/privilege/callhistory.write is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log.
+ *
+ * @param[in]   record          The record handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ * @post       contacts_db_changed_cb() callback wil be called upon success.
+ *
+ * @see contacts_connect()
+ * @see contacts_db_insert_record()
+ * @see contacts_db_delete_record()
+ * @see contacts_db_get_record()
+ */
+int contacts_db_update_record( contacts_record_h record );
+
+/**
+ * @brief Deletes a record from the contacts database with related child records.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ * @privilege %http://tizen.org/privilege/callhistory.write
+ *
+ * @remarks %http://tizen.org/privilege/contact.write is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact, \n @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile,
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial. \n\n
+ * %http://tizen.org/privilege/callhistory.write is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log.
+ *
+ * @param[in]   view_uri    The view URI of a record
+ * @param[in]   record_id   The record ID to delete
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ * @post       contacts_db_changed_cb() callback wil be called upon success.
+ *
+ * @see contacts_connect()
+ * @see contacts_db_insert_record()
+ */
+int contacts_db_delete_record( const char* view_uri, int record_id );
+
+/**
+ * @brief Replaces an id-identified record with the given record.
+ *
+ * @details Now, this API supports only _contacts_contact view_uri.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ *
+ * @remarks The write-once value of @a record is not replaced.\n
+ * This API works only for @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact
+ *
+ * @param[in]   record                The new record handle to replace
+ * @param[in]   id                    The DB record ID to be replaced
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ * @post       contacts_db_changed_cb() callback wil be called upon success.
+ *
+ * @see contacts_connect()
+ * @see contacts_db_update_record()
+ * @see contacts_db_delete_record()
+ * @see contacts_db_get_record()
+ */
+int contacts_db_replace_record( contacts_record_h record, int id );
+
+/**
+ * @brief Retrieves all records and returns the results list.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ *@privilege  %http://tizen.org/privilege/callhistory.read
+ *
+ * @remarks You must release @a record_list using contacts_list_destroy(). \n
+ * %http://tizen.org/privilege/contact.read is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_simple_contact, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_sdn and all read-only views except views which are related to phone log. \n\n
+ * %http://tizen.org/privilege/callhistory.read is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log_stat. \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_phone_log view is needed both privileges.
+ *
+ * @param[in]   view_uri        The view URI to get records
+ * @param[in]   offset          The index from which to get results
+ * @param[in]   limit           The number to limit results(value 0 is used for all records)
+ * @param[out]  record_list     The record list
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre    contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ * @see contacts_list_destroy()
+ */
+int contacts_db_get_all_records( const char* view_uri, int offset, int limit, contacts_list_h* record_list );
+
+/**
+ * @brief Uses a query to find records.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ * @privilege  %http://tizen.org/privilege/callhistory.read
+ *
+ * @remarks You must release @a record_list using contacts_list_destroy(). \n
+ * %http://tizen.org/privilege/contact.read    is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_simple_contact, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_sdn and all read-only views except views which are related to phone log. \n\n
+ * %http://tizen.org/privilege/callhistory.read        is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log_stat. \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_phone_log view is needed both privileges.
+ *
+ * @param[in]   query           The query to filter the results
+ * @param[in]   offset          The index from which to get results
+ * @param[in]   limit           The number to limit results(value 0 is used for get all records)
+ * @param[out]  record_list     The record list
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre    contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ * @see contacts_list_destroy()
+ */
+int contacts_db_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* record_list );
+
+/**
+ * @brief Inserts multiple records to the contacts database.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ * @privilege %http://tizen.org/privilege/callhistory.write
+ *
+ * @remarks %http://tizen.org/privilege/contact.write is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact, \n @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile,
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial. \n\n
+ * %http://tizen.org/privilege/callhistory.write is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log.
+ *
+ * @param[in]    record_list         The record list handle
+ * @param[out]   ids                 The IDs of inserted records
+ * @param[out]   count               The number of IDs
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ * @post       contacts_db_changed_cb() callback wil be called upon success.
+ *
+ * @see contacts_connect()
+ * @see contacts_db_update_records()
+ * @see contacts_db_delete_records()
+ */
+int contacts_db_insert_records( contacts_list_h record_list, int **ids, int *count);
+
+/**
+ * @brief Updates multiple records in the contacts database.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ * @privilege %http://tizen.org/privilege/callhistory.write
+ *
+ * @remarks %http://tizen.org/privilege/contact.write is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact, \n @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile,
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial. \n\n
+ * %http://tizen.org/privilege/callhistory.write is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log.
+ *
+ * @param[in]   record_list       The record list handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ * @post       contacts_db_changed_cb() callback wil be called upon success.
+ *
+ * @see contacts_connect()
+ * @see contacts_db_insert_records()
+ * @see contacts_db_delete_records()
+ */
+int contacts_db_update_records( contacts_list_h record_list);
+
+/**
+ * @brief Deletes multiple records in the contacts database with related child records.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ * @privilege %http://tizen.org/privilege/callhistory.write
+ *
+ * @remarks %http://tizen.org/privilege/contact.write is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact, \n @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile,
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial. \n\n
+ * %http://tizen.org/privilege/callhistory.write is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log.
+ *
+ * @param[in]   view_uri            The view URI of records
+ * @param[in]   record_id_array     The record IDs to delete
+ * @param[in]   count               The size of record ID array
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ * @post       contacts_db_changed_cb() callback wil be called upon success.
+ *
+ * @see contacts_connect()
+ * @see contacts_db_insert_records()
+ * @see contacts_db_update_records()
+ */
+int contacts_db_delete_records(const char* view_uri, int record_id_array[], int count);
+
+/**
+ * @brief Replaces database records identified by given ids with a given record list.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ *
+ * @remarks The write-once value of record is not replaced.\n
+ * This API works only for @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact
+ *
+ * @param[in]   list                                 The new record list handle to replace
+ * @param[in]   record_id_array                The record IDs to replace
+ * @param[in]   count                          The size of record ID array
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ * @post       contacts_db_changed_cb() callback wil be called upon success.
+ *
+ * @see contacts_connect()
+ * @see contacts_db_update_record()
+ * @see contacts_db_delete_record()
+ * @see contacts_db_get_record()
+ */
+int contacts_db_replace_records( contacts_list_h list, int record_id_array[], int count );
+
+/**
+ * @brief Gets the current contacts database version.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ * @privilege %http://tizen.org/privilege/callhistory.read
+ *
+ * @param[out]  contacts_db_version    The contacts database version
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ * @see contacts_db_get_changes_by_version()
+ */
+int contacts_db_get_current_version( int* contacts_db_version );
+
+/**
+ * @brief Registers a callback function to be invoked when a record changes.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ * @privilege %http://tizen.org/privilege/callhistory.read
+ *
+ * @remarks %http://tizen.org/privilege/contact.read is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_simple_contact, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial. \n\n
+ * %http://tizen.org/privilege/callhistory.read        is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log.
+ * If successive change notification produced on the view_uri are identical,
+ * then they are coalesced into a single notification if the older notification has not yet been called
+ * because default main loop is doing something.
+ * But, it means that a callback function is not called to reliably count of change.
+ *
+ * @param[in]   view_uri    The view URI of records whose changes are monitored
+ * @param[in]   callback    The callback function to register
+ * @param[in]   user_data   The user data to be passed to the callback function
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_SYSTEM              System error
+ *
+ * @pre                contacts_connect() should be called to open a connection to the contacts service.
+ * @post               contacts_db_changed_cb() will be invoked when the designated view changes.
+ *
+ * @see contacts_connect()
+ * @see contacts_db_changed_cb()
+ * @see contacts_db_remove_changed_cb()
+ */
+int contacts_db_add_changed_cb( const char* view_uri, contacts_db_changed_cb callback, void* user_data );
+
+/**
+ * @brief Unregisters a callback function.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ * @privilege %http://tizen.org/privilege/callhistory.read
+ *
+ * @remarks %http://tizen.org/privilege/contact.read is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_simple_contact, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial. \n\n
+ * %http://tizen.org/privilege/callhistory.read is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log.
+ *
+ * @param[in]   view_uri    The view URI of records whose changes are monitored
+ * @param[in]   callback    The callback function to register
+ * @param[in]   user_data   The user data to be passed to the callback function
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_SYSTEM              System error
+ *
+ * @pre                contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ * @see contacts_db_changed_cb()
+ * @see contacts_db_add_changed_cb()
+ */
+int contacts_db_remove_changed_cb( const char* view_uri, contacts_db_changed_cb callback, void* user_data );
+
+/**
+ * @brief Retrieves records changes since the given database version.
+ *
+ * @details This function will find all changed records since the given @a contacts_db_version. \n
+ *          Now, support @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact_updated_info, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group_updated_info \n
+ *          @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile_updated_info and @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_grouprel_updated_info.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ *
+ * @remarks You must release @a record_list using contacts_list_destroy().
+ *
+ * @param[in]   view_uri                    The view URI to get records
+ * @param[in]   address_book_id             The address book ID to filter
+ * @param[in]   contacts_db_version         The contacts database version
+ * @param[out]  change_record_list          The record list
+ * @param[out]  current_contacts_db_version The current contacts database version
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre    contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ * @see contacts_list_destroy()
+ */
+int contacts_db_get_changes_by_version( const char* view_uri, int address_book_id, int contacts_db_version,
+                        contacts_list_h* change_record_list, int* current_contacts_db_version );
+
+/**
+ * @brief Finds records based on a given keyword.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ *
+ * @remarks You must release @a record_list using contacts_list_destroy(). \n
+ * This API works only for @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_contact, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_grouprel, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_group_assigned \n
+ * and @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_group_not_assigned.
+ *
+ * @param[in]   view_uri        The view URI to get records
+ * @param[in]   keyword         The keyword
+ * @param[in]   offset          The index from which to get results
+ * @param[in]   limit           The number to limit results(value 0 is used for get all records)
+ * @param[out]  record_list     The record list
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre    contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ * @see contacts_list_destroy()
+ */
+int contacts_db_search_records(const char* view_uri, const char *keyword, int offset, int limit, contacts_list_h* record_list);
+
+/**
+ * @brief Finds records based on given query and keyword.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ *
+ * @remarks You must release @a record_list using contacts_list_destroy(). \n
+ * This API works only for @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_contact, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_grouprel, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_group_assigned \n
+ * and @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_group_not_assigned
+ *
+ * @param[in]   query           The query handle to filter
+ * @param[in]   keyword         The keyword
+ * @param[in]   offset          The index from which to get results
+ * @param[in]   limit           The number to limit results(value 0 used for get all records)
+ * @param[out]  record_list     The record list
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre    contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ * @see contacts_list_destroy()
+ */
+int contacts_db_search_records_with_query(contacts_query_h query, const char *keyword, int offset, int limit, contacts_list_h* record_list);
+
+/**
+ * @brief Finds records based on a keyword and range.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ *
+ * @remarks You must release @a record_list using contacts_list_destroy(). \n
+ * This API works only for @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_contact, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_grouprel, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_group_assigned, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_group_not_assigned. These views can search records with range @ref CONTACTS_SEARCH_RANGE_NAME, @ref CONTACTS_SEARCH_RANGE_NUMBER, @ref CONTACTS_SEARCH_RANGE_DATA. \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_number can search records with @ref CONTACTS_SEARCH_RANGE_NAME and @ref CONTACTS_SEARCH_RANGE_NUMBER.\n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_email can search records with @ref CONTACTS_SEARCH_RANGE_NAME and @ref CONTACTS_SEARCH_RANGE_EMAIL. \n
+ *
+ * @param[in]   view_uri        The view URI
+ * @param[in]   keyword         The keyword
+ * @param[in]   offset          The index from which to get results
+ * @param[in]   limit           The number to limit results(value 0 is used for get all records)
+ * @param[in]   range           The search range
+ * @param[out]  record_list     The record list
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre    contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ * @see contacts_list_destroy()
+ */
+int contacts_db_search_records_with_range(const char* view_uri, const char *keyword, int offset, int limit, int range, contacts_list_h* record_list);
+
+/**
+ * @brief Gets the number of records in a specific view.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ * @privilege %http://tizen.org/privilege/callhistory.read
+ *
+ * @remarks %http://tizen.org/privilege/contact.read   is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_simple_contact, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_sdn and all read-only views except views which is related to phone log. \n\n
+ * %http://tizen.org/privilege/callhistory.read is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log_stat. \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_phone_log view is needed both privilege.
+ *
+ * @param[in]   view_uri        The view URI
+ * @param[out]  count           The count of records
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre    contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ */
+int contacts_db_get_count( const char* view_uri, int *count);
+
+/**
+ * @brief Gets the number of records matching a query.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ * @privilege %http://tizen.org/privilege/callhistory.read
+ *
+ * @remarks %http://tizen.org/privilege/contact.read is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_simple_contact, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_sdn and all read-only views except views which is related to phone log. \n\n
+ * %http://tizen.org/privilege/callhistory.read is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log_stat. \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_phone_log view is needed both privilege.
+ *
+ * @param[in]   query           The query handle
+ * @param[out]  count           The count of records
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre    contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ */
+int contacts_db_get_count_with_query( contacts_query_h query, int *count);
+
+/**
+ * @brief Gets the last successful changed contacts database version on the current connection.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ * @privilege %http://tizen.org/privilege/callhistory.read
+ *
+ * @param[out]  last_change_version    The database version
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ * @see contacts_db_get_current_version()
+ */
+int contacts_db_get_last_change_version(int* last_change_version);
+
+/**
+ * @internal
+ * @brief Called to get the result of an insert batch operation.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   error                  Error code for batch operation
+ * @param[in]   ids                    IDs of inserted records
+ * @param[in]   count          The number of ids
+ * @param[in]   user_data      The user data passed from the batch operation
+ *
+ * @return  @c True to continue with the next iteration of the loop or @c false to break out of the loop
+ *
+ * @pre contacts_db_insert_records_async() will invoke this callback.
+ *
+ * @see contacts_db_insert_records_async()
+ */
+typedef void (*contacts_db_insert_result_cb)( int error, int *ids, int count, void *user_data);
+
+/**
+ * @internal
+ * @brief Called to get the result of a batch operation.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   error                  Error code for batch operation
+ * @param[in]   user_data              The user data passed from the batch operation
+ *
+ * @return  @c True to continue with the next iteration of the loop or @c false to break out of the loop
+ *
+ * @pre contacts_db_update_records_async() will invoke this callback.
+ *
+ * @see contacts_db_update_records_async()
+ * @see contacts_db_delete_records_async()
+ * @see contacts_db_replace_records_async()
+ */
+typedef void (*contacts_db_result_cb)( int error, void *user_data);
+
+/**
+ * @internal
+ * @brief Inserts multiple records to the contacts database as a batch operation.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ * @privilege  %http://tizen.org/privilege/callhistory.write
+ *
+ * @remarks The purpose of async API is for the UI not to create a thread.
+ * If you have to display progress during the DB operation, you can use this API.
+ * The callback function will be called in main loop.
+ * Do not use this API in a thread.
+ * During the execution of this API, you can not call the other DB operation APIs.
+ * %http://tizen.org/privilege/contact.write is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact, \n @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile,
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial. \n\n
+ * %http://tizen.org/privilege/callhistory.write is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log.
+ *
+ * @param[in]   record_list                    The record list handle
+ * @param[in]   callback                       The callback function to inform about the batch operation result
+ * @param[in]   user_data                      The user data to be passed to the callback function
+ *
+ * @return  @c 0 on sucess,
+ *          otherwise a negative error value (#contacts_error_e)
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_DB                         Database operation failure
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @post               contacts_db_insert_result_cb() callback will be called
+ *
+ * @see contacts_connect()
+ * @see contacts_db_insert_records()
+ * @see contacts_db_update_records_async()
+ * @see contacts_db_delete_records_async()
+ */
+int contacts_db_insert_records_async( contacts_list_h record_list, contacts_db_insert_result_cb callback, void *user_data);
+
+/**
+ * @internal
+ * @brief Updates multiple records in the contacts database as a batch operation.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ * @privilege %http://tizen.org/privilege/callhistory.write
+ *
+ * @remarks %http://tizen.org/privilege/contact.write is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact, \n @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile,
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial. \n\n
+ * %http://tizen.org/privilege/callhistory.write is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log.
+ *
+ * @param[in]   record_list                    The record list handle
+ * @param[in]   callback                       The callback function to inform about the batch operation result
+ * @param[in]   user_data                      The user data to be passed to the callback function
+ *
+ * @return  0 on success, otherwise a negative error value
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_DB                         Database operation failure
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ * @post               contacts_db_result_cb() callback will be called
+ *
+ * @see contacts_connect()
+ * @see contacts_db_update_records()
+ * @see contacts_db_insert_records_async()
+ * @see contacts_db_delete_records_async()
+ */
+int contacts_db_update_records_async( contacts_list_h record_list, contacts_db_result_cb callback, void *user_data);
+
+/**
+ * @internal
+ * @brief Deletes multiple records with related child records in the contacts database as a batch operation.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ * @privilege %http://tizen.org/privilege/callhistory.write
+ *
+ * @remarks %http://tizen.org/privilege/contact.write is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact, \n @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile,
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship, \n
+ * @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo, @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial. \n\n
+ * %http://tizen.org/privilege/callhistory.write is needed for record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log.
+ *
+ * @param[in]   view_uri                       The view URI of records
+ * @param[in]   record_id_array                The record IDs to delete
+ * @param[in]   count                          The size of record ID array
+ * @param[in]   callback                       The callback function to inform about the batch operation result
+ * @param[in]   user_data                      The user data to be passed to the callback function
+ *
+ * @return  @c 0 on sucess,
+ *          otherwise a negative error value (#contacts_error_e)
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_DB                         Database operation failure
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ * @post               contacts_db_result_cb() callback will be called
+ *
+ * @see contacts_connect()
+ * @see contacts_db_delete_records()
+ * @see contacts_db_insert_records_async()
+ * @see contacts_db_update_records_async()
+ */
+int contacts_db_delete_records_async(const char* view_uri, int record_id_array[], int count, contacts_db_result_cb callback, void *user_data);
+
+/**
+ * @internal
+ * @brief Replaces database records identified by given ids with a given record list, asynchronously.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ *
+ * @remarks the write-once value of record is not replaced.\n
+ * This API works only for @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact
+ *
+ * @param[in]   list                         The new record list handle to replace
+ * @param[in]   record_id_array                The record IDs to replace
+ * @param[in]   count                          The size of record ID array
+ * @param[in]   callback                       The callback function to inform about the batch operation result
+ * @param[in]   user_data                      The user data to be passed to the callback function
+ *
+ * @return  @c 0 on sucess,
+ *          otherwise a negative error value (#contacts_error_e)
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_DB                         Database operation failure
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ * @post               contacts_db_result_cb() callback will be called
+ *
+ * @see contacts_connect()
+ * @see contacts_db_replace_record()
+ * @see contacts_db_update_record_async()
+ * @see contacts_db_delete_records_async()
+ */
+int contacts_db_replace_records_async( contacts_list_h list, int record_id_array[], int count, contacts_db_result_cb callback, void *user_data );
+
+#ifndef _CONTACTS_NATIVE
+
+/**
+ * @internal
+ * @brief Called when the designated view changes.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   view_uri       The view URI, only _contacts_person and _contacts_phone_log are now supported
+ * @param[in]   changes        It includes changes information ("type:id," string is repeated, you should parse it)
+ * @param[in]   user_data      The user data passed from the callback registration function
+ *
+ * @see contacts_db_add_changed_cb_with_info()
+ */
+
+typedef void (*contacts_db_change_cb_with_info)(const char* view_uri, char *changes, void* user_data);
+
+/**
+ * @internal
+ * @brief Registers a callback function.
+ * @details Now, support only _contacts_person and _contacts_phone_log view_uri.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ * @privilege %http://tizen.org/privilege/callhistory.read
+ *
+ * @remarks %http://tizen.org/privilege/contact.read is needed to get notification whenever record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person is changed, \n
+ * %http://tizen.org/privilege/callhistory.read is needed to get notification whenever record which is related to @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log is changed.
+ *
+ * @param[in]   view_uri       The view URI of records whose changes are monitored
+ * @param[in]   callback       The callback function to register
+ * @param[in]  user_data       The user data to be passed to the callback function
+ *
+ * @return  @c 0 on sucess,
+ *          otherwise a negative error value (#contacts_error_e)
+ *
+ * @retval     #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY              Out of memory
+ * @retval     #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_IPC                        IPC error
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @pre                contacts_connect() should be called to open a connection to the contacts service.
+ * @post               contacts_db_change_cb_with_info() callback will be called
+ *
+ * @see contacts_connect()
+ * @see contacts_db_changed_cb_with_info()
+ * @see contacts_db_remove_changed_cb_with_info()
+ */
+int contacts_db_add_changed_cb_with_info(const char* view_uri, contacts_db_change_cb_with_info callback, void* user_data);
+
+/**
+ * @internal
+ * @brief Unregisters a callback function.
+ * @details Now, support only _contacts_person and _contacts_phone_log view_uri.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   view_uri       The view URI of records whose changes are monitored
+ * @param[in]   callback       The callback function to register
+ * @param[in]  user_data       The user data to be passed to the callback function
+ *
+ * @return  @c 0 on sucess,
+ *          otherwise a negative error value (#contacts_error_e)
+ *
+ * @retval     #CONTACTS_ERROR_NONE                Successful
+ * @retval     #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @pre                contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ * @see contacts_db_changed_cb_with_info()
+ * @see contacts_db_add_changed_cb_with_info()
+ */
+int contacts_db_remove_changed_cb_with_info(const char* view_uri, contacts_db_change_cb_with_info callback, void* user_data);
+
+#endif
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__TIZEN_SOCIAL_CONTACTS_DB_H__
diff --git a/include/contacts_db_status.h b/include/contacts_db_status.h
new file mode 100755 (executable)
index 0000000..4d85797
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CONTACTS_DB_STATUS_H__
+#define __TIZEN_SOCIAL_CONTACTS_DB_STATUS_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_db_status.h
+ */
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_DATABASE_MODULE
+ * @{
+ */
+
+/**
+ * @brief Enumeration for contact DB status.
+ *
+ * @since_tizen 2.3
+ *
+ */
+
+typedef enum {
+    CONTACTS_DB_STATUS_NORMAL,             /**< Normal */
+    CONTACTS_DB_STATUS_CHANGING_COLLATION, /**< DB status is Changing collation */
+} contacts_db_status_e;
+
+/**
+ * @brief  Gets the current status of server.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]  status  The current status of server
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @pre     This function requires an open connection to the contacts service by contacts_connect().
+ *
+ * @see contacts_connect()
+ */
+
+int contacts_db_get_status(contacts_db_status_e *status);
+
+/**
+ * @brief  Called when contacts-service server status changes.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]  status       The current status of server
+ * @param[in]  user_data    The user data passed from the callback registration function
+ *
+ * @pre     This function requires an open connection to contacts service by contacts_connect().
+ *
+ * @see contacts_db_add_status_changed_cb()
+ */
+
+typedef void (*contacts_db_status_changed_cb)(contacts_db_status_e status, void* user_data);
+
+/**
+ * @brief  Registers a callback function.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]  callback     The callback function to register
+ * @param[in]  user_data    The user data to be passed to the callback function
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @pre                This function requires an open connection to the contacts service by contacts_connect().
+ *
+ * @see contacts_connect()
+ * @see contacts_db_remove_status_changed_cb()
+ */
+
+int contacts_db_add_status_changed_cb(contacts_db_status_changed_cb callback, void* user_data);
+
+/**
+ * @brief  Unregisters a callback function.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]  callback   The callback function to register
+ * @param[in]  user_data  The user data to be passed to the callback function
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @pre  This function requires an open connection to the contacts service by contacts_connect().
+ *
+ * @see contacts_connect()
+ * @see contacts_db_add_status_changed_cb()
+ */
+
+int contacts_db_remove_status_changed_cb(contacts_db_status_changed_cb callback, void* user_data);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__TIZEN_SOCIAL_CONTACTS_DB_STATUS_H__
diff --git a/include/contacts_errors.h b/include/contacts_errors.h
new file mode 100644 (file)
index 0000000..40ebfa5
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CONTACTS_ERROR_H__
+#define __TIZEN_SOCIAL_CONTACTS_ERROR_H__
+
+#include <tizen.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_errors.h
+ */
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_COMMON_MODULE
+ * @{
+ */
+
+/**
+ * @brief Enumeration for contacts errors.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum
+{
+    /* GENERAL */
+    CONTACTS_ERROR_NONE                 = TIZEN_ERROR_NONE,                      /**< Successful */
+    CONTACTS_ERROR_OUT_OF_MEMORY        = TIZEN_ERROR_OUT_OF_MEMORY,             /**< Out of memory */
+    CONTACTS_ERROR_INVALID_PARAMETER    = TIZEN_ERROR_INVALID_PARAMETER,         /**< Invalid parameter */
+    CONTACTS_ERROR_FILE_NO_SPACE        = TIZEN_ERROR_FILE_NO_SPACE_ON_DEVICE,   /**< FS Full */
+    CONTACTS_ERROR_PERMISSION_DENIED    = TIZEN_ERROR_PERMISSION_DENIED,         /**< Permission denied */
+    CONTACTS_ERROR_NOT_SUPPORTED        = TIZEN_ERROR_NOT_SUPPORTED,             /**< Not supported */
+
+    /* LOGIC & DATA */
+    CONTACTS_ERROR_NO_DATA                   = TIZEN_ERROR_NO_DATA,                   /**< Requested data does not exist */
+
+    /* DB */
+    CONTACTS_ERROR_DB_LOCKED            = TIZEN_ERROR_CONTACTS | 0x81,           /**< Database table locked or file locked */
+    CONTACTS_ERROR_DB                   = TIZEN_ERROR_CONTACTS | 0x9F,           /**< Unknown DB error */
+
+    /* IPC */
+    CONTACTS_ERROR_IPC_NOT_AVALIABLE    = TIZEN_ERROR_CONTACTS | 0xB1,           /**< IPC server is not available */
+    CONTACTS_ERROR_IPC                  = TIZEN_ERROR_CONTACTS | 0xBF,           /**< Unknown IPC error */
+
+    /* ENVIRONMENT & OTHER MODULE */
+    // Socket, inotify, vconf, icu, tapi, security/smack, account and so on
+    CONTACTS_ERROR_SYSTEM               = TIZEN_ERROR_CONTACTS | 0xEF,           /**< Internal system module error */
+
+    /* UNHANDLED EXCEPTION */
+    CONTACTS_ERROR_INTERNAL                            = TIZEN_ERROR_CONTACTS | 0xFF,            /**< Implementation Error, Temporary Use */
+} contacts_error_e;
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*  __TIZEN_SOCIAL_CONTACTS_ERROR_H__ */
+
diff --git a/include/contacts_filter.h b/include/contacts_filter.h
new file mode 100755 (executable)
index 0000000..3f9fcbf
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CONTACTS_FILTER_H__
+#define __TIZEN_SOCIAL_CONTACTS_FILTER_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_filter.h
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CONTACTS_SVC_FILTER_MODULE Filter
+ *
+ * @brief The contacts Filter API provides the set of definitions and interfaces that enable application developers to make filters to set query.
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_CONTACTS_FILTER_HEADER Required Header
+ *  \#include <contacts.h>
+ *
+ * <BR>
+ * @{
+ */
+
+/**
+ * @brief Enumeration for Contacts match string flags.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum
+{
+    CONTACTS_MATCH_EXACTLY,         /**< Full string, case-sensitive */
+    CONTACTS_MATCH_FULLSTRING,      /**< Full string, case-insensitive */
+    CONTACTS_MATCH_CONTAINS,        /**< Sub string, case-insensitive */
+    CONTACTS_MATCH_STARTSWITH,      /**< Start with, case-insensitive */
+    CONTACTS_MATCH_ENDSWITH,        /**< End with, case-insensitive */
+    CONTACTS_MATCH_EXISTS           /**< IS NOT NULL */
+} contacts_match_str_flag_e;
+
+/**
+ * @brief Enumeration for Contacts match int flags.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum
+{
+    CONTACTS_MATCH_EQUAL,                   /**< '=' */
+    CONTACTS_MATCH_GREATER_THAN,            /**< '>' */
+    CONTACTS_MATCH_GREATER_THAN_OR_EQUAL,   /**< '>=' */
+    CONTACTS_MATCH_LESS_THAN,               /**< '<' */
+    CONTACTS_MATCH_LESS_THAN_OR_EQUAL,      /**< '<=' */
+    CONTACTS_MATCH_NOT_EQUAL,               /**< '<>', this flag can yield poor performance */
+    CONTACTS_MATCH_NONE,                    /**< IS NULL */
+} contacts_match_int_flag_e;
+
+/**
+ * @brief Enumeration for Contacts filter operators.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum {
+    CONTACTS_FILTER_OPERATOR_AND,   /**< AND */
+    CONTACTS_FILTER_OPERATOR_OR     /**< OR */
+} contacts_filter_operator_e;
+
+
+/**
+ * @brief Creates a filter.
+ *
+ * @since_tizen 2.3
+ *
+ * @remarks You must release @a filter using contacts_filter_destroy().
+ *
+ * @param[in]   view_uri            The view URI of a filter
+ * @param[out]  filter              The filter handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @pre     contacts_connect() should be called to initialize
+ *
+ * @see contacts_filter_destroy()
+ */
+int contacts_filter_create( const char* view_uri, contacts_filter_h* filter );
+
+/**
+ * @brief Destroys a filter.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   filter    The filter handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see contacts_filter_create()
+ */
+int contacts_filter_destroy( contacts_filter_h filter );
+
+/**
+ * @brief Adds a condition for a string type property.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   filter          The filter handle
+ * @param[in]   property_id     The property ID to add a condition
+ * @param[in]   match           The match flag
+ * @param[in]   match_value     The match value
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @see contacts_filter_add_operator()
+ */
+int contacts_filter_add_str( contacts_filter_h filter, unsigned int property_id, contacts_match_str_flag_e match, const char* match_value );
+
+/**
+ * @brief Adds a condition for an integer type property.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   filter          The filter handle
+ * @param[in]   property_id     The property ID to add a condition
+ * @param[in]   match           The match flag
+ * @param[in]   match_value     The match value
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @see contacts_filter_add_operator()
+ */
+int contacts_filter_add_int( contacts_filter_h filter, unsigned int property_id, contacts_match_int_flag_e match, int match_value );
+
+/**
+ * @brief Adds a condition for a long int type property.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   filter          The filter handle
+ * @param[in]   property_id     The property ID to add a condition
+ * @param[in]   match           The match flag
+ * @param[in]   match_value     The match value
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @see contacts_filter_add_operator()
+ */
+int contacts_filter_add_lli( contacts_filter_h filter, unsigned int property_id, contacts_match_int_flag_e match, long long int match_value );
+
+/**
+ * @brief Adds a condition for a double type property.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   filter          The filter handle
+ * @param[in]   property_id     The property ID to add a condition
+ * @param[in]   match           The match flag
+ * @param[in]   match_value     The match value
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @see contacts_filter_add_operator()
+ */
+int contacts_filter_add_double( contacts_filter_h filter, unsigned int property_id, contacts_match_int_flag_e match, double match_value );
+
+/**
+ * @brief Adds a condition for a boolean type property.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   filter          The filter handle
+ * @param[in]   property_id     The property ID to add a condition
+ * @param[in]   match_value     The match value
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @see contacts_filter_add_operator()
+ */
+int contacts_filter_add_bool( contacts_filter_h filter, unsigned int property_id, bool match_value );
+
+/**
+ * @brief Adds an operator between conditions.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   filter          The filter handle
+ * @param[in]   operator_type   The operator type
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see contacts_filter_add_str()
+ * @see contacts_filter_add_int()
+ * @see contacts_filter_add_bool()
+ */
+int contacts_filter_add_operator( contacts_filter_h filter, contacts_filter_operator_e operator_type );
+
+/**
+ * @brief Adds a filter to a given filter.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   parent_filter       The parent filter handle
+ * @param[in]   child_filter        The child filter handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see contacts_filter_add_operator()
+ */
+int contacts_filter_add_filter(contacts_filter_h parent_filter, contacts_filter_h child_filter);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__TIZEN_SOCIAL_CONTACTS_FILTER_H__
diff --git a/include/contacts_group.h b/include/contacts_group.h
new file mode 100644 (file)
index 0000000..961b5b6
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CONTACTS_GROUP_H__
+#define __TIZEN_SOCIAL_CONTACTS_GROUP_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_group.h
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CONTACTS_SVC_GROUP_MODULE Group
+ *
+ * @brief The contacts group API provides the set of definitions and interfaces that enable application developers to add/remove contact as group member.
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_GROUP_MODULE_HEADER Required Header
+ *  \#include <contacts.h>
+ *
+ * <BR>
+ * @{
+ */
+
+/**
+ * @brief Adds a contact and a group relationship to the contacts database.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ *
+ * @param[in]   group_id       The group ID
+ * @param[in]   contact_id     The contact ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ *
+ * @pre   contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ * @see contacts_group_remove_contact()
+ */
+int contacts_group_add_contact(int group_id, int contact_id);
+
+/**
+ * @brief Removes a contact and a group relationship from the contacts database.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ *
+ * @param[in]   group_id       The group ID
+ * @param[in]   contact_id     The contact ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ *
+ * @pre   contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ * @see contacts_group_add_contact()
+ */
+int contacts_group_remove_contact(int group_id, int contact_id);
+
+/**
+ * @brief Sets a group between the previous group and the next group.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ *
+ * @param[in]   group_id                The group ID to move
+ * @param[in]   previous_group_id       The previous group ID
+ * @param[in]   next_group_id           The back group ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see  contacts_connect()
+ */
+int contacts_group_set_group_order(int group_id, int previous_group_id, int next_group_id);
+
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__TIZEN_SOCIAL_CONTACTS_GROUP_H__
old mode 100755 (executable)
new mode 100644 (file)
similarity index 73%
rename from src/cts-restriction.h
rename to include/contacts_internal.h
index 3ad8a9a..00b5fb0
@@ -3,8 +3,6 @@
  *
  * 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
  * limitations under the License.
  *
  */
-#ifndef __CTS_FACEBOOK_H__
-#define __CTS_FACEBOOK_H__
+#ifndef __TIZEN_SOCIAL_CONTACTS_INTERNAL_H__
+#define __TIZEN_SOCIAL_CONTACTS_INTERNAL_H__
 
-int cts_restriction_init(void);
-void cts_restriction_final(void);
+#include <contacts_phone_log_internal.h>
 
-int cts_restriction_get_permit(void);
+#endif //__TIZEN_SOCIAL_CONTACTS_INTERNAL_H__
 
-#endif //__CTS_FACEBOOK_H__
 
diff --git a/include/contacts_list.h b/include/contacts_list.h
new file mode 100644 (file)
index 0000000..078cbc4
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CONTACTS_LIST_H__
+#define __TIZEN_SOCIAL_CONTACTS_LIST_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_list.h
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CONTACTS_SVC_LIST_MODULE List
+ *
+ * @brief The contacts record API provides the set of definitions and interfaces that enable application developers to get/set records list data.
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_LIST_MODULE_HEADER Required Header
+ *  \#include <contacts.h>
+ *
+ * <BR>
+ * @{
+ */
+
+
+/**
+ * @brief Creates a contacts list.
+ *
+ * @since_tizen 2.3
+ *
+ * @remarks You must release @a contacts_list using contacts_list_destroy().
+ *
+ * @param[out]  contacts_list    The contacts list handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see contacts_list_destroy()
+ */
+int contacts_list_create( contacts_list_h* contacts_list );
+
+/**
+ * @brief Destroys a contacts list and releases its all resources.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   contacts_list  The contacts list handle
+ * @param[in]   delete_child   Set @c true to destroy child records automatically,
+ *                             otherwise set @c false to not destroy child records automatically
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                    Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER       Invalid parameter
+ *
+ * @see contacts_list_create()
+ */
+int contacts_list_destroy( contacts_list_h contacts_list, bool delete_child );
+
+/**
+ * @brief Retrieves the number of contact entities from a contacts list.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   contacts_list           The contacts list handle
+ * @param[out]  count                   The count of contact entity
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see contacts_list_add()
+ */
+int contacts_list_get_count( contacts_list_h contacts_list, int *count );
+
+/**
+ * @brief Adds a record to a contacts list.
+ *
+ * @since_tizen 2.3
+ *
+ * @remarks Same kind of record can be added.
+ *
+ * @param[in]   contacts_list           The contacts list handle
+ * @param[in]   record                  The record handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see contacts_list_remove()
+ */
+int contacts_list_add( contacts_list_h contacts_list, contacts_record_h record );
+
+/**
+ * @brief Removes a record from the contacts list.
+ *
+ * @details If the record is current record, then current record is changed the next record.\n
+ *          If the record is the last record, then current record will be @c NULL.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   contacts_list           The contacts list handle
+ * @param[in]   record                  The record handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ *
+ * @see contacts_list_add()
+ */
+int contacts_list_remove( contacts_list_h contacts_list, contacts_record_h record );
+
+/**
+ * @brief Retrieves a record from the contacts list.
+ *
+ * @details The default current record is the first record.
+ *
+ * @since_tizen 2.3
+ *
+ * @remarks You MUST NOT destroy the @a record.
+ *          It is destroyed automatically when the @a contacts_list is destroyed.
+ *
+ * @param[in]   contacts_list           The contacts list handle
+ * @param[out]  record                  The record handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ */
+int contacts_list_get_current_record_p( contacts_list_h contacts_list, contacts_record_h* record );
+
+/**
+ * @brief Moves a contacts list to the previous position.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]  contacts_list    The contacts list handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ *
+ * @see contacts_list_next()
+ */
+int contacts_list_prev( contacts_list_h contacts_list );
+
+/**
+ * @brief Moves a contacts list to the next position.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]  contacts_list      The contacts list handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ *
+ * @see contacts_list_prev()
+ */
+int contacts_list_next( contacts_list_h contacts_list );
+
+/**
+ * @brief Moves a contacts list to the first position.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]  contacts_list   The contacts list handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ *
+ * @see contacts_list_last()
+ */
+int contacts_list_first( contacts_list_h contacts_list );
+
+/**
+ * @brief Moves a contacts list to the last position.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]  contacts_list    The contacts list handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ *
+ * @see contacts_list_first()
+ */
+int contacts_list_last( contacts_list_h contacts_list );
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__TIZEN_SOCIAL_CONTACTS_LIST_H__
diff --git a/include/contacts_person.h b/include/contacts_person.h
new file mode 100644 (file)
index 0000000..6af6a4c
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CONTACTS_PERSON_H__
+#define __TIZEN_SOCIAL_CONTACTS_PERSON_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_person.h
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CONTACTS_SVC_PERSON_MODULE Person
+ *
+ * @brief The contacts person API provides the set of definitions and interfaces that enable application developers to link/unlink person and contact.
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_PERSON_MODULE_HEADER Required Header
+ *  \#include <contacts.h>
+ *
+ * <BR>
+ * @{
+ */
+
+/**
+ * @brief Links a person to another person.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ *
+ * @param[in]   base_person_id      The base person ID
+ * @param[in]   person_id           The person ID to link to
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see  contacts_connect()
+ */
+int contacts_person_link_person(int base_person_id, int person_id);
+
+/**
+ * @brief Unlinks a contact from a person.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ *
+ * @param[in]   person_id               The person ID
+ * @param[in]   contact_id              The contact ID to unlink
+ * @param[out]  unlinked_person_id       The person ID generated
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see  contacts_connect()
+ */
+int contacts_person_unlink_contact(int person_id, int contact_id, int* unlinked_person_id);
+
+/**
+ * @brief Resets a person's usage count.
+ *
+ * @details The person is no longer in the most frequently contacted person list.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ *
+ * @param[in]   person_id           The person ID
+ * @param[in]   type                The type to reset
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval     #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see  contacts_connect()
+ */
+int contacts_person_reset_usage(int person_id, contacts_usage_type_e type);
+
+/**
+ * @brief Sets the order of a (favorite) contact.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ *
+ * @param[in]   person_id               The person ID to move
+ * @param[in]   previous_person_id      The previous person ID
+ * @param[in]   next_person_id          The back person ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see  contacts_connect()
+ */
+int contacts_person_set_favorite_order(int person_id, int previous_person_id, int next_person_id);
+
+/**
+ * @brief Enumeration for Contacts person properties.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum {
+    CONTACTS_PERSON_PROPERTY_NAME_CONTACT,      /**< Default contacts record */
+    CONTACTS_PERSON_PROPERTY_NUMBER,            /**< Default number record */
+    CONTACTS_PERSON_PROPERTY_EMAIL,             /**< Default email record */
+    CONTACTS_PERSON_PROPERTY_IMAGE,             /**< Default image record */
+} contacts_person_property_e;
+
+/**
+ * @brief Sets a record's default property.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ *
+ * @remarks @a id can be contact_id, number_id, email_id, image_id.
+ *
+ * @param[in]   property            #contacts_person_property_e
+ * @param[in]   person_id           The person ID
+ * @param[in]   id                  The record ID
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see  contacts_connect()
+ */
+int contacts_person_set_default_property(contacts_person_property_e property, int person_id,
+        int id);
+
+/**
+ * @brief Gets a default property for a record.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ *
+ * @remarks @a id can be contact_id, number_id, email_id, image_id.
+ *
+ * @param[in]   property            #contacts_person_property_e
+ * @param[in]   person_id           The person ID
+ * @param[out]  id                  The record ID of the property to be set as default
+
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see  contacts_connect()
+ */
+int contacts_person_get_default_property(contacts_person_property_e property, int person_id,
+        int *id);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__TIZEN_SOCIAL_CONTACTS_PERSON_H__
diff --git a/include/contacts_phone_log.h b/include/contacts_phone_log.h
new file mode 100644 (file)
index 0000000..a869f11
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CONTACTS_PHONELOG_H__
+#define __TIZEN_SOCIAL_CONTACTS_PHONELOG_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_phone_log.h
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CONTACTS_SVC_PHONELOG_MODULE Phone log
+ *
+ * @brief The contacts phone log API provides the set of definitions and interfaces that enable application developers to reset phone log count.
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_PHONELOG_MODULE_HEADER Required Header
+ *  \#include <contacts.h>
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_PHONELOG_MODULE_FEATURE Related Features
+ * This API is related with the following features:\n
+ *  - http://tizen.org/feature/network.telephony\n
+ *
+ * It is recommended to design feature related codes in your application for reliability.\n
+ *
+ * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n
+ *
+ * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n
+ *
+ * More details on featuring your application can be found from <a href="../org.tizen.mobile.native.appprogramming/html/ide_sdk_tools/feature_element.htm"><b>Feature Element</b>.</a>
+ *
+ * <BR>
+ * @{
+ */
+
+
+/**
+ * @brief   Resets the phone log's count.
+ * @details The number of all types in the phone log will be @c 0.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/callhistory.write
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see  contacts_connect()
+ */
+int contacts_phone_log_reset_statistics(void);
+
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__TIZEN_SOCIAL_CONTACTS_PHONELOG_H__
diff --git a/include/contacts_phone_log_internal.h b/include/contacts_phone_log_internal.h
new file mode 100644 (file)
index 0000000..fd00c48
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CONTACTS_PHONELOG_INTERNAL_H__
+#define __TIZEN_SOCIAL_CONTACTS_PHONELOG_INTERNAL_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_phone_log_internal.h
+ */
+
+/**
+ * @brief Enumeration for Contacts phone log delete flags.
+ */
+typedef enum {
+       CONTACTS_PHONE_LOG_DELETE_BY_ADDRESS,           /**< Delete by address */
+       CONTACTS_PHONE_LOG_DELETE_BY_MESSAGE_EXTRA_DATA1,       /**< Delete by message extra_data1 */
+       CONTACTS_PHONE_LOG_DELETE_BY_EMAIL_EXTRA_DATA1, /**< Delete by email extra_data1  */
+} contacts_phone_log_delete_e;
+
+/**
+ * @brief Deletes a phone log with extra_data1.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/callhistory.write
+ *
+ * @param[in]  op                              Operation #contacts_phone_log_delete_e
+ * @param[in]  address (optional)      Address to delete (number, email,  etc)
+ * @param[in]  extra_data1 (optional)  Extra_data1 to delete
+ *
+ * @return  @c 0 on sucess,
+ *          otherwise a negative error value (#contacts_error_e)
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY            Out of memory
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_IPC                       IPC error * @par example
+ * @code
+ contacts_phone_log_delete(CONTACTS_PHONE_LOG_DELETE_BY_ADDRESS, "0123456789");
+ contacts_phone_log_delete(CONTACTS_PHONE_LOG_DELETE_BY_MESSAGE_EXTRA_DATA1,  2);
+ contacts_phone_log_delete(CONTACTS_PHONE_LOG_DELETE_BY_EMAIL_EXTRA_DATA1,  1);
+ * @endcode
+ */
+int contacts_phone_log_delete(contacts_phone_log_delete_e op, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__TIZEN_SOCIAL_CONTACTS_PHONELOG_INTERNAL_H__
diff --git a/include/contacts_query.h b/include/contacts_query.h
new file mode 100644 (file)
index 0000000..dc2d6cd
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CONTACTS_QUERY_H__
+#define __TIZEN_SOCIAL_CONTACTS_QUERY_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_query.h
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CONTACTS_SVC_QUERY_MODULE Query
+ *
+ * @brief The contacts Query API provides the set of definitions and interfaces that enable application developers to make query to get list.
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_CONTACTS_QUERY_HEADER Required Header
+ *  \#include <contacts.h>
+ *
+ * <BR>
+ * @{
+ */
+
+/**
+ * @brief Creates a query.
+ *
+ * @since_tizen 2.3
+ *
+ * @remarks You must release @a query using contacts_query_destroy().
+ *
+ * @param[in]   view_uri            The view URI of a query
+ * @param[out]  query               The filter handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @pre     contacts_connect() should be called to initialize
+ *
+ * @see contacts_query_destroy()
+ */
+int contacts_query_create( const char* view_uri, contacts_query_h* query );
+
+/**
+ * @brief Destroys a query.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   query    The query handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see contacts_query_create()
+ */
+int contacts_query_destroy( contacts_query_h query );
+
+/**
+ * @brief Adds property IDs for projection.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   query              The query handle
+ * @param[in]   property_id_array   The property ID array
+ * @param[in]   count               The number of property IDs
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ */
+int contacts_query_set_projection(contacts_query_h query, unsigned int property_id_array[], int count);
+
+/**
+ * @brief Sets the "distinct" option for projection.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   query           The query handle
+ * @param[in]   set             Set @c true to set the distinct option for projection,
+ *                              otherwise @c false to unset the distinct option
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ */
+int contacts_query_set_distinct(contacts_query_h query, bool set);
+
+/**
+ * @brief Sets a filter for query.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   query           The query handle
+ * @param[in]   filter          The filter handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see contacts_filter_create()
+ */
+int contacts_query_set_filter(contacts_query_h query, contacts_filter_h filter);
+
+/**
+ * @brief Sets a sort mode for query.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   query           The query handle
+ * @param[in]   property_id     The property ID to sort
+ * @param[in]   is_ascending    Set @c true for ascending sort mode,
+ *                              otherwise @c false for descending sort mode
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ */
+int contacts_query_set_sort(contacts_query_h query, unsigned int property_id, bool is_ascending);
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__TIZEN_SOCIAL_CONTACTS_QUERY_H__
diff --git a/include/contacts_record.h b/include/contacts_record.h
new file mode 100644 (file)
index 0000000..d56f35d
--- /dev/null
@@ -0,0 +1,475 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CONTACTS_RECORD_H__
+#define __TIZEN_SOCIAL_CONTACTS_RECORD_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_record.h
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CONTACTS_SVC_RECORD_MODULE Record
+ *
+ * @brief The contacts record API provides the set of the definitions and interfaces that enable application developers to get/set data from/to contacts record handle.
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_RECORD_MODULE_HEADER Required Header
+ *  \#include <contacts.h>
+ *
+ * <BR>
+ * @{
+ */
+
+
+/**
+ * @brief Creates a record.
+ *
+ * @since_tizen 2.3
+ *
+ * @remarks You must release @a record using contacts_record_destroy().
+ *
+ * @param[in]   view_uri    The view URI
+ * @param[out]  record      The record handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @pre     contacts_connect() should be called to initialize.
+ *
+ * @see contacts_record_destroy()
+ */
+int contacts_record_create( const char* view_uri, contacts_record_h* record );
+
+/**
+ * @brief Destroys a record and releases its all resources.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   record         The record handle
+ * @param[in]   delete_child   Set @c true to destroy child records automatically,
+ *                             otherwise set @c false to not destroy child records automatically
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                    Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER       Invalid parameter
+ *
+ * @see contacts_record_create()
+ */
+int contacts_record_destroy( contacts_record_h record, bool delete_child );
+
+/**
+ * @brief Makes a clone of a record.
+ *
+ * @since_tizen 2.3
+ *
+ * @remarks You must release @a cloned_record using contacts_record_destroy().
+ *
+ * @param[in]   record              The record handle
+ * @param[out]  cloned_record       The cloned record handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                    Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY           Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER       Invalid parameter
+ *
+ * @see contacts_record_destroy()
+ */
+int contacts_record_clone( contacts_record_h record, contacts_record_h* cloned_record );
+
+/**
+ * @brief Gets a string from the record handle.
+ *
+ * @since_tizen 2.3
+ *
+ * @remarks You must release @a value using free().
+ *
+ * @param[in]   record          The record handle
+ * @param[in]   property_id     The property ID
+ * @param[out]  value           The value to be returned
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                 Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER    Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @see contacts_record_get_str_p()
+ * @see contacts_record_set_str()
+ */
+int contacts_record_get_str( contacts_record_h record, unsigned int property_id, char** value );
+
+/**
+ * @brief Gets a string pointer from the record handle.
+ *
+ * @since_tizen 2.3
+ *
+ * @remarks You MUST NOT release @a value.
+ *
+ * @param[in]   record          The record handle
+ * @param[in]   property_id     The property ID
+ * @param[out]  value           The value to be returned
+ *
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                 Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER    Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @see contacts_record_get_str()
+ * @see contacts_record_set_str()
+ */
+int contacts_record_get_str_p( contacts_record_h record, unsigned int property_id, char** value );
+
+/**
+ * @brief Sets a string to a record.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   record          The record handle
+ * @param[in]   property_id     The property ID
+ * @param[in]   value           The value to set
+ *
+ * @return      @c 0 on success,
+ *              otherwise a negative error value
+ *
+ * @retval      #CONTACTS_ERROR_NONE                    Successful
+ * @retval      #CONTACTS_ERROR_INVALID_PARAMETER       Invalid parameter
+ * @retval      #CONTACTS_ERROR_NOT_SUPPORTED           Not supported
+ *
+ * @see contacts_record_get_str()
+ * @see contacts_record_get_str_p()
+ */
+int contacts_record_set_str( contacts_record_h record, unsigned int property_id, const char* value );
+
+/**
+ * @brief Gets a record's integer value.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   record          The record handle
+ * @param[in]   property_id     The property ID
+ * @param[out]  value           The value to be returned
+ *
+ * @return @c 0 on success,
+ *         otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @see contacts_record_set_int()
+ */
+int contacts_record_get_int( contacts_record_h record, unsigned int property_id, int* value );
+
+/**
+ * @brief Sets an integer value to a record.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   record          The record handle
+ * @param[in]   property_id     The property ID
+ * @param[in]   value           The value to set
+ *
+ * @return      @c 0 on success,
+ *              otherwise a negative error value
+ *
+ * @retval      #CONTACTS_ERROR_NONE                    Successful
+ * @retval      #CONTACTS_ERROR_INVALID_PARAMETER       Invalid parameter
+ * @retval      #CONTACTS_ERROR_NOT_SUPPORTED           Not supported
+ *
+ * @see contacts_record_get_int()
+ */
+int contacts_record_set_int( contacts_record_h record, unsigned int property_id, int value );
+
+/**
+ * @brief Gets a record's long integer value.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   record          The record handle
+ * @param[in]   property_id     The property ID
+ * @param[out]  value           The value to be returned
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @see contacts_record_set_lli()
+ */
+int contacts_record_get_lli( contacts_record_h record, unsigned int property_id, long long int *value );
+
+/**
+ * @brief Sets a long long integer value to a record.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   record          The record handle
+ * @param[in]   property_id     The property ID
+ * @param[in]   value           The value to set
+ *
+ * @return      @c 0 on success,
+ *              otherwise a negative error value
+ *
+ * @retval      #CONTACTS_ERROR_NONE                    Successful
+ * @retval      #CONTACTS_ERROR_INVALID_PARAMETER       Invalid parameter
+ * @retval      #CONTACTS_ERROR_NOT_SUPPORTED           Not supported
+ *
+ * @see contacts_record_get_lli()
+ */
+int contacts_record_set_lli( contacts_record_h record, unsigned int property_id, long long int value );
+
+/**
+ * @brief Gets a record's boolean value.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   record          The record handle
+ * @param[in]   property_id     The property ID
+ * @param[out]  value           The value to be returned
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @see contacts_record_set_bool()
+ */
+int contacts_record_get_bool( contacts_record_h record, unsigned int property_id, bool *value );
+
+/**
+ * @brief Sets a boolean value to a record.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   record          The record handle
+ * @param[in]   property_id     The property ID
+ * @param[in]   value           The value to set
+ *
+ * @return      @c 0 on success,
+ *              otherwise a negative error value
+ *
+ * @retval      #CONTACTS_ERROR_NONE                    Successful
+ * @retval      #CONTACTS_ERROR_INVALID_PARAMETER       Invalid parameter
+ * @retval      #CONTACTS_ERROR_NOT_SUPPORTED           Not supported
+ *
+ * @see contacts_record_get_bool()
+ */
+int contacts_record_set_bool( contacts_record_h record, unsigned int property_id, bool value );
+
+/**
+ * @brief Gets a record's double value.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   record          The record handle
+ * @param[in]   property_id     The property ID
+ * @param[out]  value           The value to be returned
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @see contacts_record_set_double()
+ */
+int contacts_record_get_double( contacts_record_h record, unsigned int property_id, double *value );
+
+/**
+ * @brief Sets a double value to a record.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   record          The record handle
+ * @param[in]   property_id     The property ID
+ * @param[in]   value           The value to set
+ *
+ * @return      @c 0 on success,
+ *              otherwise a negative error value
+ *
+ * @retval      #CONTACTS_ERROR_NONE                    Successful
+ * @retval      #CONTACTS_ERROR_INVALID_PARAMETER       Invalid parameter
+ * @retval      #CONTACTS_ERROR_NOT_SUPPORTED           Not supported
+ *
+ * @see contacts_record_get_double()
+ */
+int contacts_record_set_double( contacts_record_h record, unsigned int property_id, double value );
+
+/**
+ * @brief Adds a child record to the parent record.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   record          The parent record handle
+ * @param[in]   property_id     The property ID
+ * @param[in]   child_record    The child record handle to be added to parent record handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                    Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER       Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @see contacts_record_remove_child_record()
+ */
+int contacts_record_add_child_record( contacts_record_h record, unsigned int property_id, contacts_record_h child_record );
+
+/**
+ * @brief Removes a child record from the parent record.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   record          The parent record handle
+ * @param[in]   property_id     The property ID
+ * @param[in]   child_record    The child record handle to be removed from parent record handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                    Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER       Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @see contacts_record_add_child_record()
+ */
+int contacts_record_remove_child_record( contacts_record_h record, unsigned int property_id, contacts_record_h child_record );
+
+/**
+ * @brief Gets the number of child records of a parent record.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   record          The parent record handle
+ * @param[in]   property_id     The property ID
+ * @param[out]  count           The child record count
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @see contacts_record_add_child_record()
+ * @see contacts_record_remove_child_record()
+ */
+int contacts_record_get_child_record_count( contacts_record_h record, unsigned int property_id, int *count );
+
+/**
+ * @brief Gets a child record handle pointer from the parent record.
+ *
+ * @since_tizen 2.3
+ *
+ * @remarks You MUST NOT release @a child_record. It is released when the parent record is destroyed.
+ *
+ * @param[in]   record          The record handle
+ * @param[in]   property_id     The property ID
+ * @param[in]   index           The index of child record
+ * @param[out]  child_record    The child record handle pointer
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                 Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER    Invalid parameter
+ * @retval  #CONTACTS_ERROR_NO_DATA
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @see contacts_record_add_child_record()
+ * @see contacts_record_remove_child_record()
+ * @see contacts_record_get_child_record_count()
+ */
+int contacts_record_get_child_record_at_p( contacts_record_h record, unsigned int property_id, int index, contacts_record_h* child_record );
+
+/**
+ * @brief Clones a child record list of the given parent record.
+ *
+ * @since_tizen 2.3
+ *
+ * @remarks You must release @a cloned_list using contacts_list_destroy().
+ *
+ * @param[in]   record          The record handle
+ * @param[in]   property_id     The property ID
+ * @param[out]  cloned_list     The cloned list handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                 Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER    Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ *
+ * @see contacts_list_destroy()
+ */
+int contacts_record_clone_child_record_list( contacts_record_h record, unsigned int property_id, contacts_list_h* cloned_list );
+
+/**
+ * @brief Gets URI string from a record.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   record                 The record handle
+ * @param[out]  view_uri                       The URI of record
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                 Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER    Invalid parameter
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ */
+int contacts_record_get_uri_p( contacts_record_h record, const char** view_uri );
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__TIZEN_SOCIAL_CONTACTS_RECORD_H__
diff --git a/include/contacts_service.h b/include/contacts_service.h
new file mode 100755 (executable)
index 0000000..10f1597
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CONTACTS_SERVICE_H__
+#define __TIZEN_SOCIAL_CONTACTS_SERVICE_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_service.h
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CONTACTS_SVC_COMMON_MODULE Common
+ *
+ * @brief The contacts common API provides the set of definitions and interfaces to initialize and deinitialize.
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_COMMON_MODULE_HEADER Required Header
+ *  \#include <contacts.h>
+ *
+ * <BR>
+ * @{
+ */
+
+/**
+ * @brief Connects to the contacts service.
+ *
+ * @since_tizen 2.3
+ *
+ * @remarks Connection opening is necessary to access the contacts server such as fetching, inserting, or updating records.\n
+ *          The execution of contacts_connect() and contacts_disconnect() could slow down your application. So it is not recommended to call them frequently.
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC_NOT_AVALIABLE   IPC server is not available
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ * @retval  #CONTACTS_ERROR_SYSTEM              System error
+ *
+ * @see contacts_disconnect()
+ */
+int contacts_connect(void);
+
+/**
+ * @brief Disconnects from the contacts service.
+ *
+ * @since_tizen 2.3
+ *
+ * @remarks If there is no opened connection, this function returns #CONTACTS_ERROR_DB.
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                  Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval  #CONTACTS_ERROR_DB                    Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                   IPC error
+ *
+ * @see contacts_connect()
+ */
+int contacts_disconnect(void);
+
+/**
+ * @brief Connects to the contacts service with a connection on another thread.
+ *
+ * @since_tizen 2.3
+ *
+ * @remarks Opening connection is necessary to access the contact server and to perform operations such as fetching, inserting, or updating records.\n
+ *          On multiple thread environment with contacts_connect(), request can be failed in one thread, while another request is working by the connection in the other thread.
+ *          To prevent request fail, contacts_connect_on_thread() is recommended. Then new connection is set for the thread.
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC_NOT_AVALIABLE   IPC server is not available
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ * @retval  #CONTACTS_ERROR_SYSTEM              System error
+ * @retval  #CONTACTS_ERROR_INTERNAL            Internal error
+ *
+ * @see  contacts_disconnect_on_thread()
+ */
+int contacts_connect_on_thread(void);
+
+/**
+ * @brief Disconnects from the contacts service.
+ *
+ * @since_tizen 2.3
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                  Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER     Invalid parameter
+ * @retval  #CONTACTS_ERROR_DB                    Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC                   IPC error
+ *
+ * @see contacts_connect_on_thread()
+ */
+int contacts_disconnect_on_thread(void);
+
+
+/**
+ * @brief Definition for contacts_connect_with_flags(). If it is called the API with this flag, then retry to call contacts_connect() for several times.
+ *
+ * @since_tizen 2.3
+ *
+ * @see contacts_connect_with_flags()
+ */
+#define CONTACTS_CONNECT_FLAG_RETRY    0x00000001
+
+/**
+ * @brief Definition for default flag of contacts_connect_with_flags().
+ *
+ * @since_tizen 2.3
+ *
+ * @see contacts_connect_with_flags()
+ */
+#define CONTACTS_CONNECT_FLAG_NONE     0
+
+/**
+ * @brief Connects to the contacts service.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   flags  connection flag
+ *
+ * @remarks Connection opening is necessary to access the contacts server such as fetching, inserting, or updating records.\n
+ *          Before contacts-service daemon is ready, if you call contacts_connect(), it will fail.
+ *          To prevent it, if you call this API with @ref CONTACTS_CONNECT_FLAG_RETRY flags, it will retry several time.\n
+ *          To close the connection, contacts_disconnect() should be called.
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_DB                  Database operation failure
+ * @retval  #CONTACTS_ERROR_IPC_NOT_AVALIABLE   IPC server is not available
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ * @retval  #CONTACTS_ERROR_SYSTEM              System error
+ *
+ * @see  contacts_disconnect()
+ */
+int contacts_connect_with_flags(unsigned int flags);
+
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__TIZEN_SOCIAL_CONTACTS_SERVICE_H__
diff --git a/include/contacts_setting.h b/include/contacts_setting.h
new file mode 100755 (executable)
index 0000000..5a51ab7
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CONTACTS_SETTING_H__
+#define __TIZEN_SOCIAL_CONTACTS_SETTING_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_setting.h
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CONTACTS_SVC_SETTING_MODULE Setting
+ *
+ * @brief The contacts setting API provides the set of definitions and interfaces that enable application developers to set up contacts features.
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_SETTING_MODULE_HEADER Required Header
+ *  \#include <contacts.h>
+ *
+ * <BR>
+ * @{
+ */
+
+/**
+ * @brief Enumeration for name display order.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum
+{
+    CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST,   /**< First name comes at the first */
+    CONTACTS_NAME_DISPLAY_ORDER_LASTFIRST    /**< First name comes at the last */
+} contacts_name_display_order_e;
+
+/**
+ * @brief Gets the contacts name display order.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ *
+ * @param[out]  name_display_order    The name display order
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_IPC                 Unknown IPC error
+ * @retval  #CONTACTS_ERROR_SYSTEM              Internal system module error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ */
+int contacts_setting_get_name_display_order(contacts_name_display_order_e *name_display_order);
+
+/**
+ * @brief Sets the contacts name display order.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ *
+ * @param[in]  name_display_order    The name display order
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_IPC                 Unknown IPC error
+ * @retval  #CONTACTS_ERROR_SYSTEM              Internal system module error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ * @post               contacts_setting_name_display_order_changed_cb() callback will be called upon success.
+ *
+ * @see contacts_connect()
+ */
+int contacts_setting_set_name_display_order(contacts_name_display_order_e name_display_order);
+
+
+/**
+ * @brief Enumeration for name sorting order.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum
+{
+    CONTACTS_NAME_SORTING_ORDER_FIRSTLAST,   /**< Contacts are first sorted based on the first name  */
+    CONTACTS_NAME_SORTING_ORDER_LASTFIRST    /**< Contacts are first sorted based on the last name  */
+} contacts_name_sorting_order_e;
+
+
+/**
+ * @brief Gets the contacts name sorting order in which contacts are returned.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ *
+ * @param[out]  name_sorting_order    The name sorting order
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_IPC                 Unknown IPC error
+ * @retval  #CONTACTS_ERROR_SYSTEM              Internal system module error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ */
+int contacts_setting_get_name_sorting_order(contacts_name_sorting_order_e *name_sorting_order);
+
+/**
+ * @brief Sets the contacts name sorting order in which contacts are returned.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ *
+ * @param[in]  name_sorting_order    The name sorting order
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_IPC                 Unknown IPC error
+ * @retval  #CONTACTS_ERROR_SYSTEM              Internal system module error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ * @post               contacts_setting_name_sorting_order_changed_cb() callback will be called upon success.
+ *
+ * @see contacts_connect()
+ */
+int contacts_setting_set_name_sorting_order(contacts_name_sorting_order_e name_sorting_order);
+
+/**
+ * @brief Called when a designated view changes.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   name_display_order  The name display order setting value
+ * @param[in]   user_data           The user data passed from the callback registration function
+ *
+ * @pre The callback must be registered using contacts_setting_add_name_display_order_changed_cb().
+ * contacts_setting_set_name_display_order() must be called to invoke this callback.
+ *
+ * @see contacts_setting_add_name_display_order_changed_cb()
+ * @see contacts_setting_remove_name_display_order_changed_cb()
+ */
+typedef void (*contacts_setting_name_display_order_changed_cb)(contacts_name_display_order_e name_display_order, void* user_data);
+
+
+/**
+ * @brief Registers a callback function.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ *
+ * @param[in]   callback    The callback function to register
+ * @param[in]   user_data   The user data to be passed to the callback function
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE               Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #CONTACTS_ERROR_IPC                Unknown IPC error
+ * @retval  #CONTACTS_ERROR_INTERNAL           Implementation Error, Temporary Use
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED  Permission denied. This application does not have the privilege to call this method.
+ *
+ * @pre                contacts_connect() should be called to open a connection to the contacts service.
+ * @post               contacts_setting_name_display_order_changed_cb() will be called under certain conditions, after calling contacts_setting_set_name_display_order().
+ *
+ * @see contacts_connect()
+ * @see contacts_setting_remove_name_display_order_changed_cb()
+ */
+
+int contacts_setting_add_name_display_order_changed_cb(contacts_setting_name_display_order_changed_cb callback, void* user_data);
+
+/**
+ * @brief Unregisters a callback function.
+ *
+ * @since_tizen 2.3
+ * @param[in]   callback   The callback function to register
+ * @param[in]   user_data  The user data to be passed to the callback function
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_INTERNAL            Implementation Error, Temporary Use
+ *
+ * @pre contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ * @see contacts_setting_add_name_display_order_changed_cb()
+ */
+
+int contacts_setting_remove_name_display_order_changed_cb(contacts_setting_name_display_order_changed_cb callback, void* user_data);
+
+/**
+ * @brief Called when a designated view changes.
+ *
+ * @since_tizen 2.3
+ * @param[in]   name_sorting_order  The name sorting order setting value
+ * @param[in]   user_data           The user data passed from the callback registration function
+ *
+ * @pre The callback must be registered using contacts_setting_add_name_sorting_order_changed_cb().
+ * contacts_setting_set_name_sorting_order() must be called to invoke this callback.
+ *
+ * @see contacts_setting_add_name_sorting_order_changed_cb()
+ * @see contacts_setting_remove_name_sorting_order_changed_cb()
+ */
+typedef void (*contacts_setting_name_sorting_order_changed_cb)(contacts_name_sorting_order_e name_sorting_order, void* user_data);
+
+
+/**
+ * @brief Registers a callback function.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ *
+ * @param[in]   callback    The callback function to register
+ * @param[in]   user_data   The user data to be passed to the callback function
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_IPC                 Unknown IPC error
+ * @retval  #CONTACTS_ERROR_INTERNAL            Implementation Error, Temporary Use
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ *
+ * @pre                contacts_connect() should be called to open a connection to the contacts service.
+ * @post               contacts_setting_name_sorting_order_changed_cb() will be called under certain conditions, after calling contacts_setting_set_name_sorting_order().
+ *
+ * @see contacts_connect()
+ * @see contacts_setting_remove_name_sorting_order_changed_cb()
+ */
+
+int contacts_setting_add_name_sorting_order_changed_cb(contacts_setting_name_sorting_order_changed_cb callback, void* user_data);
+
+/**
+ * @brief Unregisters a callback function.
+ *
+ * @since_tizen 2.3
+ * @param[in]   callback    The callback function to register
+ * @param[in]   user_data   The user data to be passed to the callback function
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_INTERNAL            Implementation Error, Temporary Use
+ *
+ * @pre contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see contacts_connect()
+ * @see contacts_setting_add_name_sorting_order_changed_cb()
+ */
+
+int contacts_setting_remove_name_sorting_order_changed_cb(contacts_setting_name_sorting_order_changed_cb callback, void* user_data);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__TIZEN_SOCIAL_CONTACTS_SETTING_H__
diff --git a/include/contacts_sim.h b/include/contacts_sim.h
new file mode 100644 (file)
index 0000000..6e7dbe1
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CONTACTS_SIM_H__
+#define __TIZEN_SOCIAL_CONTACTS_SIM_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_sim.h
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CONTACTS_SVC_SIM_MODULE SIM
+ *
+ * @brief The contacts SIM API provides the set of definitions and interfaces that enable application developers to get/set data from/to SIM card.
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_SIM_MODULE_HEADER Required Header
+ *  \#include <contacts.h>
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_SIM_MODULE_FEATURE Related Features
+ * This API is related with the following features:\n
+ *  - http://tizen.org/feature/network.telephony\n
+ *
+ * It is recommended to design feature related codes in your application for reliability.\n
+ *
+ * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n
+ *
+ * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n
+ *
+ * More details on featuring your application can be found from <a href="../org.tizen.mobile.native.appprogramming/html/ide_sdk_tools/feature_element.htm"><b>Feature Element</b>.</a>
+ * <BR>
+ * @{
+ */
+
+/**
+ * @brief Imports all contacts from SIM to Contacts Database.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.write
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_IPC                 Unknown IPC error
+ * @retval  #CONTACTS_ERROR_SYSTEM              Internal system module error
+ * @retval  #CONTACTS_ERROR_INTERNAL            Implementation Error, Temporary Use
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see  contacts_connect()
+ */
+int contacts_sim_import_all_contacts(void);
+
+
+/**
+ * @brief Checks whether SIM initialization is completed.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ *
+ * @param[out]  completed    @c true if SIM is initialized,
+ *                           otherwise @c false if SIM is not initialized
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_NOT_SUPPORTED       Not supported
+ * @retval  #CONTACTS_ERROR_IPC                 Unknown IPC error
+ * @retval  #CONTACTS_ERROR_SYSTEM              Internal system module error
+ *
+ * @pre     contacts_connect() should be called to open a connection to the contacts service.
+ *
+ * @see  contacts_connect()
+ */
+int contacts_sim_get_initialization_status(bool *completed);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__TIZEN_SOCIAL_CONTACTS_SIM_H__
diff --git a/include/contacts_types.h b/include/contacts_types.h
new file mode 100644 (file)
index 0000000..35004c0
--- /dev/null
@@ -0,0 +1,354 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 __TIZEN_SOCIAL_CONTACTS_TYPES_H__
+#define __TIZEN_SOCIAL_CONTACTS_TYPES_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define _CONTACTS_BEGIN_VIEW() \
+    typedef struct{ \
+        const char* const _uri;
+#define _CONTACTS_BEGIN_READ_ONLY_VIEW() _CONTACTS_BEGIN_VIEW()
+#define _CONTACTS_PROPERTY_INT(property_id_name)    unsigned int property_id_name;
+#define _CONTACTS_PROPERTY_STR(property_id_name)    unsigned int property_id_name;
+#define _CONTACTS_PROPERTY_BOOL(property_id_name)   unsigned int property_id_name;
+#define _CONTACTS_PROPERTY_DOUBLE(property_id_name) unsigned int property_id_name;
+#define _CONTACTS_PROPERTY_LLI(property_id_name)    unsigned int property_id_name;
+
+#define _CONTACTS_PROPERTY_CHILD_SINGLE(property_id_name)   unsigned int property_id_name;
+#define _CONTACTS_PROPERTY_CHILD_MULTIPLE(property_id_name) unsigned int property_id_name;
+
+#define _CONTACTS_PROPERTY_FILTER_INT(property_id_name)     unsigned int property_id_name;
+#define _CONTACTS_PROPERTY_FILTER_STR(property_id_name)     unsigned int property_id_name;
+#define _CONTACTS_PROPERTY_FILTER_BOOL(property_id_name)    unsigned int property_id_name;
+#define _CONTACTS_PROPERTY_FILTER_DOUBLE(property_id_name)  unsigned int property_id_name;
+#define _CONTACTS_PROPERTY_FILTER_LLI(property_id_name)     unsigned int property_id_name;
+
+#define _CONTACTS_PROPERTY_PROJECTION_INT(property_id_name)     unsigned int property_id_name;
+#define _CONTACTS_PROPERTY_PROJECTION_STR(property_id_name)     unsigned int property_id_name;
+#define _CONTACTS_PROPERTY_PROJECTION_BOOL(property_id_name)    unsigned int property_id_name;
+#define _CONTACTS_PROPERTY_PROJECTION_DOUBLE(property_id_name)  unsigned int property_id_name;
+#define _CONTACTS_PROPERTY_PROJECTION_LLI(property_id_name)     unsigned int property_id_name;
+#define _CONTACTS_END_VIEW(name) \
+    } name##_property_ids; \
+    extern API const name##_property_ids name;
+#define _CONTACTS_END_READ_ONLY_VIEW(name) _CONTACTS_END_VIEW(name)
+
+#define _CONTACTS_HANDLE(A) typedef struct __##A{}* A;
+
+_CONTACTS_HANDLE( contacts_record_h )
+_CONTACTS_HANDLE( contacts_filter_h )
+_CONTACTS_HANDLE( contacts_list_h )
+_CONTACTS_HANDLE( contacts_query_h )
+
+/**
+ * @file contacts_types.h
+ */
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_RECORD_MODULE
+ * @{
+ */
+
+/**
+ * @brief Enumeration for contacts number type.
+ *
+ * @details The number can be made with a set of values by specifying one or more values.
+ *          \n Example : CTS_NUM_TYPE_HOME|CTS_NUM_TYPE_VOICE
+ *          \n Exceptionally, CTS_NUM_TYPE_CUSTOM is exclusive.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum {
+    CONTACTS_NUMBER_TYPE_OTHER,                 /**< Other number type */
+    CONTACTS_NUMBER_TYPE_CUSTOM = 1<<0,         /**< Custom number type */
+    CONTACTS_NUMBER_TYPE_HOME = 1<<1,           /**< A telephone number associated with a residence */
+    CONTACTS_NUMBER_TYPE_WORK = 1<<2,           /**< A telephone number associated with a place of work */
+    CONTACTS_NUMBER_TYPE_VOICE = 1<<3,          /**< A voice telephone number */
+    CONTACTS_NUMBER_TYPE_FAX = 1<<4,            /**< A facsimile telephone number */
+    CONTACTS_NUMBER_TYPE_MSG = 1<<5,            /**< The telephone number has voice messaging support */
+    CONTACTS_NUMBER_TYPE_CELL = 1<<6,           /**< A cellular telephone number */
+    CONTACTS_NUMBER_TYPE_PAGER = 1<<7,          /**< A paging device telephone number */
+    CONTACTS_NUMBER_TYPE_BBS = 1<<8,            /**< A bulletin board system telephone number */
+    CONTACTS_NUMBER_TYPE_MODEM = 1<<9,          /**< A MODEM connected telephone number */
+    CONTACTS_NUMBER_TYPE_CAR = 1<<10,           /**< A car-phone telephone number */
+    CONTACTS_NUMBER_TYPE_ISDN = 1<<11,          /**< An ISDN service telephone number */
+    CONTACTS_NUMBER_TYPE_VIDEO = 1<<12,         /**< A video conferencing telephone number */
+    CONTACTS_NUMBER_TYPE_PCS = 1<<13,           /**< A personal communication services telephone number */
+    CONTACTS_NUMBER_TYPE_COMPANY_MAIN = 1<<14,  /**< A company main number */
+    CONTACTS_NUMBER_TYPE_RADIO = 1<<15,         /**< A radio phone number */
+    CONTACTS_NUMBER_TYPE_MAIN = 1<<29,          /**< An additional type for main */
+    CONTACTS_NUMBER_TYPE_ASSISTANT = 1<<30,     /**< An additional type for assistant */
+}contacts_number_type_e;
+
+/**
+ * @brief Enumeration for Contact email type.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum {
+    CONTACTS_EMAIL_TYPE_OTHER,          /**< Other email type */
+    CONTACTS_EMAIL_TYPE_CUSTOM = 1<<0,  /**< Custom email type */
+    CONTACTS_EMAIL_TYPE_HOME = 1<<1,    /**< An email address associated with a residence */
+    CONTACTS_EMAIL_TYPE_WORK = 1<<2,    /**< An email address associated with a place of work */
+    CONTACTS_EMAIL_TYPE_MOBILE = 1<<3,  /**< A mobile email address */
+}contacts_email_type_e;
+
+/**
+ * @brief Enumeration for Contact company type.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum {
+    CONTACTS_COMPANY_TYPE_OTHER,            /**< Other company type */
+    CONTACTS_COMPANY_TYPE_CUSTOM = 1<<0,    /**< Custom company type */
+    CONTACTS_COMPANY_TYPE_WORK = 1<<1,      /**< Work company type */
+}contacts_company_type_e;
+
+/**
+ * @brief Enumeration for Contact address type.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum {
+    CONTACTS_ADDRESS_TYPE_OTHER,            /**< Other address type */
+    CONTACTS_ADDRESS_TYPE_CUSTOM = 1<<0,    /**< A delivery address for a residence */
+    CONTACTS_ADDRESS_TYPE_HOME = 1<<1,      /**< A delivery address for a residence */
+    CONTACTS_ADDRESS_TYPE_WORK = 1<<2,      /**< A delivery address for a place of work */
+    CONTACTS_ADDRESS_TYPE_DOM = 1<<3,       /**< A domestic delivery address */
+    CONTACTS_ADDRESS_TYPE_INTL = 1<<4,      /**< An international delivery address */
+    CONTACTS_ADDRESS_TYPE_POSTAL = 1<<5,    /**< A postal delivery address */
+    CONTACTS_ADDRESS_TYPE_PARCEL = 1<<6,    /**< A parcel delivery address */
+}contacts_address_type_e;
+
+/**
+ * @brief Enumeration for Contact URL type.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum {
+    CONTACTS_URL_TYPE_OTHER,    /**< Other URL type*/
+    CONTACTS_URL_TYPE_CUSTOM,   /**< Custom URL type */
+    CONTACTS_URL_TYPE_HOME,     /**< Home URL type */
+    CONTACTS_URL_TYPE_WORK,     /**< Work URL type */
+}contacts_url_type_e;
+
+/**
+ * @brief Enumeration for Contact messenger type.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum{
+    CONTACTS_MESSENGER_TYPE_OTHER,      /**< Other messenger type */
+    CONTACTS_MESSENGER_TYPE_CUSTOM,     /**< Custom messenger type */
+    CONTACTS_MESSENGER_TYPE_GOOGLE,     /**< Google messenger type */
+    CONTACTS_MESSENGER_TYPE_WLM,        /**< Windows live messenger type */
+    CONTACTS_MESSENGER_TYPE_YAHOO,      /**< Yahoo messenger type */
+    CONTACTS_MESSENGER_TYPE_FACEBOOK,   /**< Facebook messenger type */
+    CONTACTS_MESSENGER_TYPE_ICQ,        /**< ICQ type */
+    CONTACTS_MESSENGER_TYPE_AIM,        /**< AOL instance messenger type */
+    CONTACTS_MESSENGER_TYPE_QQ,         /**< QQ type */
+    CONTACTS_MESSENGER_TYPE_JABBER,     /**< Jabber type */
+    CONTACTS_MESSENGER_TYPE_SKYPE,      /**< Skype type */
+    CONTACTS_MESSENGER_TYPE_IRC,        /**< IRC type */
+}contacts_messenger_type_e;
+
+/**
+ * @brief Enumeration for Call history type.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum {
+    CONTACTS_PLOG_TYPE_NONE,                        /**< None */
+    CONTACTS_PLOG_TYPE_VOICE_INCOMMING = 1,         /**< Incoming call */
+    CONTACTS_PLOG_TYPE_VOICE_OUTGOING = 2,          /**< Outgoing call */
+    CONTACTS_PLOG_TYPE_VIDEO_INCOMMING = 3,         /**< Incoming video call */
+    CONTACTS_PLOG_TYPE_VIDEO_OUTGOING = 4,          /**< Outgoing video call */
+    CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN = 5,  /**< Not confirmed missed call */
+    CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN = 6,    /**< Confirmed missed call */
+    CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN = 7,  /**< Not confirmed missed video call */
+    CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN = 8,    /**< Confirmed missed video call */
+    CONTACTS_PLOG_TYPE_VOICE_REJECT = 9,            /**< Rejected call */
+    CONTACTS_PLOG_TYPE_VIDEO_REJECT = 10,           /**< Rejected video call */
+    CONTACTS_PLOG_TYPE_VOICE_BLOCKED = 11,          /**< Blocked call */
+    CONTACTS_PLOG_TYPE_VIDEO_BLOCKED = 12,          /**< Blocked video call */
+
+    CONTACTS_PLOG_TYPE_MMS_INCOMMING = 101,         /**< Incoming MMS */
+    CONTACTS_PLOG_TYPE_MMS_OUTGOING = 102,          /**< Outgoing MMS */
+    CONTACTS_PLOG_TYPE_SMS_INCOMMING = 103,         /**< Incoming SMS */
+    CONTACTS_PLOG_TYPE_SMS_OUTGOING = 104,          /**< Outgoing SMS */
+    CONTACTS_PLOG_TYPE_SMS_BLOCKED = 105,           /**< Blocked SMS */
+    CONTACTS_PLOG_TYPE_MMS_BLOCKED = 106,           /**< Blocked MMS */
+
+    CONTACTS_PLOG_TYPE_EMAIL_RECEIVED = 201,        /**< Received email */
+    CONTACTS_PLOG_TYPE_EMAIL_SENT = 202,            /**< Sent email */
+
+}contacts_phone_log_type_e;
+
+/**
+ * @brief Enumeration for Contact event type.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum {
+    CONTACTS_EVENT_TYPE_OTHER,          /**< Other event type */
+    CONTACTS_EVENT_TYPE_CUSTOM,         /**< Custom event type */
+    CONTACTS_EVENT_TYPE_BIRTH,          /**< Birthday event type */
+    CONTACTS_EVENT_TYPE_ANNIVERSARY     /**< Anniversary event type */
+}contacts_event_type_e;
+
+/**
+ * @brief Enumeration for Contact event calendar type.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum {
+       CONTACTS_EVENT_CALENDAR_TYPE_GREGORIAN,         /**< Gregorian calendar */
+       CONTACTS_EVENT_CALENDAR_TYPE_CHINESE            /**< Chinese calenadr */
+}contacts_event_calendar_type_e;
+
+/**
+ * @brief Enumeration of Contact image type
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum {
+    CONTACTS_IMAGE_TYPE_OTHER,       /**< Other type */
+    CONTACTS_IMAGE_TYPE_CUSTOM,      /**< Custom type */
+}contacts_image_type_e;
+
+/**
+ * @brief Enumeration for usage type.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum {
+    CONTACTS_USAGE_STAT_TYPE_NONE,          /**< None */
+    CONTACTS_USAGE_STAT_TYPE_OUTGOING_CALL, /**< Outgoing call */
+    CONTACTS_USAGE_STAT_TYPE_OUTGOING_MSG   /**< Outgoing message */
+}contacts_usage_type_e;
+
+/**
+ * @brief Enumeration for Contact display name source type.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum {
+    CONTACTS_DISPLAY_NAME_SOURCE_TYPE_INVALID,      /**< Invalid source of display name */
+    CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL,        /**< Produced display name from email record */
+    CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NUMBER,       /**< Produced display name from number record */
+    CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NICKNAME,     /**< Produced display name from nickname record */
+    CONTACTS_DISPLAY_NAME_SOURCE_TYPE_COMPANY,      /**< Produced display name from company record */
+    CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME,         /**< Produced display name from name record */
+}contacts_display_name_source_type_e;
+
+/**
+ * @brief Enumeration for Address book mode.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum {
+    CONTACTS_ADDRESS_BOOK_MODE_NONE,        /**< All module can read and write contacts of this address_book */
+    CONTACTS_ADDRESS_BOOK_MODE_READONLY,    /**< All module can only read contacts of this address_book*/
+}contacts_address_book_mode_e;
+
+/**
+ * @brief Enumeration for link mode when inserting contact.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum{
+    CONTACTS_CONTACT_LINK_MODE_NONE,            /**< Auto link immediately */
+    CONTACTS_CONTACT_LINK_MODE_IGNORE_ONCE,     /**< Do not auto link when the contact is inserted */
+}contacts_contact_link_mode_e;
+
+/**
+ * @brief Enumeration for Contact relationship type.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum {
+    CONTACTS_RELATIONSHIP_TYPE_OTHER,               /**< Other relationship type*/
+    CONTACTS_RELATIONSHIP_TYPE_ASSISTANT,           /**< Assistant type */
+    CONTACTS_RELATIONSHIP_TYPE_BROTHER,             /**< Brother type */
+    CONTACTS_RELATIONSHIP_TYPE_CHILD,               /**< Child type */
+    CONTACTS_RELATIONSHIP_TYPE_DOMESTIC_PARTNER,    /**< Domestic Partner type */
+    CONTACTS_RELATIONSHIP_TYPE_FATHER,              /**< Father type */
+    CONTACTS_RELATIONSHIP_TYPE_FRIEND,              /**< Friend type */
+    CONTACTS_RELATIONSHIP_TYPE_MANAGER,             /**< Manager type */
+    CONTACTS_RELATIONSHIP_TYPE_MOTHER,              /**< Mother type */
+    CONTACTS_RELATIONSHIP_TYPE_PARENT,              /**< Parent type */
+    CONTACTS_RELATIONSHIP_TYPE_PARTNER,             /**< Partner type */
+    CONTACTS_RELATIONSHIP_TYPE_REFERRED_BY,         /**< Referred by type */
+    CONTACTS_RELATIONSHIP_TYPE_RELATIVE,            /**< Relative type */
+    CONTACTS_RELATIONSHIP_TYPE_SISTER,              /**< Sister type */
+    CONTACTS_RELATIONSHIP_TYPE_SPOUSE,              /**< Spouse type */
+    CONTACTS_RELATIONSHIP_TYPE_CUSTOM,              /**< Custom type */
+}contacts_relationship_type_e;
+
+/**
+ * @brief Enumeration for Contact search range.
+ *
+ * @since_tizen 2.3
+ *
+ */
+typedef enum {
+    CONTACTS_SEARCH_RANGE_NAME = 0x00000001,     /**< Search record from name */
+    CONTACTS_SEARCH_RANGE_NUMBER  = 0x00000002,  /**< Search record from name and number */
+    CONTACTS_SEARCH_RANGE_DATA  = 0x00000004,    /**< Search record from name,number and data */
+    CONTACTS_SEARCH_RANGE_EMAIL  = 0x00000008,   /**< Search record from name,number,data and email. Now, support only _contacts_person_email view_uri*/
+}contacts_search_range_e;
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_SOCIAL_CONTACTS_TYPES_H__ */
+
diff --git a/include/contacts_vcard.h b/include/contacts_vcard.h
new file mode 100644 (file)
index 0000000..7665282
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CONTACTS_VCARD_H__
+#define __TIZEN_SOCIAL_CONTACTS_VCARD_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_vcard.h
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CONTACTS_SVC_VCARD_MODULE vCard
+ *
+ * @brief The contacts record API provides the set of definitions and interfaces that enable application developers to get/set data from/to vCard.
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VCARD_MODULE_HEADER Required Header
+ *  \#include <contacts.h>
+ *
+ * <BR>
+ * @{
+ */
+
+
+/**
+ * @brief Called to get a record handle of @ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   record     The record handle
+ * @param[in]   user_data  The user data passed from the foreach function
+ *
+ * @return  @c true to continue with the next iteration of the loop,
+ *          otherwise @c false to break out of the loop
+ *
+ * @pre contacts_vcard_parse_to_contact_foreach() will invoke this callback.
+ *
+ * @see contacts_vcard_parse_to_contact_foreach()
+ */
+typedef bool (*contacts_vcard_parse_cb)(contacts_record_h record, void *user_data);
+
+/**
+ * @brief Retrieves all contacts with a record handle (_contacts_contact) from a vCard file.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   vcard_file_path     The file path of vCard stream file
+ * @param[in]   callback            The callback function to invoke
+ * @param[in]   user_data           The user data to be passed to the callback function
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_NO_DATA             Requested data does not exist
+ * @retval  #CONTACTS_ERROR_SYSTEM              System error
+ *
+ * @pre     contacts_connect() should be called to initialize.
+ * @post    This function invokes contacts_vcard_parse_cb().
+ *
+ * @see  contacts_vcard_parse_cb()
+ */
+int contacts_vcard_parse_to_contact_foreach(const char *vcard_file_path, contacts_vcard_parse_cb callback, void *user_data);
+
+/**
+ * @brief Retrieves all contacts with a contacts list from a vCard stream.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   vcard_stream            The vCard stream
+ * @param[out]  contacts_list           The contacts list handle
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @pre     contacts_connect() should be called to initialize.
+ *
+ */
+int contacts_vcard_parse_to_contacts(const char *vcard_stream, contacts_list_h *contacts_list);
+
+/**
+ * @brief Retrieves the vCard stream from a contact.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   contact                 The contact record handle
+ * @param[out]  vcard_stream            The vCard stream
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ */
+int contacts_vcard_make_from_contact(contacts_record_h contact, char **vcard_stream);
+
+/**
+ * @brief Retrieves the vCard stream from a contact.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   my_profile              The my_profile record handle
+ * @param[out]  vcard_stream            The vCard stream
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ */
+int contacts_vcard_make_from_my_profile(contacts_record_h my_profile, char **vcard_stream);
+
+
+/**
+ * @brief Retrieves the vCard stream from a person.
+ *
+ * @since_tizen 2.3
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/contact.read
+ *
+ * @param[in]   person                  The person record handle
+ * @param[out]  vcard_stream            The vCard stream
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_FILE_NO_SPACE       FS Full
+ * @retval  #CONTACTS_ERROR_PERMISSION_DENIED   Permission denied. This application does not have the privilege to call this method.
+ * @retval  #CONTACTS_ERROR_DB                  DB error
+ * @retval  #CONTACTS_ERROR_IPC                 IPC error
+ *
+ * @pre     contacts_connect() should be called to initialize.
+ *
+ */
+int contacts_vcard_make_from_person(contacts_record_h person, char **vcard_stream);
+
+/**
+ * @brief Retrieves the count of contact entities from a vCard file.
+ *
+ * @since_tizen 2.3
+ *
+ * @param[in]   vcard_file_path             The person record handle
+ * @param[out]  count                       The count of contact entity
+ *
+ * @return  @c 0 on success,
+ *          otherwise a negative error value
+ *
+ * @retval  #CONTACTS_ERROR_NONE                Successful
+ * @retval  #CONTACTS_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CONTACTS_ERROR_SYSTEM              System error
+ */
+int contacts_vcard_get_entity_count(const char *vcard_file_path, int *count);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__TIZEN_SOCIAL_CONTACTS_VCARD_H__
diff --git a/include/contacts_views.h b/include/contacts_views.h
new file mode 100755 (executable)
index 0000000..a66babc
--- /dev/null
@@ -0,0 +1,1701 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 __TIZEN_SOCIAL_CONTACTS_VIEWS_H__
+#define __TIZEN_SOCIAL_CONTACTS_VIEWS_H__
+
+#include "contacts_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file contacts_views.h
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ *
+ * @brief This page provides information about views with properties.
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_HEADER Required Header
+ *  \#include <contacts.h>
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_OVERVIEW Overview
+ * In this category, application developers can find tables with view properties.
+ *
+ * A view is a structure which describes properties of a record.
+ *
+ * A record can have basic properties of five types: integer, string, boolean, long integer, double. Each property
+ * of basic type has functions to operate on it:
+ *
+ * <table>
+ * <tr>
+ *    <th>Property type</th>
+ *    <th>Setter</th>
+ *    <th>Getter</th>
+ * </tr>
+ * <tr>
+ *    <td> string </td>
+ *    <td> @ref contacts_record_set_str </td>
+ *    <td> @ref contacts_record_get_str </td>
+ * </tr>
+ * <tr>
+ *    <td> integer </td>
+ *    <td> @ref contacts_record_set_int </td>
+ *    <td> @ref contacts_record_get_int </td>
+ * </tr>
+ * <tr>
+ *    <td> boolean </td>
+ *    <td> @ref contacts_record_set_bool </td>
+ *    <td> @ref contacts_record_get_bool </td>
+ * </tr>
+ * <tr>
+ *    <td> long integer </td>
+ *    <td> @ref contacts_record_set_lli </td>
+ *    <td> @ref contacts_record_get_lli </td>
+ * </tr>
+ * <tr>
+ *    <td> double </td>
+ *    <td> @ref contacts_record_set_double </td>
+ *    <td> @ref contacts_record_get_double </td>
+ * </tr>
+ * </table>
+ *
+ * For long integer functions, "lli" stands for long long int, usually used to hold UTC time.
+ *
+ * Record types which have *_id as their properties, hold identifiers of other records - for example, name, number and email
+ * views hold ID of their corresponding contacts in contact_id property
+ * (as children of the corresponding contacts record).
+ *
+ * Properties of type 'record' are other records. For example, the _contacts_contact view
+ * has a 'name' property of type 'record'. This means that records of type name (_contacts_name view)
+ * can be children of the contact record. If a name record holds the identifier
+ * of a contact record in its 'contact_id' property, it is the child record of the corresponding
+ * contact record.
+ *
+ * Records can have many children of a given type.
+ *
+ * For a more detailed explanation and examples, see the main section of Contacts API.
+ *
+ * <BR>
+ */
+
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address_book _contacts_address_book view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts addressbook view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the addressbook </td></tr>
+ * <tr><td>integer</td><td> account_id </td><td>read, write once</td><td> Account ID that the addressbook belongs to </td></tr>
+ * <tr><td>string</td><td> name </td><td>read, write</td><td> It cannot be @c NULL. Duplicate names are not allowed. </td></tr>
+ * <tr><td>integer</td><td> mode </td><td>read, write</td><td> Addressbook mode, refer to the @ref contacts_address_book_mode_e </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                    // read only
+    _CONTACTS_PROPERTY_INT( account_id )            // read, write once
+    _CONTACTS_PROPERTY_STR( name )                  // read, write
+    _CONTACTS_PROPERTY_INT( mode )                  // read, write
+_CONTACTS_END_VIEW( _contacts_address_book )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group _contacts_group view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts group view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the group </td></tr>
+ * <tr><td>integer</td><td> address_book_id </td><td>read, write once</td><td> Addressbook ID that the group belongs to </td></tr>
+ * <tr><td>string</td><td> name </td><td>read, write</td><td> Group name </td></tr>
+ * <tr><td>string</td><td> ringtone_path </td><td>read, write</td><td> Ringtone path of the group </td></tr>
+ * <tr><td>string</td><td> image_path </td><td>read, write</td><td> Image path of the group </td></tr>
+ * <tr><td>string</td><td> vibration </td><td>read, write</td><td> Vibration path of the group </td></tr>
+ * <tr><td>string</td><td> extra_data </td><td>read, write</td><td> Extra data for default group name </td></tr>
+ * <tr><td>boolean</td><td> is_read_only </td><td>read, write once</td><td> The group is read only or not </td></tr>
+ * <tr><td>string</td><td> message_alert </td><td>read, write</td><td> Message alert path of the group </td></tr>
+ * </table>
+ *
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                    // read only
+    _CONTACTS_PROPERTY_INT( address_book_id )       // read, write once
+    _CONTACTS_PROPERTY_STR( name )                  // read, write
+    _CONTACTS_PROPERTY_STR( ringtone_path )         // read, write
+    _CONTACTS_PROPERTY_STR( image_path )            // read, write
+    _CONTACTS_PROPERTY_STR( vibration )             // read, write
+    _CONTACTS_PROPERTY_STR( extra_data )            // read, write, string
+    _CONTACTS_PROPERTY_BOOL( is_read_only )         // read, write once
+    _CONTACTS_PROPERTY_STR( message_alert )         // read, write
+_CONTACTS_END_VIEW( _contacts_group )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person _contacts_person view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts person view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the person </td></tr>
+ * <tr><td>string</td><td> display_name </td><td>read only</td><td> Display name of the person </td></tr>
+ * <tr><td>string</td><td> display_name_index </td><td>read only</td><td> The first character of first string for grouping. This is normalized using icu (projection) </td></tr>
+ * <tr><td>integer</td><td> display_contact_id </td><td>read only</td><td> Display contact ID that the person belongs to </td></tr>
+ * <tr><td>string</td><td> ringtone_path </td><td>read, write</td><td> Ringtone path of the person </td></tr>
+ * <tr><td>string</td><td> image_thumbnail_path </td><td>read only</td><td> Image thumbnail path of the person </td></tr>
+ * <tr><td>string</td><td> vibration </td><td>read, write</td><td> Vibration path of the person </td></tr>
+ * <tr><td>string</td><td> message_alert </td><td>read, write</td><td> Message alert path of the person </td></tr>
+ * <tr><td>string</td><td> status </td><td>read only</td><td> Status of social account </td></tr>
+ * <tr><td>boolean</td><td> is_favorite </td><td>read, write</td><td> The person is favorite or not </td></tr>
+ * <tr><td>double</td><td> favorite_priority </td><td> sort only </td><td> The priority of favorite contacts. You cannot get/set the value but you can use it as sorting key, see the @ref contacts_query_set_sort </td></tr>
+ * <tr><td>integer</td><td> link_count </td><td>read only</td><td> Link count of contact records (projection) </td></tr>
+ * <tr><td>string</td><td> addressbook_ids </td><td>read only</td><td> Addressbook IDs that the person belongs to (projection) </td></tr>
+ * <tr><td>boolean</td><td> has_phonenumber </td><td>read only</td><td> The person has phone number or not </td></tr>
+ * <tr><td>boolean</td><td> has_email </td><td>read only</td><td> The person has email or not </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                    // read only
+    _CONTACTS_PROPERTY_STR( display_name )          // read only
+    _CONTACTS_PROPERTY_STR( display_name_index)     // read only
+    _CONTACTS_PROPERTY_INT( display_contact_id )    // read, write
+    _CONTACTS_PROPERTY_STR( ringtone_path )         // read, write
+    _CONTACTS_PROPERTY_STR( image_thumbnail_path )  // read only
+    _CONTACTS_PROPERTY_STR( vibration )             // read, write
+    _CONTACTS_PROPERTY_STR( status )                // read only
+    _CONTACTS_PROPERTY_BOOL( is_favorite )          // read, write
+    _CONTACTS_PROPERTY_DOUBLE( favorite_priority )  // sort only
+    _CONTACTS_PROPERTY_INT( link_count )            // read only
+    _CONTACTS_PROPERTY_STR( addressbook_ids )       // read only
+    _CONTACTS_PROPERTY_BOOL( has_phonenumber )      // read only
+    _CONTACTS_PROPERTY_BOOL( has_email )            // read only
+    _CONTACTS_PROPERTY_STR( message_alert )         // read, write
+_CONTACTS_END_VIEW( _contacts_person )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_simple_contact _contacts_simple_contact view
+ * You can only get simple contact using this view.
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this simple contact view </td></tr>
+ * <tr><td>integer</td><td>id</td><td> DB record ID of the contact </td></tr>
+ * <tr><td>string</td><td>display_name</td><td> Display name of the contact </td></tr>
+ * <tr><td>integer</td><td>display_source_id</td><td> The source type of display name, refer to the @ref contacts_display_name_source_type_e </td></tr>
+ * <tr><td>integer</td><td>address_book_id</td><td> Addressbook that the contact belongs to </td></tr>
+ * <tr><td>string</td><td>ringtone_path</td><td> Ringtone path of the contact </td></tr>
+ * <tr><td>string</td><td>image_thumbnail_path</td><td> Image thumbnail path of the contact </td></tr>
+ * <tr><td>boolean</td><td>is_favorite</td><td> The contact is favorite or not </td></tr>
+ * <tr><td>boolean</td><td>has_phonenumber</td><td> The contact has phone number or not </td></tr>
+ * <tr><td>boolean</td><td>has_email</td><td> The contact has email or not </td></tr>
+ * <tr><td>integer</td><td>person_id</td><td> Person ID that the contact belongs to </td></tr>
+ * <tr><td>string</td><td>uid</td><td> Unique identifier </td></tr>
+ * <tr><td>string</td><td>vibration</td><td> Vibration path of the contact </td></tr>
+ * <tr><td>string</td><td>message_alert</td><td> Message alert path of the contact </td></tr>
+ * <tr><td>integer</td><td>changed_time</td><td> Last changed contact time </td></tr>
+ * </table>
+ *
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                    // read only
+    _CONTACTS_PROPERTY_STR( display_name )          // read only
+    _CONTACTS_PROPERTY_INT( display_source_type)    // read only
+    _CONTACTS_PROPERTY_INT( address_book_id )       // read only
+    _CONTACTS_PROPERTY_STR( ringtone_path )         // read only
+    _CONTACTS_PROPERTY_STR( image_thumbnail_path )  // read only
+    _CONTACTS_PROPERTY_BOOL( is_favorite )          // read only
+    _CONTACTS_PROPERTY_BOOL( has_phonenumber )      // read only
+    _CONTACTS_PROPERTY_BOOL( has_email )            // read only
+    _CONTACTS_PROPERTY_INT( person_id )             // read only
+    _CONTACTS_PROPERTY_STR( uid )                   // read only
+    _CONTACTS_PROPERTY_STR( vibration )             // read only
+    _CONTACTS_PROPERTY_INT( changed_time )          // read only
+    _CONTACTS_PROPERTY_STR( message_alert )         // read only
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_simple_contact )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact _contacts_contact view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contact view  </td></tr>
+ * <tr><td>integer</td><td>id</td><td>read only</td><td> DB record ID of the contact </td></tr>
+ * <tr><td>string</td><td>display_name</td><td>read only</td><td> Display name of the contact </td></tr>
+ * <tr><td>integer</td><td>display_source_id</td><td>read only</td><td> The source type of display name, refer to the @ref contacts_display_name_source_type_e </td></tr>
+ * <tr><td>integer</td><td>address_book_id</td><td>read, write once</td><td> Addressbook ID that the contact belongs to </td></tr>
+ * <tr><td>string</td><td>ringtone_path</td><td>read, write</td><td> Ringtone path of the contact </td></tr>
+ * <tr><td>string</td><td>image_thumbnail_path</td><td>read only</td><td> Image thumbnail path of the contact </td></tr>
+ * <tr><td>boolean</td><td>is_favorite</td><td>read, write</td><td> The contact is favorite or not </td></tr>
+ * <tr><td>boolean</td><td>has_phonenumber</td><td>read only</td><td> The contact has phone number or not </td></tr>
+ * <tr><td>boolean</td><td>has_email</td><td>read only</td><td> The contact has email or not </td></tr>
+ * <tr><td>integer</td><td>person_id</td><td>read, write once</td><td> Person ID that the contact belongs to. If set when inserting, a contact will be linked to person </td></tr>
+ * <tr><td>string</td><td>uid</td><td>read, write</td><td> Unique identifier </td></tr>
+ * <tr><td>string</td><td>vibration</td><td>read, write</td><td> Vibration path of the contact </td></tr>
+ * <tr><td>string</td><td>message_alert</td><td>read, write</td><td> Message alert path of the contact </td></tr>
+ * <tr><td>integer</td><td>changed_time</td><td>read only</td><td> Last changed contact time </td></tr>
+ * <tr><td>integer</td><td>link_mode</td><td>read, write once</td><td> The link mode, refer to the @ref contacts_contact_link_mode_e. If the person_id was set, this value will be ignored </td></tr>
+ * <tr><td>record</td><td>name</td><td>read, write</td><td> _contacts_name child record (single) </td></tr>
+ * <tr><td>record</td><td>company</td><td>read, write</td><td> _contacts_company child record (multiple) </td></tr>
+ * <tr><td>record</td><td>note</td><td>read, write</td><td> _contacts_note child record (multiple) </td></tr>
+ * <tr><td>record</td><td>number</td><td>read, write</td><td> _contacts_number child record (multiple) </td></tr>
+ * <tr><td>record</td><td>email</td><td>read, write</td><td> _contacts_email child record (multiple) </td></tr>
+ * <tr><td>record</td><td>event</td><td>read, write</td><td> _contacts_event child record (multiple) </td></tr>
+ * <tr><td>record</td><td>messenger</td><td>read, write</td><td> _contacts_messenger child record (multiple) </td></tr>
+ * <tr><td>record</td><td>address</td><td>read, write</td><td> _contacts_address child record (multiple) </td></tr>
+ * <tr><td>record</td><td>url</td><td>read, write</td><td> _contacts_url child record (multiple) </td></tr>
+ * <tr><td>record</td><td>nickname</td><td>read, write</td><td> _contacts_nickname child record (multiple) </td></tr>
+ * <tr><td>record</td><td>profile</td><td>read, write</td><td>  _contacts_profile child record (multiple) </td></tr>
+ * <tr><td>record</td><td>relationship</td><td>read, write</td><td> _contacts_relationship child record (multiple)</td></tr>
+ * <tr><td>record</td><td>image</td><td>read, write</td><td> _contacts_image child record (multiple)</td></tr>
+ * <tr><td>record</td><td>group_relation</td><td>read, write</td><td> _contacts_group_relation child record (multiple)</td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                        // read only
+    _CONTACTS_PROPERTY_STR( display_name )              // read only
+    _CONTACTS_PROPERTY_INT( display_source_type )       // read only
+    _CONTACTS_PROPERTY_INT( address_book_id )           // read, write once
+    _CONTACTS_PROPERTY_STR( ringtone_path )             // read, write
+    _CONTACTS_PROPERTY_STR( image_thumbnail_path )      // read only
+    _CONTACTS_PROPERTY_BOOL( is_favorite )              // read, write
+    _CONTACTS_PROPERTY_BOOL( has_phonenumber )          // read only
+    _CONTACTS_PROPERTY_BOOL( has_email )                // read only
+    _CONTACTS_PROPERTY_INT( person_id )                 // read, write once
+    _CONTACTS_PROPERTY_STR( uid )                       // read, write
+    _CONTACTS_PROPERTY_STR( vibration )                 // read, write
+    _CONTACTS_PROPERTY_INT( changed_time )              // read only
+    _CONTACTS_PROPERTY_INT( link_mode )                 // read, write
+    _CONTACTS_PROPERTY_CHILD_SINGLE( name )             // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( image )          // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( company )        // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( note )           // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( number )         // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( email )          // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( event )          // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( messenger )      // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( address )        // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( url )            // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( nickname )       // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( profile )        // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( relationship )   // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( group_relation ) // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( extension )      // read, write
+    _CONTACTS_PROPERTY_STR( message_alert )             // read, write
+_CONTACTS_END_VIEW( _contacts_contact )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile _contacts_my_profile view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this my profile view </td></tr>
+ * <tr><td>integer</td><td>id</td><td>read only</td><td> DB record ID of the my profile </td></tr>
+ * <tr><td>string</td><td>display_name</td><td>read only</td><td> Display name of the profile </td></tr>
+ * <tr><td>integer</td><td>address_book_id</td><td>read, write once</td><td> Addressbook ID that the profile belongs to </td></tr>
+ * <tr><td>string</td><td>image_thumbnail_path</td><td>read only</td><td> Image thumbnail path of the profile </td></tr>
+ * <tr><td>string</td><td>uid</td><td>read, write</td><td> Unique identifier </td></tr>
+ * <tr><td>integer</td><td>changed_time</td><td>read only</td><td> Last changed profile time </td></tr>
+ * <tr><td>record</td><td>name</td><td>read, write</td><td> _contacts_name child record (single) </td></tr>
+ * <tr><td>record</td><td>company</td><td>read, write</td><td> _contacts_company child record (multiple) </td></tr>
+ * <tr><td>record</td><td>note</td><td>read, write</td><td> _contacts_note child record (multiple) </td></tr>
+ * <tr><td>record</td><td>number</td><td>read, write</td><td> _contacts_number child record (multiple) </td></tr>
+ * <tr><td>record</td><td>email</td><td>read, write</td><td> _contacts_email child record (multiple) </td></tr>
+ * <tr><td>record</td><td>event</td><td>read, write</td><td> _contacts_event child record (multiple) </td></tr>
+ * <tr><td>record</td><td>messenger</td><td>read, write</td><td> _contacts_messenger child record (multiple) </td></tr>
+ * <tr><td>record</td><td>address</td><td>read, write</td><td> _contacts_address child record (multiple) </td></tr>
+ * <tr><td>record</td><td>url</td><td>read, write</td><td> _contacts_url child record (multiple) </td></tr>
+ * <tr><td>record</td><td>nickname</td><td>read, write</td><td> _contacts_nickname child record (multiple) </td></tr>
+ * <tr><td>record</td><td>profile</td><td>read, write</td><td> _contacts_profile child record (multiple) </td></tr>
+ * <tr><td>record</td><td>relationship</td><td>read, write</td><td> _contacts_relationship child record (multiple) </td></tr>
+ * <tr><td>record</td><td>image</td><td>read, write</td><td> _contacts_image child record (multiple) </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                        // read only
+    _CONTACTS_PROPERTY_STR( display_name )              // read only
+    _CONTACTS_PROPERTY_INT( address_book_id )           // read, write once
+    _CONTACTS_PROPERTY_STR( image_thumbnail_path )      // read only
+    _CONTACTS_PROPERTY_STR( uid )                       // read, write
+    _CONTACTS_PROPERTY_INT( changed_time )              // read only
+    _CONTACTS_PROPERTY_CHILD_SINGLE( name )             // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( image )          // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( company )        // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( note )           // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( number )         // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( email )          // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( event )          // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( messenger )      // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( address )        // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( url )            // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( nickname )       // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( profile )        // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( relationship )   // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE( extension )      // read, write
+_CONTACTS_END_VIEW( _contacts_my_profile )
+
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_name _contacts_name view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ *</tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts name view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the name </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> Contacts ID that the name record belongs to </td></tr>
+ * <tr><td>string</td><td> first </td><td>read, write</td><td> First name </td></tr>
+ * <tr><td>string</td><td> last </td><td>read, write</td><td> Last name </td></tr>
+ * <tr><td>string</td><td> addition </td><td>read, write</td><td> Middle name </td></tr>
+ * <tr><td>string</td><td> suffix </td><td>read, write</td><td> Suffix </td></tr>
+ * <tr><td>string</td><td> prefix </td><td>read, write</td><td> Prefix </td></tr>
+ * <tr><td>string</td><td> phonetic_first </td><td>read, write</td><td> Pronounce the first name </td></tr>
+ * <tr><td>string</td><td> phonetic_middle </td><td>read, write</td><td> Pronounce the middle name  </td></tr>
+ * <tr><td>string</td><td> phonetic_last </td><td>read, write</td><td> Pronounce the last name </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                // read only
+    _CONTACTS_PROPERTY_INT( contact_id )        // read, write once
+    _CONTACTS_PROPERTY_STR( first )             // read, write
+    _CONTACTS_PROPERTY_STR( last )              // read, write
+    _CONTACTS_PROPERTY_STR( addition )          // read, write
+    _CONTACTS_PROPERTY_STR( suffix )            // read, write
+    _CONTACTS_PROPERTY_STR( prefix )            // read, write
+    _CONTACTS_PROPERTY_STR( phonetic_first )    // read, write
+    _CONTACTS_PROPERTY_STR( phonetic_middle )   // read, write
+    _CONTACTS_PROPERTY_STR( phonetic_last )     // read, write
+_CONTACTS_END_VIEW( _contacts_name )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ *
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_number _contacts_number view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts number view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the number </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> Contact ID that the number belongs to</td></tr>
+ * <tr><td>integer</td><td> type </td><td>read, write</td><td> Number type, refer to the @ref contacts_number_type_e </td></tr>
+ * <tr><td>string</td><td> label </td><td>read, write</td><td> Custom number type label, when the number type is #CONTACTS_NUMBER_TYPE_CUSTOM </td></tr>
+ * <tr><td>boolean</td><td> is_default </td><td>read, write</td><td> The number is default number or not </td></tr>
+ * <tr><td>string</td><td> number </td><td>read, write</td><td> Number </td></tr>
+ * <tr><td>string</td><td> normalized_number </td><td> filter only </td><td> You can only use this property for search filter. </td></tr>
+ * <tr><td>string</td><td> cleaned_number </td><td> filter only </td><td> You can only use this property for search filter. </td></tr>
+ * <tr><td>string</td><td> number_filter </td><td> filter only </td><td> You can only use this property for search filter. </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                // read only
+    _CONTACTS_PROPERTY_INT( contact_id )        // read, write once
+    _CONTACTS_PROPERTY_INT( type )              // read, write
+    _CONTACTS_PROPERTY_STR( label )             // read, write
+    _CONTACTS_PROPERTY_BOOL( is_default )       // read, write
+    _CONTACTS_PROPERTY_STR( number )            // read, write
+    _CONTACTS_PROPERTY_STR( normalized_number ) // filter only
+    _CONTACTS_PROPERTY_STR( cleaned_number )    // filter only
+    _CONTACTS_PROPERTY_STR( number_filter )     // filter only
+_CONTACTS_END_VIEW( _contacts_number )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_email _contacts_email view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts email view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the email </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> Contact ID that the email belongs to </td></tr>
+ * <tr><td>integer</td><td> type </td><td>read, write</td><td> Email type, refer to the @ref contacts_email_type_e  </td></tr>
+ * <tr><td>string</td><td> label </td><td>read, write</td><td> Custom mail type label, when the email type is #CONTACTS_EMAIL_TYPE_CUSTOM </td></tr>
+ * <tr><td>boolean</td><td> is_default </td><td>read, write</td><td>  The email is default email or not </td></tr>
+ * <tr><td>string</td><td> email </td><td>read, write</td><td> Email address</td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                // read only
+    _CONTACTS_PROPERTY_INT( contact_id )        // read, write once
+    _CONTACTS_PROPERTY_INT( type )              // read, write
+    _CONTACTS_PROPERTY_STR( label )             // read, write
+    _CONTACTS_PROPERTY_BOOL( is_default )       // read, write
+    _CONTACTS_PROPERTY_STR( email )             // read, write
+_CONTACTS_END_VIEW( _contacts_email )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_address _contacts_address view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts address view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the address </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> Contact ID that the address belongs to </td></tr>
+ * <tr><td>integer</td><td> type </td><td>read, write</td><td> Address type, refer to the @ref contacts_address_type_e </td></tr>
+ * <tr><td>string</td><td> label </td><td>read, write</td><td> Address type label, when the address type is #CONTACTS_ADDRESS_TYPE_CUSTOM </td></tr>
+ * <tr><td>string</td><td> postbox </td><td>read, write</td><td> Post office box </td></tr>
+ * <tr><td>string</td><td> postal_code </td><td>read, write</td><td> Postal code </td></tr>
+ * <tr><td>string</td><td> region </td><td>read, write</td><td> Region </td></tr>
+ * <tr><td>string</td><td> locality </td><td>read, write</td><td> Locality </td></tr>
+ * <tr><td>string</td><td> street </td><td>read, write</td><td> Street </td></tr>
+ * <tr><td>string</td><td> country </td><td>read, write</td><td> Country </td></tr>
+ * <tr><td>string</td><td> extended </td><td>read, write</td><td> Extended address </td></tr>
+ * <tr><td>boolean</td><td> is_default </td><td>read, write</td><td> The address is default or not </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                // read only
+    _CONTACTS_PROPERTY_INT( contact_id )        // read, write once
+    _CONTACTS_PROPERTY_INT( type )              // read, write
+    _CONTACTS_PROPERTY_STR( label )             // read, write
+    _CONTACTS_PROPERTY_STR( postbox )           // read, write
+    _CONTACTS_PROPERTY_STR( extended )          // read, write
+    _CONTACTS_PROPERTY_STR( street )            // read, write
+    _CONTACTS_PROPERTY_STR( locality )          // read, write
+    _CONTACTS_PROPERTY_STR( region )            // read, write
+    _CONTACTS_PROPERTY_STR( postal_code )       // read, write
+    _CONTACTS_PROPERTY_STR( country )           // read, write
+    _CONTACTS_PROPERTY_BOOL( is_default )       // read, write
+_CONTACTS_END_VIEW( _contacts_address )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_note _contacts_note view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts note view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the note </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> Contact ID that the note belongs to </td></tr>
+ * <tr><td>string</td><td> note </td><td>read, write</td><td> Note contents </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )            // read only
+    _CONTACTS_PROPERTY_INT( contact_id )    // read, write once
+    _CONTACTS_PROPERTY_STR( note )          // read, write
+_CONTACTS_END_VIEW( _contacts_note )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_url _contacts_url view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts URL view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the URL </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> Contact ID that the URL belongs to </td></tr>
+ * <tr><td>integer</td><td> type </td><td>read, write</td><td> URL type, refer to the @ref contacts_url_type_e </td></tr>
+ * <tr><td>string</td><td> label </td><td>read, write</td><td> Custom URL type label, when the URL type is #CONTACTS_URL_TYPE_CUSTOM </td></tr>
+ * <tr><td>string</td><td> url </td><td>read, write</td><td> URL </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                // read only
+    _CONTACTS_PROPERTY_INT( contact_id )        // read, write once
+    _CONTACTS_PROPERTY_INT( type )              // read, write
+    _CONTACTS_PROPERTY_STR( label )             // read, write
+    _CONTACTS_PROPERTY_STR( url )               // read, write
+_CONTACTS_END_VIEW( _contacts_url )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_event _contacts_event view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts event view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the event </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> Contact ID that the event belongs to </td></tr>
+ * <tr><td>integer</td><td> type </td><td>read, write</td><td> Event type, refer to the @ref contacts_event_type_e </td></tr>
+ * <tr><td>string</td><td> label </td><td>read, write</td><td> Custom event type label, when the event type is #CONTACTS_EVENT_TYPE_CUSTOM </td></tr>
+ * <tr><td>integer</td><td> date </td><td>read, write</td><td> Event date(YYYYMMDD). e.g. 2014/1/1 : 20140101 </td></tr>
+ * <tr><td>integer</td><td> calendar_type </td><td>read, write</td><td> Calendar type, refer to the @ref contacts_event_calendar_type_e </td></tr>
+ * <tr><td>bool</td><td> is_leap_month </td><td>read, write</td><td> The month is leap or not (valid on lunisolar calendar only) </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                // read only
+    _CONTACTS_PROPERTY_INT( contact_id )        // read, write once
+    _CONTACTS_PROPERTY_INT( type )              // read, write
+    _CONTACTS_PROPERTY_STR( label )             // read, write
+    _CONTACTS_PROPERTY_INT( date )              // read, write
+    _CONTACTS_PROPERTY_INT( calendar_type )     // read, write
+    _CONTACTS_PROPERTY_BOOL( is_leap_month )    // read, write
+_CONTACTS_END_VIEW( _contacts_event )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group_relation _contacts_group_relation view
+ * Refer @ref contacts_group_add_contact, @ref contacts_group_remove_contact
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this relationship view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the group (can not used as filter) </td></tr>
+ * <tr><td>integer</td><td> group_id </td><td>read, write once</td><td> DB record ID of the group </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> DB record ID of the contact </td></tr>
+ * <tr><td>string</td><td> name </td><td>read only</td><td> Group name </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                // read only, can not used as filter
+    _CONTACTS_PROPERTY_INT( group_id )          // read, write once
+    _CONTACTS_PROPERTY_INT( contact_id )        // read, write once
+    _CONTACTS_PROPERTY_STR( name )              // read only
+_CONTACTS_END_VIEW( _contacts_group_relation )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_relationship _contacts_relationship view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this relationship view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the relationship </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> Contact ID that the relationship belongs to </td></tr>
+ * <tr><td>integer</td><td> type </td><td>read, write</td><td> Relationship type, refer to the @ref contacts_relationship_type_e </td></tr>
+ * <tr><td>string</td><td> label </td><td>read, write</td><td> Custom relationship type label, when the relationship type is CONTACTS_RELATIONSHIP_TYPE_CUSTOM </td></tr>
+ * <tr><td>string</td><td> name </td><td>read, write</td><td> Selected contact name that the relationship belongs to </td></tr>
+ * </table>
+ *
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                // read only
+    _CONTACTS_PROPERTY_INT( contact_id )        // read, write once
+    _CONTACTS_PROPERTY_INT( type )              // read, write
+    _CONTACTS_PROPERTY_STR( label )             // read, write
+    _CONTACTS_PROPERTY_STR( name )              // read, write
+_CONTACTS_END_VIEW( _contacts_relationship )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_image _contacts_image view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts image view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the image </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> Contact ID that the image belongs to </td></tr>
+ * <tr><td>integer</td><td> type </td><td>read, write</td><td> Image type, refer to the @ref contacts_image_type_e </td></tr>
+ * <tr><td>string</td><td> label </td><td>read, write</td><td> Custom image type label, when the image type is #CONTACTS_IMAGE_TYPE_CUSTOM </td></tr>
+ * <tr><td>string</td><td> path </td><td>read, write</td><td> Image thumbnail path </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                // read only
+    _CONTACTS_PROPERTY_INT( contact_id )        // read, write once
+    _CONTACTS_PROPERTY_INT( type )              // read, write
+    _CONTACTS_PROPERTY_STR( label )             // read, write
+    _CONTACTS_PROPERTY_STR( path )              // read, write
+    _CONTACTS_PROPERTY_BOOL( is_default )
+_CONTACTS_END_VIEW( _contacts_image )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_company _contacts_company view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts company view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the company </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> Contact ID that the company belongs to </td></tr>
+ * <tr><td>integer</td><td> type </td><td>read, write</td><td> Company type, refer to the @ref contacts_company_type_e </td></tr>
+ * <tr><td>string</td><td> label </td><td>read, write</td><td> Custom company type label, when the company type is #CONTACTS_COMPANY_TYPE_CUSTOM </td></tr>
+ * <tr><td>string</td><td> name </td><td>read, write</td><td> Company name </td></tr>
+ * <tr><td>string</td><td> department </td><td>read, write</td><td> Department </td></tr>
+ * <tr><td>string</td><td> job_title </td><td>read, write</td><td> Job title </td></tr>
+ * <tr><td>string</td><td> assistant_name </td><td>read, write</td><td> Assistant name </td></tr>
+ * <tr><td>string</td><td> role </td><td>read, write</td><td> Role </td></tr>
+ * <tr><td>string</td><td> logo </td><td>read, write</td><td> Company logo image file path </td></tr>
+ * <tr><td>string</td><td> location </td><td>read, write</td><td> Company location </td></tr>
+ * <tr><td>string</td><td> description </td><td>read, write</td><td> Description </td></tr>
+ * <tr><td>string</td><td> phonetic_name </td><td>read, write</td><td> Pronounce the company name </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                    // read only
+    _CONTACTS_PROPERTY_INT( contact_id )            // read, write once
+    _CONTACTS_PROPERTY_INT( type )                  // read, write
+    _CONTACTS_PROPERTY_STR( label )                 // read, write
+    _CONTACTS_PROPERTY_STR( name )                  // read, write
+    _CONTACTS_PROPERTY_STR( department )            // read, write
+    _CONTACTS_PROPERTY_STR( job_title )             // read, write
+    _CONTACTS_PROPERTY_STR( assistant_name )        // read, write
+    _CONTACTS_PROPERTY_STR( role )                  // read, write
+    _CONTACTS_PROPERTY_STR( logo )                  // read, write
+    _CONTACTS_PROPERTY_STR( location )              // read, write
+    _CONTACTS_PROPERTY_STR( description )           // read, write
+    _CONTACTS_PROPERTY_STR( phonetic_name )         // read, write
+_CONTACTS_END_VIEW( _contacts_company )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_nickname _contacts_nickname view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts nickname view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the nickname </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> Contact ID that the nickname belongs to </td></tr>
+ * <tr><td>string</td><td> nickname </td><td>read, write</td><td> Nickname </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                    // read only
+    _CONTACTS_PROPERTY_INT( contact_id )            // read, write once
+    _CONTACTS_PROPERTY_STR( name )                  // read, write
+_CONTACTS_END_VIEW( _contacts_nickname )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_messenger _contacts_messenger view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts messenger view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the messenger </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> Contact ID that the messenger belongs to </td></tr>
+ * <tr><td>integer</td><td> type </td><td>read, write</td><td> Messenger type, refer to the @ref contacts_messenger_type_e </td></tr>
+ * <tr><td>string</td><td> label </td><td>read, write</td><td> Custom messenger type label, when the messenger type is #CONTACTS_MESSENGER_TYPE_CUSTOM </td></tr>
+ * <tr><td>string</td><td> im_id </td><td>read, write</td><td> Messenger ID (email address or email ID...) </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                    // read only
+    _CONTACTS_PROPERTY_INT( contact_id )            // read, write once
+    _CONTACTS_PROPERTY_INT( type )                  // read, write
+    _CONTACTS_PROPERTY_STR( label )                 // read, write
+    _CONTACTS_PROPERTY_STR( im_id )                 // read, write
+_CONTACTS_END_VIEW( _contacts_messenger )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_extension _contacts_extension view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts extension view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the contact extension </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> Contact ID that the contact extension belongs to </td></tr>
+ * <tr><td>integer</td><td> data1 </td><td>read, write</td><td> The extra child record format for non-provided from contacts-service </td></tr>
+ * <tr><td>string</td><td> data2 </td><td>read, write</td><td> The extra child record format for non-provided from contacts-service </td></tr>
+ * <tr><td>string</td><td> data3 </td><td>read, write</td><td> The extra child record format for non-provided from contacts-service </td></tr>
+ * <tr><td>string</td><td> data4 </td><td>read, write</td><td> The extra child record format for non-provided from contacts-service </td></tr>
+ * <tr><td>string</td><td> data5 </td><td>read, write</td><td> The extra child record format for non-provided from contacts-service </td></tr>
+ * <tr><td>string</td><td> data6 </td><td>read, write</td><td> The extra child record format for non-provided from contacts-service </td></tr>
+ * <tr><td>string</td><td> data7 </td><td>read, write</td><td> The extra child record format for non-provided from contacts-service </td></tr>
+ * <tr><td>string</td><td> data8 </td><td>read, write</td><td> The extra child record format for non-provided from contacts-service </td></tr>
+ * <tr><td>string</td><td> data9 </td><td>read, write</td><td> The extra child record format for non-provided from contacts-service </td></tr>
+ * <tr><td>string</td><td> data10 </td><td>read, write</td><td> The extra child record format for non-provided from contacts-service </td></tr>
+ * <tr><td>string</td><td> data11 </td><td>read, write</td><td> The extra child record format for non-provided from contacts-service </td></tr>
+ * <tr><td>string</td><td> data12 </td><td>read, write</td><td> The extra child record format for non-provided from contacts-service </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                    // read only
+    _CONTACTS_PROPERTY_INT( contact_id )            // read, write once
+    _CONTACTS_PROPERTY_INT( data1 )                 // read, write
+    _CONTACTS_PROPERTY_STR( data2 )                 // read, write
+    _CONTACTS_PROPERTY_STR( data3 )                 // read, write
+    _CONTACTS_PROPERTY_STR( data4 )                 // read, write
+    _CONTACTS_PROPERTY_STR( data5 )                 // read, write
+    _CONTACTS_PROPERTY_STR( data6 )                 // read, write
+    _CONTACTS_PROPERTY_STR( data7 )                 // read, write
+    _CONTACTS_PROPERTY_STR( data8 )                 // read, write
+    _CONTACTS_PROPERTY_STR( data9 )                 // read, write
+    _CONTACTS_PROPERTY_STR( data10 )                // read, write
+    _CONTACTS_PROPERTY_STR( data11 )                // read, write
+    _CONTACTS_PROPERTY_STR( data12 )                // read, write
+_CONTACTS_END_VIEW( _contacts_extension )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_sdn _contacts_sdn view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts sdn view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of the sdn </td></tr>
+ * <tr><td>string</td><td> name </td><td>read only</td><td> Provided name of sdn </td></tr>
+ * <tr><td>string</td><td> number </td><td>read only</td><td> Provided number of sdn </td></tr>
+ * <tr><td>integer</td><td> sim_slot_no </td><td>read only</td><td>It is related to the SIM slot number. sim_slot_no 0 means first SIM card, sim_slot_no 1 means second SIM. It is same with handle index of telephony handle list. Refer to the telephony_init() </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                    // read only
+    _CONTACTS_PROPERTY_STR( name )                  // read only
+    _CONTACTS_PROPERTY_STR( number )                // read only
+    _CONTACTS_PROPERTY_INT( sim_slot_no )           // read only
+_CONTACTS_END_VIEW( _contacts_sdn )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_profile _contacts_profile view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contacts profile view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of profile </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> Contacts ID that the profile belongs to </td></tr>
+ * <tr><td>string</td><td> uid </td><td>read, write</td><td> Unique identifier </td></tr>
+ * <tr><td>string</td><td> text </td><td>read, write</td><td> Profile contents </td></tr>
+ * <tr><td>integer</td><td> order </td><td>read, write</td><td> Priority to display the profile </td></tr>
+ * <tr><td>string</td><td> service_operation </td><td>read, write</td><td> Data for app_control_set_operation </td></tr>
+ * <tr><td>string</td><td> mime </td><td>read, write</td><td> Data for app_control_set_mime </td></tr>
+ * <tr><td>string</td><td> app_id </td><td>read, write</td><td> Data for app_control_set_app_id </td></tr>
+ * <tr><td>string</td><td> uri </td><td>read, write</td><td> Data for app_control_set_uri </td></tr>
+ * <tr><td>string</td><td> catagory </td><td>read, write</td><td> Data for app_control_set_category </td></tr>
+ * <tr><td>string</td><td> extra_data </td><td>read, write</td><td> It includes "key:value,key:value," pairs. You should parse it. And you must base64 encode each key and value</td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                    // read only
+    _CONTACTS_PROPERTY_STR( uid )                   // read, write
+    _CONTACTS_PROPERTY_STR( text )                  // read, write
+    _CONTACTS_PROPERTY_INT( order )                 // read, write
+    _CONTACTS_PROPERTY_STR( service_operation )     // read, write
+    _CONTACTS_PROPERTY_STR( mime )                  // read, write
+    _CONTACTS_PROPERTY_STR( app_id )                // read, write
+    _CONTACTS_PROPERTY_STR( uri )                   // read, write
+    _CONTACTS_PROPERTY_STR( category )              // read, write
+    _CONTACTS_PROPERTY_STR( extra_data )            // read, write
+    _CONTACTS_PROPERTY_INT( contact_id )            // read, write once
+_CONTACTS_END_VIEW( _contacts_profile )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity_photo _contacts_activity_photo view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contact activity photo view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of activity photo </td></tr>
+ * <tr><td>integer</td><td> activity_id </td><td>read, write once</td><td> Activity ID that the activity photo belongs to </td></tr>
+ * <tr><td>string</td><td> photo_url </td><td>read, write</td><td> Photo URL </td></tr>
+ * <tr><td>integer</td><td> sort_index </td><td>read, write</td><td> Sorted photo index </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                    // read only
+    _CONTACTS_PROPERTY_INT( activity_id )           // read, write once
+    _CONTACTS_PROPERTY_STR( photo_url )             // read, write
+    _CONTACTS_PROPERTY_INT( sort_index )            // read, write
+_CONTACTS_END_VIEW( _contacts_activity_photo )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity _contacts_activity view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this activity view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of activity </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> Contact ID that the activity belongs to </td></tr>
+ * <tr><td>string</td><td> source_name </td><td>read, write</td><td> Account name that the activity belongs to </td></tr>
+ * <tr><td>int</td><td> timestamp </td><td>read, write</td><td> Published time of activity </td></tr>
+ * <tr><td>string</td><td> status </td><td>read, write</td><td> Activity status </td></tr>
+ * <tr><td>string</td><td> service_operation </td><td>read, write</td><td> Data for app_control_set_operation </td></tr>
+ * <tr><td>string</td><td> uri </td><td>read, write</td><td> Data for app_control_set_uri </td></tr>
+ * <tr><td>record</td><td> photo </td><td>read, write</td><td> _contacts_activity_photo child record (multiple) </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                    // read only
+    _CONTACTS_PROPERTY_INT( contact_id )            // read, write once
+    _CONTACTS_PROPERTY_STR( source_name )           // read, write
+    _CONTACTS_PROPERTY_STR( status )                // read, write
+    _CONTACTS_PROPERTY_INT( timestamp )             // read, write
+    _CONTACTS_PROPERTY_STR( service_operation )     // read, write
+    _CONTACTS_PROPERTY_STR( uri )                   // read, write
+    _CONTACTS_PROPERTY_CHILD_MULTIPLE(photo)        // read, write
+_CONTACTS_END_VIEW( _contacts_activity )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_speeddial _contacts_speeddial view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this contact speed dial view </td></tr>
+ * <tr><td>integer</td><td> speeddial_number </td><td>read, write once</td><td> Stored speed dial number </td></tr>
+ * <tr><td>integer</td><td> number_id </td><td>read, write</td><td> Number ID that the speed dial belongs to </td></tr>
+ * <tr><td>string</td><td> number </td><td>read only</td><td> Contact number of specified speed dial </td></tr>
+ * <tr><td>string</td><td> number_label </td><td>read only</td><td> Contact number label of specified speed dial, when the number type is CONTACTS_NUMBER_TYPE_CUSTOM </td></tr>
+ * <tr><td>integer</td><td> number_type </td><td>read only</td><td> Contact number type, refer to the @ref contacts_number_type_e </td></tr>
+ * <tr><td>integer</td><td> person_id </td><td>read only</td><td> Person ID that the speed dial belongs to </td></tr>
+ * <tr><td>string</td><td> display_name </td><td>read only</td><td> Display name that the speed dial belongs to </td></tr>
+ * <tr><td>string</td><td> image_thumbnail_path </td><td>read only</td><td> Image thumbnail path that the speed dial belongs to </td></tr>
+ * <tr><td>string</td><td> normalized_number </td><td>filter only</td><td> You can only use this property for search filter </td></tr>
+ * <tr><td>string</td><td> cleaned_number </td><td>filter only</td><td> You can only use this property for search filter </td></tr>
+ * <tr><td>string</td><td> number_filter </td><td>filter only</td><td>  If you add filter with this property, the string will be normalized as minmatch length internally and the match rule will be applied CONTACTS_MATCH_EXACTLY </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( speeddial_number )      // read, write once
+    _CONTACTS_PROPERTY_INT( number_id )             // read, write
+    _CONTACTS_PROPERTY_STR( number )                // read only
+    _CONTACTS_PROPERTY_STR( number_label )          // read only
+    _CONTACTS_PROPERTY_INT( number_type )           // read only
+    _CONTACTS_PROPERTY_INT( person_id )             // read only
+    _CONTACTS_PROPERTY_STR( display_name )          // read only
+    _CONTACTS_PROPERTY_STR( image_thumbnail_path )  // read only
+    _CONTACTS_PROPERTY_STR( normalized_number)      // filter only
+    _CONTACTS_PROPERTY_STR( cleaned_number)         // filter only
+    _CONTACTS_PROPERTY_STR( number_filter)          // filter only
+_CONTACTS_END_VIEW( _contacts_speeddial )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log _contacts_phone_log view
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Read, Write</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td>read only</td><td> Identifier of this phone log view </td></tr>
+ * <tr><td>integer</td><td> id </td><td>read only</td><td> DB record ID of phone log </td></tr>
+ * <tr><td>integer</td><td> person_id </td><td>read, write once </td><td> Person ID that the phone log belongs to </td></tr>
+ * <tr><td>string</td><td> address </td><td>read, write once </td><td> Number or Email that the phone log displays </td></tr>
+ * <tr><td>integer</td><td> log_time </td><td>read, write once</td><td> Call end time. The value means number of seconds since 1970-01-01 00:00:00 (UTC) </td></tr>
+ * <tr><td>integer</td><td> log_type </td><td>read, write</td><td> Log type, refer to the @ref contacts_phone_log_type_e </td></tr>
+ * <tr><td>integer</td><td> extra_data1 </td><td>read, write once</td><td> You can set the related integer data (e.g. message_id, email_id or duration(seconds) of call) </td></tr>
+ * <tr><td>string</td><td> extra_data2 </td><td>read, write once</td><td> You can set the related string data (e.g. short message, subject) </td></tr>
+ * <tr><td>string</td><td> normalized_address </td><td> filter only</td><td> You can only use this property for search filter</td></tr>
+ * <tr><td>string</td><td> cleaned_address </td><td> filter only</td><td> You can only use this property for search filter</td></tr>
+ * <tr><td>string</td><td> address_filter </td><td> filter only</td><td> You can only use this property for search filter</td></tr>
+ * <tr><td>integer</td><td> sim_slot_no </td><td>read, write once</td><td> You can set the related SIM slot number. sim_slot_no 0 means first SIM card, sim_slot_no 1 means second SIM. It is same with handle index of telephony handle list. Refer to the telephony_init() </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_VIEW()
+    _CONTACTS_PROPERTY_INT( id )                    // read only
+    _CONTACTS_PROPERTY_INT( person_id )             // read, write once
+    _CONTACTS_PROPERTY_STR( address )               // read, write once, number or email
+    _CONTACTS_PROPERTY_INT( log_time )              // read, write once
+    _CONTACTS_PROPERTY_INT( log_type )              // read, write
+    _CONTACTS_PROPERTY_INT( extra_data1 )           // read, write once : message or email ID, duration(seconds)
+    _CONTACTS_PROPERTY_STR( extra_data2 )           // read, write once : shortmsg, subject
+    _CONTACTS_PROPERTY_STR( normalized_address )    // filter only
+    _CONTACTS_PROPERTY_STR( cleaned_address )       // filter only
+    _CONTACTS_PROPERTY_STR( address_filter )        // filter only
+    _CONTACTS_PROPERTY_INT( sim_slot_no )           // read, write once
+_CONTACTS_END_VIEW( _contacts_phone_log )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact_updated_info _contacts_contact_updated_info view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this contact updated info view </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td> Updated contact ID </td></tr>
+ * <tr><td>integer</td><td> address_book_id </td><td> Addressbook ID that the updated contact belongs to </td></tr>
+ * <tr><td>integer</td><td> type </td><td> Contact updated type, refer to the @ref contacts_changed_e </td></tr>
+ * <tr><td>integer</td><td> version </td><td> Updated version </td></tr>
+ * <tr><td>boolean</td><td> image_changed </td><td> Contact image is changed or not </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( contact_id )
+    _CONTACTS_PROPERTY_INT( address_book_id )
+    _CONTACTS_PROPERTY_INT( type )               // insert/update/delete
+    _CONTACTS_PROPERTY_INT( version )
+    _CONTACTS_PROPERTY_BOOL( image_changed )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_contact_updated_info )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_my_profile_updated_info _contacts_my_profile_updated_info view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this my profile updated info view </td></tr>
+ * <tr><td>integer</td><td> address_book_id </td><td> Address book ID that the updated my profile belongs to </td></tr>
+ * <tr><td>integer</td><td> last_changed_type </td><td> Changed update type, refer to the @ref contacts_changed_e </td></tr>
+ * <tr><td>integer</td><td> version </td><td> Updated version </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( address_book_id )
+    _CONTACTS_PROPERTY_INT( last_changed_type )
+    _CONTACTS_PROPERTY_INT( version )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_my_profile_updated_info )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group_updated_info _contacts_group_updated_info view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this group updated info view </td></tr>
+ * <tr><td>integer</td><td> group_id </td><td> Updated group ID </td></tr>
+ * <tr><td>integer</td><td> address_book_id </td><td> Address book ID that the updated group belongs to </td></tr>
+ * <tr><td>integer</td><td> type </td><td> Changed update type, refer to the @ref contacts_changed_e </td></tr>
+ * <tr><td>integer</td><td> version </td><td> Updated version </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( group_id )
+    _CONTACTS_PROPERTY_INT( address_book_id )
+    _CONTACTS_PROPERTY_INT( type )                // insert/update/delete
+    _CONTACTS_PROPERTY_INT( version )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_group_updated_info )
+
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group_member_updated_info _contacts_group_member_updated_info view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this group member updated info view </td></tr>
+ * <tr><td>integer</td><td> group_id </td><td> Updated group ID </td></tr>
+ * <tr><td>integer</td><td> address_book_id </td><td> Address book ID that the updated group belongs to </td></tr>
+ * <tr><td>integer</td><td> version </td><td> Updated version </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+       _CONTACTS_PROPERTY_INT( group_id )
+       _CONTACTS_PROPERTY_INT( address_book_id )
+       _CONTACTS_PROPERTY_INT( version )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_group_member_updated_info )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_grouprel_updated_info _contacts_grouprel_updated_info view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this group relation updated info view </td></tr>
+ * <tr><td>integer</td><td> group_id </td><td> Group ID of group relation </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td> Contact ID of the updated group relation </td></tr>
+ * <tr><td>integer</td><td> address_book_id </td><td> Address book ID of contact that the updated group relation </td></tr>
+ * <tr><td>integer</td><td> type </td><td> Changed update type, refer to the @ref contacts_changed_e </td></tr>
+ * <tr><td>integer</td><td> version </td><td> Updated version </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( group_id )
+    _CONTACTS_PROPERTY_INT( contact_id )
+    _CONTACTS_PROPERTY_INT( address_book_id )
+    _CONTACTS_PROPERTY_INT( type )                // insert/delete
+    _CONTACTS_PROPERTY_INT( version )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_grouprel_updated_info )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_contact _contacts_person_contact view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this person contact view </td></tr>
+ * <tr><td>integer</td><td> person_id </td><td> DB record ID of the person </td></tr>
+ * <tr><td>string</td><td> display_name </td><td> Display name of the person</td></tr>
+ * <tr><td>string</td><td> display_name_index </td><td> The first character of first string for grouping. This is normalized using icu (projection) </td></tr>
+ * <tr><td>integer</td><td> display_contact_id </td><td> Display contact ID that the person belongs to (projection) </td></tr>
+ * <tr><td>string</td><td> ringtone_path </td><td> Ringtone path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> image_thumbnail_path </td><td> Image thumbnail path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> vibration </td><td> Vibration path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> message_alert </td><td> Message alert path of the person  (projection) </td></tr>
+ * <tr><td>string</td><td> status </td><td> Status of social account (projection) </td></tr>
+ * <tr><td>boolean</td><td> is_favorite </td><td> The person is favorite or not </td></tr>
+ * <tr><td>integer</td><td> link_count </td><td> Link count of contact records (projection) </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td> Contact ID that the person belongs to </td></tr>
+ * <tr><td>string</td><td> addressbook_ids </td><td> Addressbook IDs that the person belongs to (projection) </td></tr>
+ * <tr><td>boolean</td><td> has_phonenumber </td><td> The person has phone number or not </td></tr>
+ * <tr><td>boolean</td><td> has_email </td><td> The person has email or not </td></tr>
+ * <tr><td>integer</td><td> address_book_id </td><td> Addressbook ID that the person belongs to </td></tr>
+ * <tr><td>integer</td><td> address_book_mode </td><td> Addressbook mode, refer to the @ref contacts_address_book_mode_e </td></tr>
+ * <tr><td>string</td><td> address_book_name </td><td> Addressbook name that the person belongs to </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( person_id )
+    _CONTACTS_PROPERTY_STR( display_name )
+    _CONTACTS_PROPERTY_PROJECTION_STR( display_name_index)
+    _CONTACTS_PROPERTY_PROJECTION_INT( display_contact_id )
+    _CONTACTS_PROPERTY_PROJECTION_STR( ringtone_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( image_thumbnail_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( vibration )
+    _CONTACTS_PROPERTY_PROJECTION_STR( status )
+    _CONTACTS_PROPERTY_BOOL( is_favorite )
+    _CONTACTS_PROPERTY_PROJECTION_INT( link_count )
+    _CONTACTS_PROPERTY_PROJECTION_STR( addressbook_ids )
+    _CONTACTS_PROPERTY_BOOL( has_phonenumber )
+    _CONTACTS_PROPERTY_BOOL( has_email )
+    _CONTACTS_PROPERTY_INT( contact_id )
+    _CONTACTS_PROPERTY_INT( address_book_id )
+    _CONTACTS_PROPERTY_STR( address_book_name )
+    _CONTACTS_PROPERTY_INT( address_book_mode )
+    _CONTACTS_PROPERTY_PROJECTION_STR( message_alert )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_person_contact )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_number _contacts_person_number view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this person number view </td></tr>
+ * <tr><td>integer</td><td> person_id </td><td> DB record ID of the person </td></tr>
+ * <tr><td>string</td><td> display_name </td><td> Display name of the person</td></tr>
+ * <tr><td>string</td><td> display_name_index </td><td> The first character of first string for grouping. This is normalized using icu (projection) </td></tr>
+ * <tr><td>integer</td><td> display_contact_id </td><td> Display contact ID that the person belongs to (projection) </td></tr>
+ * <tr><td>string</td><td> ringtone_path </td><td> Ringtone path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> image_thumbnail_path </td><td> Image thumbnail path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> vibration </td><td> Vibration path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> message_alert </td><td> Message alert path of the person  (projection) </td></tr>
+ * <tr><td>boolean</td><td> is_favorite </td><td> The person is favorite or not </td></tr>
+ * <tr><td>boolean</td><td> has_phonenumber </td><td> The person has phone number or not </td></tr>
+ * <tr><td>boolean</td><td> has_email </td><td> The person has email or not </td></tr>
+ * <tr><td>integer</td><td> number_id </td><td> Number ID that the person belongs to </td></tr>
+ * <tr><td>integer</td><td> type </td><td> Number type, refer to the @ref contacts_number_type_e (projection) </td></tr>
+ * <tr><td>string</td><td> label </td><td> Custom number type label, when the number type is #CONTACTS_NUMBER_TYPE_CUSTOM (projection) </td></tr>
+ * <tr><td>boolean</td><td> is_primary_default </td><td> The number is default number or not </td></tr>
+ * <tr><td>string</td><td> number </td><td> Number </td></tr>
+ * <tr><td>string</td><td> number_filter </td><td> If you add filter with this property, the string will be normalized as minmatch length internally and the match rule will be applied CONTACTS_MATCH_EXACTLY </td></tr>
+ * <tr><td>string</td><td> normalized_number </td><td> You can only use this property for search filter</td></tr>
+ * <tr><td>string</td><td> cleaned_number </td><td>You can only use this property for search filter </td></tr>
+ * </table>
+
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( person_id )
+    _CONTACTS_PROPERTY_STR( display_name )
+    _CONTACTS_PROPERTY_PROJECTION_STR( display_name_index)
+    _CONTACTS_PROPERTY_PROJECTION_INT( display_contact_id )
+    _CONTACTS_PROPERTY_PROJECTION_STR( ringtone_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( image_thumbnail_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( vibration )
+    _CONTACTS_PROPERTY_BOOL( is_favorite )
+    _CONTACTS_PROPERTY_BOOL( has_phonenumber )
+    _CONTACTS_PROPERTY_BOOL( has_email )
+    _CONTACTS_PROPERTY_INT( number_id )
+    _CONTACTS_PROPERTY_PROJECTION_INT( type )
+    _CONTACTS_PROPERTY_PROJECTION_STR( label )
+    _CONTACTS_PROPERTY_BOOL( is_primary_default )
+    _CONTACTS_PROPERTY_STR( number )
+    _CONTACTS_PROPERTY_FILTER_STR( number_filter )
+    _CONTACTS_PROPERTY_FILTER_STR( normalized_number )
+    _CONTACTS_PROPERTY_PROJECTION_STR( message_alert )
+    _CONTACTS_PROPERTY_FILTER_STR( cleaned_number )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_person_number )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_email _contacts_person_email view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this person email view </td></tr>
+ * <tr><td>integer</td><td> person_id </td><td> DB record ID of the person </td></tr>
+ * <tr><td>string</td><td> display_name </td><td> Display name of the person </td></tr>
+ * <tr><td>string</td><td> display_name_index </td><td> The first character of first string for grouping. This is normalized using icu (projection) </td></tr>
+ * <tr><td>integer</td><td> display_contact_id </td><td> Display contact ID that the person belongs to (projection) </td></tr>
+ * <tr><td>string</td><td> ringtone_path </td><td> Ringtone path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> image_thumbnail_path </td><td> Image thumbnail path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> vibration </td><td> Vibration path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> message_alert </td><td> Message alert path of the person  (projection) </td></tr>
+ * <tr><td>boolean</td><td> is_favorite </td><td> The person is favorite or not </td></tr>
+ * <tr><td>boolean</td><td> has_phonenumber </td><td> The person has phone number or not </td></tr>
+ * <tr><td>boolean</td><td> has_email </td><td> The person has email or not </td></tr>
+ * <tr><td>integer</td><td> email_id </td><td> Email ID that the person belongs to </td></tr>
+ * <tr><td>integer</td><td> type </td><td> Email type, refer to the @ref contacts_email_type_e (projection) </td></tr>
+ * <tr><td>string</td><td> label </td><td> Custom mail type label, when the email type is #CONTACTS_EMAIL_TYPE_CUSTOM (projection) </td></tr>
+ * <tr><td>boolean</td><td> is_primary_default </td><td> The email is default email or not </td></tr>
+ * <tr><td>string</td><td> email </td><td> Email address</td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( person_id )
+    _CONTACTS_PROPERTY_STR( display_name )
+    _CONTACTS_PROPERTY_PROJECTION_STR( display_name_index)
+    _CONTACTS_PROPERTY_PROJECTION_INT( display_contact_id )
+    _CONTACTS_PROPERTY_PROJECTION_STR( ringtone_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( image_thumbnail_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( vibration )
+    _CONTACTS_PROPERTY_BOOL( is_favorite )
+    _CONTACTS_PROPERTY_BOOL( has_phonenumber )
+    _CONTACTS_PROPERTY_BOOL( has_email )
+    _CONTACTS_PROPERTY_INT( email_id )
+    _CONTACTS_PROPERTY_PROJECTION_INT( type )
+    _CONTACTS_PROPERTY_PROJECTION_STR( label )
+    _CONTACTS_PROPERTY_BOOL( is_primary_default )
+    _CONTACTS_PROPERTY_STR( email )
+    _CONTACTS_PROPERTY_PROJECTION_STR( message_alert )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_person_email )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_grouprel _contacts_person_grouprel view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this person group relation view </td></tr>
+ * <tr><td>integer</td><td> person_id </td><td> DB record ID of the person </td></tr>
+ * <tr><td>string</td><td> display_name </td><td> Display name of the person </td></tr>
+ * <tr><td>string</td><td> display_name_index </td><td> The first character of first string for grouping. This is normalized using icu (projection) </td></tr>
+ * <tr><td>integer</td><td> display_contact_id </td><td> Display contact ID that the person belongs to (projection) </td></tr>
+ * <tr><td>string</td><td> ringtone_path </td><td> Ringtone path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> image_thumbnail_path </td><td> Image thumbnail path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> vibration </td><td> Vibration path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> message_alert </td><td> Message alert path of the person  (projection) </td></tr>
+ * <tr><td>string</td><td> status </td><td> Status of social account (projection) </td></tr>
+ * <tr><td>boolean</td><td> is_favorite </td><td> The person is favorite or not </td></tr>
+ * <tr><td>integer</td><td> link_count </td><td> Link count of contat records (projection)  </td></tr>
+ * <tr><td>string</td><td> addressbook_ids </td><td> Addressbook IDs that the person belongs to (projection) </td></tr>
+ * <tr><td>boolean</td><td> has_phonenumber </td><td> The person has phone number or not </td></tr>
+ * <tr><td>boolean</td><td> has_email </td><td> The person has email or not </td></tr>
+ * <tr><td>integer</td><td> address_book_id </td><td> Addressbook ID that the person belongs to </td></tr>
+ * <tr><td>integer</td><td> address_book_mode </td><td> Addressbook mode, refer to the @ref contacts_address_book_mode_e </td></tr>
+ * <tr><td>string</td><td> address_book_name </td><td> Addressbook name that the person belongs to </td></tr>
+ * <tr><td>integer</td><td> group_id </td><td> Group ID that the person belongs to </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td> Contact ID that the person belongs to (projection) </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( person_id )
+    _CONTACTS_PROPERTY_STR( display_name )
+    _CONTACTS_PROPERTY_PROJECTION_STR( display_name_index)
+    _CONTACTS_PROPERTY_PROJECTION_INT( display_contact_id )
+    _CONTACTS_PROPERTY_PROJECTION_STR( ringtone_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( image_thumbnail_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( vibration )
+    _CONTACTS_PROPERTY_PROJECTION_STR( status )
+    _CONTACTS_PROPERTY_BOOL( is_favorite )
+    _CONTACTS_PROPERTY_PROJECTION_INT( link_count )
+    _CONTACTS_PROPERTY_PROJECTION_STR( addressbook_ids )
+    _CONTACTS_PROPERTY_BOOL( has_phonenumber )
+    _CONTACTS_PROPERTY_BOOL( has_email )
+    _CONTACTS_PROPERTY_INT( address_book_id )
+    _CONTACTS_PROPERTY_INT( group_id )
+    _CONTACTS_PROPERTY_STR( address_book_name )
+    _CONTACTS_PROPERTY_INT( address_book_mode )
+    _CONTACTS_PROPERTY_PROJECTION_INT( contact_id )
+    _CONTACTS_PROPERTY_PROJECTION_STR( message_alert )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_person_grouprel )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_group_assigned _contacts_person_group_assigned view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this person group assigned view </td></tr>
+ * <tr><td>integer</td><td> person_id </td><td> DB record ID of the person </td></tr>
+ * <tr><td>string</td><td> display_name </td><td> Display name of the person </td></tr>
+ * <tr><td>string</td><td> display_name_index </td><td> The first character of first string for grouping. This is normalized using icu (projection) </td></tr>
+ * <tr><td>integer</td><td> display_contact_id </td><td> Display contact ID that the person belongs to (projection) </td></tr>
+ * <tr><td>string</td><td> ringtone_path </td><td> Ringtone path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> image_thumbnail_path </td><td> Image thumbnail path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> vibration </td><td> Vibration path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> message_alert </td><td> Message alert path of the person  (projection) </td></tr>
+ * <tr><td>string</td><td> status </td><td> Status of social account (projection) </td></tr>
+ * <tr><td>boolean</td><td> is_favorite </td><td> The person is favorite or not </td></tr>
+ * <tr><td>integer</td><td> link_count </td><td> Link count of contact records (projection) </td></tr>
+ * <tr><td>string</td><td> linked_address_book_ids </td><td> Addressbook IDs that the linked person belongs to (projection) </td></tr>
+ * <tr><td>boolean</td><td> has_phonenumber </td><td> The person has phone number or not </td></tr>
+ * <tr><td>boolean</td><td> has_email </td><td> The person has email or not </td></tr>
+ * <tr><td>integer</td><td> address_book_id </td><td> Addressbook ID that the person belongs to </td></tr>
+ * <tr><td>integer</td><td> address_book_mode </td><td> Addressbook mode, refer to the @ref contacts_address_book_mode_e </td></tr>
+ * <tr><td>integer</td><td> group_id </td><td> Group ID that the person belongs to </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td> Contact ID that the person belongs to (projection) </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( person_id )
+    _CONTACTS_PROPERTY_STR( display_name )
+    _CONTACTS_PROPERTY_PROJECTION_STR( display_name_index)
+    _CONTACTS_PROPERTY_PROJECTION_INT( display_contact_id )
+    _CONTACTS_PROPERTY_PROJECTION_STR( ringtone_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( image_thumbnail_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( vibration )
+    _CONTACTS_PROPERTY_PROJECTION_STR( status )
+    _CONTACTS_PROPERTY_BOOL( is_favorite )
+    _CONTACTS_PROPERTY_PROJECTION_INT( link_count )
+    _CONTACTS_PROPERTY_PROJECTION_STR( linked_address_book_ids )
+    _CONTACTS_PROPERTY_BOOL( has_phonenumber )
+    _CONTACTS_PROPERTY_BOOL( has_email )
+    _CONTACTS_PROPERTY_INT( address_book_id )
+    _CONTACTS_PROPERTY_INT( group_id )
+    _CONTACTS_PROPERTY_INT( address_book_mode )
+    _CONTACTS_PROPERTY_PROJECTION_INT( contact_id )
+    _CONTACTS_PROPERTY_PROJECTION_STR( message_alert )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_person_group_assigned )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_group_not_assigned _contacts_person_group_not_assigned view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this person group not assigned view </td></tr>
+ * <tr><td>integer</td><td> person_id </td><td> DB record ID of the person </td></tr>
+ * <tr><td>string</td><td> display_name </td><td> Display name of the person </td></tr>
+ * <tr><td>string</td><td> display_name_index </td><td> The first character of first string for grouping. This is normalized using icu (projection) </td></tr>
+ * <tr><td>integer</td><td> display_contact_id </td><td> Display contact ID that the person belongs to (projection) </td></tr>
+ * <tr><td>string</td><td> ringtone_path </td><td> Ringtone path of the person (projection)  </td></tr>
+ * <tr><td>string</td><td> image_thumbnail_path </td><td> Image thumbnail path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> vibration </td><td> Vibration path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> message_alert </td><td> Message alert path of the person  (projection) </td></tr>
+ * <tr><td>string</td><td> status </td><td> Status of social account (projection) </td></tr>
+ * <tr><td>boolean</td><td> is_favorite </td><td> The person is favorite or not </td></tr>
+ * <tr><td>integer</td><td> link_count </td><td> Link count of contact records (projection) </td></tr>
+ * <tr><td>string</td><td> linked_address_book_ids </td><td> Addressbook IDs that the linked person belongs to (projection) </td></tr>
+ * <tr><td>boolean</td><td> has_phonenumber </td><td> The person has phone number or not </td></tr>
+ * <tr><td>boolean</td><td> has_email </td><td> The person has email or not </td></tr>
+ * <tr><td>integer</td><td> address_book_id </td><td> Addressbook ID that the person belongs to </td></tr>
+ * <tr><td>integer</td><td> address_book_mode </td><td> Addressbook mode, refer to the @ref contacts_address_book_mode_e </td></tr>
+ * <tr><td>integer</td><td> contact_id </td><td> Contact ID that the person belongs to (projection) </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( person_id )
+    _CONTACTS_PROPERTY_STR( display_name )
+    _CONTACTS_PROPERTY_PROJECTION_STR( display_name_index)
+    _CONTACTS_PROPERTY_PROJECTION_INT( display_contact_id )
+    _CONTACTS_PROPERTY_PROJECTION_STR( ringtone_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( image_thumbnail_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( vibration )
+    _CONTACTS_PROPERTY_PROJECTION_STR( status )
+    _CONTACTS_PROPERTY_BOOL( is_favorite )
+    _CONTACTS_PROPERTY_PROJECTION_INT( link_count )
+    _CONTACTS_PROPERTY_PROJECTION_STR( linked_address_book_ids )
+    _CONTACTS_PROPERTY_BOOL( has_phonenumber )
+    _CONTACTS_PROPERTY_BOOL( has_email )
+    _CONTACTS_PROPERTY_INT( address_book_id )
+    _CONTACTS_PROPERTY_INT( address_book_mode )
+    _CONTACTS_PROPERTY_PROJECTION_INT( contact_id )
+    _CONTACTS_PROPERTY_PROJECTION_STR( message_alert )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_person_group_not_assigned )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_phone_log _contacts_person_phone_log view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this phone log view </td></tr>
+ * <tr><td>integer</td><td> person_id </td><td> DB record ID of person </td></tr>
+ * <tr><td>string</td><td> display_name </td><td> Display name of the person </td></tr>
+ * <tr><td>string</td><td> image_thumbnail_path </td><td> Image thumbnail path of the person (projection) </td></tr>
+ * <tr><td>integer</td><td> log_id </td><td> DB record ID of phone log </td></tr>
+ * <tr><td>string</td><td> address </td><td> Number or Email that the phone log displays </td></tr>
+ * <tr><td>integer</td><td> address_type </td><td> Number or Email type (projection)</td></tr>
+ * <tr><td>integer</td><td> log_time </td><td> Call end time. The value means number of seconds since 1970-01-01 00:00:00 (UTC) </td></tr>
+ * <tr><td>integer</td><td> log_type </td><td> Log type, refer to the @ref contacts_phone_log_type_e </td></tr>
+ * <tr><td>integer</td><td> extra_data1 </td><td> You can set the related integer data (e.g. message_id, email_id or duration(seconds) of call) (projection) </td></tr>
+ * <tr><td>string</td><td> extra_data2 </td><td> You can set the related string data (e.g. short message, subject) (projection) </td></tr>
+ * <tr><td>string</td><td> normalized_address </td><td> You can only use this property for search filter </td></tr>
+ * <tr><td>string</td><td> cleaned_address </td><td> You can only use this property for search filter </td></tr>
+ * <tr><td>string</td><td> address_filter </td><td> You can only use this property for search filter </td></tr>
+ * <tr><td>integer</td><td> sim_slot_no </td><td>It is related to the SIM slot number. sim_slot_no 0 means first SIM card, sim_slot_no 1 means second SIM. It is same with handle index of telephony handle list. Refer to the telephony_init() </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( person_id )
+    _CONTACTS_PROPERTY_STR( display_name )
+    _CONTACTS_PROPERTY_PROJECTION_STR( image_thumbnail_path )
+    _CONTACTS_PROPERTY_INT( log_id )
+    _CONTACTS_PROPERTY_STR( address )
+    _CONTACTS_PROPERTY_PROJECTION_INT( address_type )
+    _CONTACTS_PROPERTY_INT( log_time )
+    _CONTACTS_PROPERTY_INT( log_type )
+    _CONTACTS_PROPERTY_PROJECTION_INT( extra_data1 )
+    _CONTACTS_PROPERTY_PROJECTION_STR( extra_data2 )
+    _CONTACTS_PROPERTY_FILTER_STR( normalized_address)
+    _CONTACTS_PROPERTY_FILTER_STR( cleaned_address)
+    _CONTACTS_PROPERTY_FILTER_STR( address_filter)
+    _CONTACTS_PROPERTY_INT( sim_slot_no )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_person_phone_log )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_usage _contacts_person_usage view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this person usage view </td></tr>
+ * <tr><td>integer</td><td> person_id </td><td> DB record ID of the person </td></tr>
+ * <tr><td>string</td><td> display_name </td><td> Display name of the person </td></tr>
+ * <tr><td>string</td><td> display_name_index </td><td> The first character of first string for grouping. This is normalized using icu (projection) </td></tr>
+ * <tr><td>integer</td><td> display_contact_id </td><td> Display contact ID that the person belongs to (projection)  </td></tr>
+ * <tr><td>string</td><td> ringtone_path </td><td> Ringtone path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> image_thumbnail_path </td><td> Image thumbnail path of the person (projection)</td></tr>
+ * <tr><td>string</td><td> vibration </td><td> Vibration path of the person (projection) </td></tr>
+ * <tr><td>string</td><td> message_alert </td><td> Message alert path of the person (projection) </td></tr>
+ * <tr><td>boolean</td><td> is_favorite </td><td> The person is favorite or not </td></tr>
+ * <tr><td>boolean</td><td> has_phonenumber </td><td> The person has phone number or not </td></tr>
+ * <tr><td>boolean</td><td> has_email </td><td> The person has email or not </td></tr>
+ * <tr><td>integer</td><td> usage_type </td><td> Usage type, refer to the @ref contacts_usage_type_e </td></tr>
+ * <tr><td>integer</td><td> times_used </td><td> Usage number of person </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( person_id )
+    _CONTACTS_PROPERTY_STR( display_name )
+    _CONTACTS_PROPERTY_PROJECTION_STR( display_name_index)
+    _CONTACTS_PROPERTY_PROJECTION_INT( display_contact_id )
+    _CONTACTS_PROPERTY_PROJECTION_STR( ringtone_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( image_thumbnail_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( vibration )
+    _CONTACTS_PROPERTY_BOOL( is_favorite )
+    _CONTACTS_PROPERTY_BOOL( has_phonenumber )
+    _CONTACTS_PROPERTY_BOOL( has_email )
+    _CONTACTS_PROPERTY_INT( usage_type )
+    _CONTACTS_PROPERTY_INT( times_used )
+    _CONTACTS_PROPERTY_PROJECTION_STR( message_alert )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_person_usage )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact_number _contacts_contact_number view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this contacts number view </td></tr>
+ * <tr><td>integer</td><td>contact_id</td><td> Contact ID that the number belongs to </td></tr>
+ * <tr><td>string</td><td>display_name</td><td> Display name of contact that the number belongs to</td></tr>
+ * <tr><td>integer</td><td>display_source_type</td><td> The source type of display name, refer to the @ref contacts_display_name_source_type_e (projection) </td></tr>
+ * <tr><td>integer</td><td>address_book_id</td><td> Addressbook ID that the number belongs to </td></tr>
+ * <tr><td>integer</td><td>person_id</td><td> Person ID that the number belongs to </td></tr>
+ * <tr><td>string</td><td>ringtone_path</td><td> Ringtone path that the number belongs to (projection)  </td></tr>
+ * <tr><td>string</td><td>image_thumbnail_path</td><td>  Image thumbnail path that the number belongs to (projection) </td></tr>
+ * <tr><td>integer</td><td> number_id </td><td> DB record ID of the number </td></tr>
+ * <tr><td>integer</td><td> type </td><td> Number type, refer to the @ref contacts_number_type_e (projection) </td></tr>
+ * <tr><td>string</td><td> label </td><td> Custom number type label, when the number type is #CONTACTS_NUMBER_TYPE_CUSTOM (projection) </td></tr>
+ * <tr><td>boolean</td><td> is_default </td><td> The number is default number or not </td></tr>
+ * <tr><td>string</td><td> number </td><td> Number </td></tr>
+ * <tr><td>string</td><td> number_filter </td><td> If you add filter with this property, the string will be normalized as minmatch length internally and the match rule will be applied CONTACTS_MATCH_EXACTLY </td></tr>
+ * <tr><td>string</td><td> normalized_number </td><td>You can only use this property for search filter </td></tr>
+ * <tr><td>string</td><td> cleaned_number </td><td>You can only use this property for search filter </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( contact_id )
+    _CONTACTS_PROPERTY_STR( display_name )
+    _CONTACTS_PROPERTY_PROJECTION_INT( display_source_type)
+    _CONTACTS_PROPERTY_INT( address_book_id )
+    _CONTACTS_PROPERTY_INT( person_id )
+    _CONTACTS_PROPERTY_PROJECTION_STR( ringtone_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( image_thumbnail_path )
+    _CONTACTS_PROPERTY_INT( number_id )
+    _CONTACTS_PROPERTY_PROJECTION_INT( type )
+    _CONTACTS_PROPERTY_PROJECTION_STR( label )
+    _CONTACTS_PROPERTY_BOOL( is_default )
+    _CONTACTS_PROPERTY_STR( number )
+    _CONTACTS_PROPERTY_FILTER_STR( number_filter )
+    _CONTACTS_PROPERTY_FILTER_STR( normalized_number )
+    _CONTACTS_PROPERTY_FILTER_STR( cleaned_number )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_contact_number )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact_email _contacts_contact_email view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this contacts email view </td></tr>
+ * <tr><td>integer</td><td>contact_id</td><td> Contact ID that the email belongs to </td></tr>
+ * <tr><td>string</td><td>display_name</td><td> Display name that the email belongs to </td></tr>
+ * <tr><td>integer</td><td>display_source_type</td><td> The source type of display name that the email belongs to (projection) </td></tr>
+ * <tr><td>integer</td><td>address_book_id</td><td> Addressbook ID that the email belongs to </td></tr>
+ * <tr><td>integer</td><td>person_id</td><td> Person ID that the email belongs to </td></tr>
+ * <tr><td>string</td><td>ringtone_path</td><td> Ringtone path that the email belongs to (projection) </td></tr>
+ * <tr><td>string</td><td>image_thumbnail_path</td><td> Image thumbnail path that the email belongs to (projection) </td></tr>
+ * <tr><td>integer</td><td> email_id </td><td> DB record ID of the email </td></tr>
+ * <tr><td>integer</td><td> type </td><td>  Email type, refer to the @ref contacts_email_type_e (projection) </td></tr>
+ * <tr><td>string</td><td> label </td><td> Custom mail type label, when the email type is #CONTACTS_EMAIL_TYPE_CUSTOM (projection) </td></tr>
+ * <tr><td>boolean</td><td> is_default </td><td> Email is default email or not </td></tr>
+ * <tr><td>string</td><td> email </td><td> Email address </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( contact_id )
+    _CONTACTS_PROPERTY_STR( display_name )
+    _CONTACTS_PROPERTY_PROJECTION_INT( display_source_type)
+    _CONTACTS_PROPERTY_INT( address_book_id )
+    _CONTACTS_PROPERTY_INT( person_id )
+    _CONTACTS_PROPERTY_PROJECTION_STR( ringtone_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( image_thumbnail_path )
+    _CONTACTS_PROPERTY_INT( email_id )
+    _CONTACTS_PROPERTY_PROJECTION_INT( type )
+    _CONTACTS_PROPERTY_PROJECTION_STR( label )
+    _CONTACTS_PROPERTY_BOOL( is_default )
+    _CONTACTS_PROPERTY_STR( email )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_contact_email )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact_grouprel _contacts_contact_grouprel view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this contact grouprel view </td></tr>
+ * <tr><td>integer</td><td>contact_id</td><td> Contact ID that the contact group relation belongs to </td></tr>
+ * <tr><td>string</td><td>display_name</td><td> Display name of the group relation </td></tr>
+ * <tr><td>integer</td><td>display_source_type</td><td> The source type of display name (projection) </td></tr>
+ * <tr><td>integer</td><td>address_book_id</td><td> Addressbook ID that the group relation belongs to </td></tr>
+ * <tr><td>integer</td><td>person_id</td><td> Person ID that the group relation belongs to </td></tr>
+ * <tr><td>string</td><td>ringtone_path</td><td> Ringtone path of the group relation (projection) </td></tr>
+ * <tr><td>string</td><td>image_thumbnail_path</td><td> Image thumbnail path of the group relation (projection) </td></tr>
+ * <tr><td>integer</td><td> group_id </td><td> DB record ID of the group relation </td></tr>
+ * <tr><td>string</td><td> group_name </td><td> Group name (projection) </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( contact_id )
+    _CONTACTS_PROPERTY_STR( display_name )
+    _CONTACTS_PROPERTY_PROJECTION_INT( display_source_type)
+    _CONTACTS_PROPERTY_INT( address_book_id )
+    _CONTACTS_PROPERTY_INT( person_id )
+    _CONTACTS_PROPERTY_PROJECTION_STR( ringtone_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( image_thumbnail_path )
+    _CONTACTS_PROPERTY_INT( group_id )
+    _CONTACTS_PROPERTY_PROJECTION_STR( group_name )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_contact_grouprel )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact_activity _contacts_contact_activity view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this contact activity view </td></tr>
+ * <tr><td>integer</td><td>contact_id</td><td> Contact ID that the activity belongs to</td></tr>
+ * <tr><td>string</td><td>display_name</td><td> Display name of the contact that the activity belongs to </td></tr>
+ * <tr><td>integer</td><td>display_source_type</td><td> The source type of display name that the activity belongs to </td></tr>
+ * <tr><td>integer</td><td>address_book_id</td><td> Addressbook that the activity belongs to </td></tr>
+ * <tr><td>integer</td><td>person_id</td><td> Person ID that the activity belongs to </td></tr>
+ * <tr><td>string</td><td>ringtone_path</td><td> Ringtone path of the contact that the activity belongs to (projection) </td></tr>
+ * <tr><td>string</td><td>image_thumbnail_path</td><td> Image thumbnail path of the contact that the activity belongs to (projection) </td></tr>
+ * <tr><td>integer</td><td> activity_id </td><td> DB record ID of the activity </td></tr>
+ * <tr><td>string</td><td> source_name </td><td> Account name that the activity belongs to </td></tr>
+ * <tr><td>string</td><td> status </td><td> Activity status (projection) </td></tr>
+ * <tr><td>integer</td><td> timestamp </td><td> Published time of activity </td></tr>
+ * <tr><td>string</td><td> service_operation </td><td> Data for service_set_operation </td></tr>
+ * <tr><td>string</td><td> uri </td><td> Data for service_set_uri </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_INT( contact_id )
+    _CONTACTS_PROPERTY_STR( display_name )
+    _CONTACTS_PROPERTY_PROJECTION_INT( display_source_type)
+    _CONTACTS_PROPERTY_INT( address_book_id )
+    _CONTACTS_PROPERTY_INT( account_id )
+    _CONTACTS_PROPERTY_INT( person_id )
+    _CONTACTS_PROPERTY_PROJECTION_STR( ringtone_path )
+    _CONTACTS_PROPERTY_PROJECTION_STR( image_thumbnail_path )
+    _CONTACTS_PROPERTY_INT( activity_id )
+    _CONTACTS_PROPERTY_STR( source_name )
+    _CONTACTS_PROPERTY_PROJECTION_STR( status )
+    _CONTACTS_PROPERTY_INT( timestamp )
+    _CONTACTS_PROPERTY_STR( service_operation )
+    _CONTACTS_PROPERTY_STR( uri )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_contact_activity )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE View/Property
+ * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log_stat _contacts_phone_log_stat view (read only)
+ * <table>
+ * <tr>
+ *    <th>Type</th>
+ *    <th>Property ID</th>
+ *    <th>Description</th>
+ * </tr>
+ * <tr><td>string</td><td>_uri</td><td> Identifier of this log stat view </td></tr>
+ * <tr><td>integer</td><td> log_count </td><td>Log count (projection) </td></tr>
+ * <tr><td>integer</td><td> log_type </td><td> Log type, see the @ref contacts_phone_log_type_e </td></tr>
+ * </table>
+ */
+_CONTACTS_BEGIN_READ_ONLY_VIEW()
+    _CONTACTS_PROPERTY_PROJECTION_INT( log_count )
+    _CONTACTS_PROPERTY_INT( log_type )
+_CONTACTS_END_READ_ONLY_VIEW( _contacts_phone_log_stat )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_SOCIAL_CONTACTS_VIEWS_H__ */
+
diff --git a/native/ctsvc_activity.c b/native/ctsvc_activity.c
new file mode 100644 (file)
index 0000000..e18f051
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_access_control.h"
+
+API int contacts_activity_delete_by_contact_id(int contact_id)
+{
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_WRITE), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact write (contact activity)");
+       RETV_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_ACTIVITIES" WHERE contact_id = %d", contact_id);
+
+       int ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_set_activity_noti();
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       return ret;
+}
+
+API int contacts_activity_delete_by_account_id(int account_id)
+{
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_WRITE), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact write (contact activity)");
+       RETV_IF(account_id < 0, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE contact_id IN "
+                       "(SELECT C.contact_id FROM %s C, %s A ON C.addressbook_id = A.addressbook_id "
+                       "WHERE A.account_id = %d)",
+                       CTS_TABLE_ACTIVITIES, CTS_TABLE_CONTACTS, CTS_TABLE_ADDRESSBOOKS, account_id);
+
+       int ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_set_activity_noti();
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       return ret;
+}
+
+
old mode 100755 (executable)
new mode 100644 (file)
similarity index 71%
rename from test/SIMimport-test.c
rename to native/ctsvc_activity.h
index 1cbc357..f95dc52
@@ -1,35 +1,24 @@
-/*
- * 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()
-{
-       contacts_svc_connect();
-
-       int ret = contacts_svc_import_sim();
-       printf("contacts_svc_import_sim() return %d\n", ret);
-
-       contacts_svc_disconnect();
-       return 0;
-}
-
-
+/*\r
+ * Contacts Service\r
+ *\r
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
+\r
+#ifndef __TIZEN_SOCIAL_CTSVC_ACTIVITY_H__\r
+#define __TIZEN_SOCIAL_CTSVC_ACTIVITY_H__\r
+\r
+#endif // __TIZEN_SOCIAL_CTSVC_PERSON_H__\r
+\r
diff --git a/native/ctsvc_db_access_control.c b/native/ctsvc_db_access_control.c
new file mode 100644 (file)
index 0000000..692bf10
--- /dev/null
@@ -0,0 +1,474 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <pthread.h>
+#include <sys/smack.h>
+#include <pims-ipc-svc.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_mutex.h"
+#include "ctsvc_service.h"
+
+typedef struct {
+       unsigned int thread_id;
+       char *smack_label;
+       int permission;
+       int *write_list;
+       int write_list_count;
+}ctsvc_permission_info_s;
+
+static GList *__thread_list = NULL;
+
+static int have_smack = -1;
+
+// check SMACK enable or disable
+static int __ctsvc_have_smack(void)
+{
+       if (-1 == have_smack) {
+               if (NULL == smack_smackfs_path())
+                       have_smack = 0;
+               else
+                       have_smack = 1;
+       }
+       return have_smack;
+}
+
+// this function is called in mutex lock
+static ctsvc_permission_info_s * __ctsvc_find_access_info(unsigned int thread_id)
+{
+       GList *cursor;
+       CTS_VERBOSE("thread id : %08x", thread_id);
+       for (cursor=__thread_list;cursor;cursor = cursor->next) {
+               ctsvc_permission_info_s *info = NULL;
+               info = cursor->data;
+               if (info->thread_id == thread_id)
+                       return info;
+       }
+       return NULL;
+}
+
+// Check the client has read permission of the file(path)
+// success : CONTACTS_ERROR_NONE
+// fail : return negative value
+int ctsvc_have_file_read_permission(const char *path)
+{
+       int ret;
+       int permission = -1;
+       char *file_label = NULL;
+       ctsvc_permission_info_s *find = NULL;
+       const char *smack_label;
+       int have_smack;
+       unsigned int thread_id;
+
+       have_smack = __ctsvc_have_smack();
+       if (have_smack != 1)            // smack disable
+               return CONTACTS_ERROR_NONE;
+
+       // Get SMACK label of the file
+       ret = smack_getlabel(path, &file_label, SMACK_LABEL_ACCESS);
+       if(ret < 0) {
+               CTS_ERR("smack_getlabel Fail (%d)", ret);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       ctsvc_mutex_lock(CTS_MUTEX_ACCESS_CONTROL);
+       thread_id = (unsigned int)pthread_self();
+       find = __ctsvc_find_access_info(thread_id);
+       if (!find) {
+               CTS_ERR("does not have access info of the thread");
+               free(file_label);
+               ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+               return CONTACTS_ERROR_INTERNAL;
+       }
+
+       smack_label = find->smack_label;
+       permission = smack_have_access(smack_label, file_label, "r");
+       free(file_label);
+        if (permission == 0) {
+               CTS_ERR("Thread(0x%x), smack_have_access Fail(%d) : does not have permission", thread_id, permission);
+               ret = CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+       else if (permission != 1) {
+               CTS_ERR("Thread(0x%x), smack_have_access Fail(%d)", thread_id, ret);
+               ret = CONTACTS_ERROR_SYSTEM;
+       }
+       else {
+               ret= CONTACTS_ERROR_NONE;
+       }
+
+       ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+       return ret;
+}
+
+// this function is called in mutex lock
+static void __ctsvc_set_permission_info(unsigned int thread_id, const char *cookie)
+{
+       int ret;
+       int count;
+       int write_index;
+       cts_stmt stmt;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_permission_info_s *find = NULL;
+       const char *smack_label;
+       bool smack_enabled = false;
+
+       if (__ctsvc_have_smack() == 1)
+               smack_enabled = true;
+       else
+               INFO("SAMCK disabled");
+
+       find = __ctsvc_find_access_info(thread_id);
+       if (!find) {
+               CTS_ERR("does not have access info of the thread");
+               return;
+       }
+       smack_label = find->smack_label;
+
+       if (!find->permission) {                // check once
+               // contacts-service daemon has all permission
+               // Or, if smack is disabled, client has all permission
+               if ((smack_label && 0 == strcmp(smack_label, "contacts-service")) || !smack_enabled) {
+                       find->permission |= CTSVC_PERMISSION_CONTACT_READ;
+                       find->permission |= CTSVC_PERMISSION_CONTACT_WRITE;
+                       find->permission |= CTSVC_PERMISSION_PHONELOG_READ;
+                       find->permission |= CTSVC_PERMISSION_PHONELOG_WRITE;
+               }
+               else if (cookie && smack_label) {
+                       if (1 == (ret = smack_have_access(smack_label, "contacts-service::svc", "r")))
+                               find->permission |= CTSVC_PERMISSION_CONTACT_READ;
+                       else
+                               INFO("Thread(0x%x) : does not have contact read permission (%d)", thread_id, ret);
+                       if (1 == (ret = smack_have_access(smack_label, "contacts-service::svc", "w")))
+                               find->permission |= CTSVC_PERMISSION_CONTACT_WRITE;
+                       else
+                               INFO("Thread(0x%x) : does not have contact write permission (%d)", thread_id, ret);
+                       if (1 == (ret = smack_have_access(smack_label, "contacts-service::phonelog", "r")))
+                               find->permission |= CTSVC_PERMISSION_PHONELOG_READ;
+                       else
+                               INFO("Thread(0x%x) : does not have phone-log read permission (%d)", thread_id, ret);
+                       if (1 == (ret = smack_have_access(smack_label, "contacts-service::phonelog", "w")))
+                               find->permission |= CTSVC_PERMISSION_PHONELOG_WRITE;
+                       else
+                               INFO("Thread(0x%x) : does not have phone-log write permission (%d)", thread_id, ret);
+               }
+       }
+       INFO("Thread(0x%x), info(%p), permission:%d", thread_id, find, find->permission);
+
+       // white listing : core module
+       free(find->write_list);
+       find->write_list = NULL;
+       find->write_list_count = 0;
+
+       snprintf(query, sizeof(query),
+                       "SELECT count(addressbook_id) FROM "CTS_TABLE_ADDRESSBOOKS);
+       ret = ctsvc_query_get_first_int_result(query, &count);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_query_get_first_int_result() Failed(%d)", ret);
+               return;
+       }
+
+       if (find->permission & CTSVC_PERMISSION_CONTACT_WRITE) {
+               find->write_list = calloc(count, sizeof(int));
+               find->write_list_count = 0;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id, mode, smack_label FROM "CTS_TABLE_ADDRESSBOOKS);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               return;
+       }
+
+       write_index = 0;
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               int id;
+               int mode;
+               char *temp = NULL;
+
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       return;
+               }
+
+               id = ctsvc_stmt_get_int(stmt, 0);
+               mode = ctsvc_stmt_get_int(stmt, 1);
+               temp = ctsvc_stmt_get_text(stmt, 2);
+
+               if (smack_label && ((0 == strcmp(temp, smack_label)) || (0 == strcmp(smack_label, "contacts-service")))) {
+                       if (find->permission & CTSVC_PERMISSION_CONTACT_WRITE)
+                               find->write_list[write_index++] = id;
+                       continue;
+               }
+               else {
+                       switch(mode) {
+                       case CONTACTS_ADDRESS_BOOK_MODE_NONE:
+                               if (find->permission & CTSVC_PERMISSION_CONTACT_WRITE)
+                                       find->write_list[write_index++] = id;
+                               break;
+                       default:
+                               break;
+                       };
+               }
+       }
+
+       if (find->permission & CTSVC_PERMISSION_CONTACT_WRITE)
+               find->write_list_count = write_index;
+       ctsvc_stmt_finalize(stmt);
+}
+
+void ctsvc_unset_client_access_info()
+{
+       ctsvc_permission_info_s *find = NULL;
+
+       ctsvc_mutex_lock(CTS_MUTEX_ACCESS_CONTROL);
+       find = __ctsvc_find_access_info(pthread_self());
+       if (find) {
+               free(find->smack_label);
+               free(find->write_list);
+               __thread_list = g_list_remove(__thread_list, find);
+               free(find);
+       }
+       ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+}
+
+// release permission info resource when disconnecting client
+// It is set as callback function using pims-ipc API
+static void __ctsvc_client_disconnected_cb(pims_ipc_h ipc, void *user_data)
+{
+       ctsvc_permission_info_s *info;
+
+       ctsvc_mutex_lock(CTS_MUTEX_ACCESS_CONTROL);
+       info = (ctsvc_permission_info_s*)user_data;
+       if (info) {
+               INFO("Thread(0x%x), info(%p), permission:%d",
+                                                       info->thread_id, info, info->permission);
+               free(info->smack_label);
+               free(info->write_list);
+               __thread_list = g_list_remove(__thread_list, info);
+               free(info);
+       }
+
+       ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+
+       // if client did not call disconnect function such as contacts_disconnect, contacts_disconnect_on_thread
+       // DB will be closed in ctsvc_contacts_internal_disconnect()
+       ctsvc_contacts_internal_disconnect();
+}
+
+// Set access permission info per thread(client)
+void ctsvc_set_client_access_info(const char *smack_label, const char *cookie)
+{
+       unsigned int thread_id;
+       ctsvc_permission_info_s *info = NULL;
+
+       ctsvc_mutex_lock(CTS_MUTEX_ACCESS_CONTROL);
+       thread_id = (unsigned int)pthread_self();
+       info = __ctsvc_find_access_info(thread_id);
+       if (NULL == info) {
+               info = calloc(1, sizeof(ctsvc_permission_info_s));
+               if (NULL == info) {
+                       ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+                       CTS_ERR("calloc()() return NULL");
+                       return;
+               }
+               __thread_list  = g_list_append(__thread_list, info);
+       }
+       info->thread_id = thread_id;
+       FREEandSTRDUP(info->smack_label, smack_label);
+       __ctsvc_set_permission_info(thread_id, cookie);
+
+       if (strcmp(smack_label, "contacts-service") != 0)
+               pims_ipc_svc_set_client_disconnected_cb(__ctsvc_client_disconnected_cb, info);
+
+       ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+
+}
+
+// Whenever changing addressbook this function will be called
+// to reset read/write permssion info of each addressbook
+void ctsvc_reset_all_client_access_info()
+{
+       GList *cursor;
+       ctsvc_mutex_lock(CTS_MUTEX_ACCESS_CONTROL);
+       for (cursor=__thread_list;cursor;cursor=cursor->next) {
+               ctsvc_permission_info_s *info = (ctsvc_permission_info_s *)cursor->data;
+               if (info == NULL) continue;
+               __ctsvc_set_permission_info(info->thread_id, NULL);
+       }
+       ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+}
+
+bool ctsvc_have_permission(int permission)
+{
+       ctsvc_permission_info_s *find = NULL;
+       unsigned int thread_id;
+
+       have_smack = __ctsvc_have_smack();
+       if (have_smack != 1)            // smack disable
+               return true;
+
+       ctsvc_mutex_lock(CTS_MUTEX_ACCESS_CONTROL);
+       thread_id = (unsigned int)pthread_self();
+       find = __ctsvc_find_access_info(thread_id);
+       if (!find) {
+               ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+               return false;
+       }
+
+       if (CTSVC_PERMISSION_CONTACT_NONE == permission) {
+               ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+               return false;
+       }
+
+       if ((find->permission & permission) == permission) {
+               ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+               return true;
+       }
+
+       CTS_ERR("Thread(0x%x), Does not have permission %d, this module has permission %d",
+                       thread_id, permission, find->permission);
+       ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+
+       return false;
+}
+
+bool ctsvc_have_ab_write_permission(int addressbook_id)
+{
+       int i;
+       unsigned int thread_id;
+       ctsvc_permission_info_s *find = NULL;
+
+       have_smack = __ctsvc_have_smack();
+       if (have_smack != 1)            // smack disable
+               return true;
+
+       ctsvc_mutex_lock(CTS_MUTEX_ACCESS_CONTROL);
+       thread_id = (unsigned int)pthread_self();
+       find = __ctsvc_find_access_info(thread_id);
+       if (!find) {
+               ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+               CTS_ERR("can not found access info");
+               return false;
+       }
+
+       if (NULL == find->write_list) {
+               ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+               CTS_ERR("there is no write access info");
+               return false;
+       }
+
+       for (i=0;i<find->write_list_count;i++) {
+               if (addressbook_id == find->write_list[i]) {
+                       ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+                       return true;
+               }
+       }
+
+       ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+       CTS_ERR("Thread(0x%x), Does not have write permission of addressbook(%d)", thread_id, addressbook_id);
+       return false;
+}
+
+int ctsvc_get_write_permitted_addressbook_ids(int **addressbook_ids, int *count)
+{
+       ctsvc_permission_info_s *find = NULL;
+       *count = 0;
+       *addressbook_ids = NULL;
+
+       ctsvc_mutex_lock(CTS_MUTEX_ACCESS_CONTROL);
+       find = __ctsvc_find_access_info(pthread_self());
+       if (find) {
+               if (find->write_list && find->write_list_count > 0) {
+                       int size = find->write_list_count * sizeof(int);
+                       int *list = calloc(1, size);
+                       if (NULL == list) {
+                               ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+                               CTS_ERR("calloc() return NULL");
+                               return CONTACTS_ERROR_OUT_OF_MEMORY;
+                       }
+                       memcpy(list, find->write_list, size);
+                       *count = find->write_list_count;
+                       *addressbook_ids = list;
+                       ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+                       return CONTACTS_ERROR_NONE;
+               }
+               ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+       return CONTACTS_ERROR_INTERNAL;
+}
+
+char* ctsvc_get_client_smack_label()
+{
+       ctsvc_permission_info_s *find = NULL;
+       char *smack = NULL;
+
+       ctsvc_mutex_lock(CTS_MUTEX_ACCESS_CONTROL);
+       find = __ctsvc_find_access_info(pthread_self());
+       if (find)
+               smack = strdup(find->smack_label);
+       ctsvc_mutex_unlock(CTS_MUTEX_ACCESS_CONTROL);
+       return smack;
+}
+
+int ctsvc_is_owner(int addressbook_id)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       char *smack = NULL;
+       char *saved_smack = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_name, smack_label FROM "CTS_TABLE_ADDRESSBOOKS" "
+                               "WHERE addressbook_id = %d", addressbook_id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               return ret;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+
+       ret = CONTACTS_ERROR_PERMISSION_DENIED;
+
+       saved_smack = ctsvc_stmt_get_text(stmt, 1);
+       smack = ctsvc_get_client_smack_label();
+
+       if (smack && strcmp(smack, saved_smack) == 0)
+               ret = CONTACTS_ERROR_NONE;
+
+       ctsvc_stmt_finalize(stmt);
+
+       free(smack);
+       return ret;
+}
+
diff --git a/native/ctsvc_db_access_control.h b/native/ctsvc_db_access_control.h
new file mode 100644 (file)
index 0000000..d4cfda5
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CTSVC_DB_ACCESS_CONTROL_H__
+#define __TIZEN_SOCIAL_CTSVC_DB_ACCESS_CONTROL_H__
+
+int ctsvc_have_file_read_permission(const char *path);
+
+void ctsvc_set_client_access_info(const char *smack_label, const char *cookie);
+void ctsvc_unset_client_access_info(void);
+void ctsvc_reset_all_client_access_info(void);
+
+bool ctsvc_have_permission(int permission);
+char* ctsvc_get_client_smack_label(void);
+
+int ctsvc_get_write_permitted_addressbook_ids(int **addressbook_ids, int *count);
+bool ctsvc_have_ab_write_permission(int addressbook_id);
+int ctsvc_is_owner(int addressbook_id);
+
+
+#endif // __TIZEN_SOCIAL_CTSVC_DB_ACCESS_CONTROL_H__
diff --git a/native/ctsvc_db_init.c b/native/ctsvc_db_init.c
new file mode 100644 (file)
index 0000000..ec824f0
--- /dev/null
@@ -0,0 +1,947 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+
+#include "contacts.h"
+
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_view.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_access_control.h"
+
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_addressbook;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_contact;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_my_profile;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_simple_contact;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_group;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_person;
+#ifdef ENABLE_LOG_FEATURE
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_phonelog;
+#endif // ENABLE_LOG_FEATURE
+#ifdef ENABLE_SIM_FEATURE
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_speeddial;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_sdn;
+#endif // ENABLE_SIM_FEATURE
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_activity;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_activity_photo;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_address;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_company;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_email;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_event;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_grouprelation;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_relationship;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_image;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_messenger;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_name;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_nickname;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_note;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_number;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_url;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_extension;
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_profile;
+
+
+#ifdef _CONTACTS_NATIVE
+static int __ctsvc_db_view_ref_count = 0;
+#endif
+
+static GHashTable *__ctsvc_db_view_hash_table = NULL;
+
+#ifdef _CONTACTS_IPC_SERVER
+static bool __ctsvc_db_view_already_created = false;
+#endif
+
+typedef struct {
+       char *view_uri;
+       const char * const table_name;
+       int read_permission;
+       int write_permission;
+       bool need_ab_access_control;
+}db_table_info_s;
+
+static const db_table_info_s __db_tables[] = {
+       {CTSVC_VIEW_URI_ADDRESSBOOK,    CTS_TABLE_ADDRESSBOOKS, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_GROUP,                  CTS_TABLE_GROUPS, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_PERSON,                 CTSVC_DB_VIEW_PERSON, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_SIMPLE_CONTACT, CTSVC_DB_VIEW_CONTACT, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_CONTACT,                CTSVC_DB_VIEW_CONTACT, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_MY_PROFILE,     CTSVC_DB_VIEW_MY_PROFILE, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_ACTIVITY,               CTSVC_DB_VIEW_ACTIVITY, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_ACTIVITY_PHOTO,CTSVC_DB_VIEW_ACTIVITY_PHOTOS, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_PHONELOG,               CTS_TABLE_PHONELOGS, CTSVC_PERMISSION_PHONELOG_READ, CTSVC_PERMISSION_PHONELOG_WRITE, false},
+       {CTSVC_VIEW_URI_SPEEDDIAL,              CTSVC_DB_VIEW_SPEEDIDAL, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, false},
+       {CTSVC_VIEW_URI_SDN,                            CTS_TABLE_SDN, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, false},
+
+       {CTSVC_VIEW_URI_NAME,                   CTSVC_DB_VIEW_NAME, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_COMPANY,                CTSVC_DB_VIEW_COMPANY, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_NUMBER,                 CTSVC_DB_VIEW_NUMBER, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_EMAIL,                  CTSVC_DB_VIEW_EMAIL, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_URL,                    CTSVC_DB_VIEW_URL, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_ADDRESS,                CTSVC_DB_VIEW_ADDRESS, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_PROFILE,                CTSVC_DB_VIEW_PROFILE, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_RELATIONSHIP,   CTSVC_DB_VIEW_RELATIONSHIP, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_IMAGE,                  CTSVC_DB_VIEW_IMAGE, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_NOTE,                   CTSVC_DB_VIEW_NOTE, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_NICKNAME,               CTSVC_DB_VIEW_NICKNAME, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_EVENT,                  CTSVC_DB_VIEW_EVENT, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_MESSENGER,              CTSVC_DB_VIEW_MESSENGER, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_GROUP_RELATION, CTSVC_DB_VIEW_GROUP_RELATION, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+       {CTSVC_VIEW_URI_EXTENSION,              CTSVC_DB_VIEW_EXTENSION, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_WRITE, true},
+
+// Do not support get_all_records, get_records_with_query, get_count, get_count_with_query
+//     {CTSVC_VIEW_URI_GROUPS_UPDATED_INFO, CTSVC_DB_VIEW_GROUPS_UPDATED_INFO, false},
+//     {CTSVC_VIEW_URI_GROUPS_MEMBER_UPDATED_INFO, CTSVC_DB_VIEW_GROUPS_MEMBER_UPDATED_INFO, false},
+//     {CTSVC_VIEW_URI_CONTACTS_UPDATED_INFO, CTSVC_DB_VIEW_CONTACTS_UPDATED_INFO, false},
+//     {CTSVC_VIEW_URI_MY_PROFILE_UPDATED_INFO, NULL, false},
+//     {CTSVC_VIEW_URI_GROUPRELS_UPDATED_INFO, NULL, false},
+
+       {CTSVC_VIEW_URI_READ_ONLY_PERSON_CONTACT, CTSVC_DB_VIEW_PERSON_CONTACT, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_NONE, true},
+       {CTSVC_VIEW_URI_READ_ONLY_PERSON_NUMBER, CTSVC_DB_VIEW_PERSON_NUMBER, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_NONE, true},
+       {CTSVC_VIEW_URI_READ_ONLY_PERSON_EMAIL, CTSVC_DB_VIEW_PERSON_EMAIL, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_NONE, true},
+       {CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP, CTSVC_DB_VIEW_PERSON_GROUP, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_NONE, true},
+       {CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP_ASSIGNED, CTSVC_DB_VIEW_PERSON_GROUP_ASSIGNED, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_NONE, true},
+       {CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP_NOT_ASSIGNED, CTSVC_DB_VIEW_PERSON_GROUP_NOT_ASSIGNED, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_NONE, true},
+       {CTSVC_VIEW_URI_READ_ONLY_PERSON_PHONELOG, CTSVC_DB_VIEW_PERSON_PHONELOG, CTSVC_PERMISSION_CONTACT_READ|CTSVC_PERMISSION_PHONELOG_READ, CTSVC_PERMISSION_CONTACT_NONE, false},
+       {CTSVC_VIEW_URI_READ_ONLY_PERSON_USAGE, CTSVC_DB_VIEW_PERSON_USAGE, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_NONE, true},
+
+       {CTSVC_VIEW_URI_READ_ONLY_CONTACT_NUMBER, CTSVC_DB_VIEW_CONTACT_NUMBER, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_NONE, true},
+       {CTSVC_VIEW_URI_READ_ONLY_CONTACT_EMAIL, CTSVC_DB_VIEW_CONTACT_EMAIL, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_NONE, true},
+       {CTSVC_VIEW_URI_READ_ONLY_CONTACT_GROUP, CTSVC_DB_VIEW_CONTACT_GROUP, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_NONE, true},
+       {CTSVC_VIEW_URI_READ_ONLY_CONTACT_ACTIVITY, CTSVC_DB_VIEW_CONTACT_ACTIVITY, CTSVC_PERMISSION_CONTACT_READ, CTSVC_PERMISSION_CONTACT_NONE, true},
+
+       {CTSVC_VIEW_URI_READ_ONLY_PHONELOG_STAT, CTS_TABLE_PHONELOG_STAT, CTSVC_PERMISSION_PHONELOG_READ, CTSVC_PERMISSION_CONTACT_NONE, false},
+
+};
+
+// this function is called in mutex lock
+int ctsvc_db_plugin_init()
+{
+       int i;
+
+#ifdef _CONTACTS_NATIVE
+       __ctsvc_db_view_ref_count++;
+#endif
+
+       if (__ctsvc_db_view_hash_table) {
+               return CONTACTS_ERROR_NONE;
+       }
+
+       __ctsvc_db_view_hash_table = g_hash_table_new(g_str_hash, g_str_equal);
+
+       if (__ctsvc_db_view_hash_table) {
+               int count = sizeof(__db_tables) /sizeof(db_table_info_s);
+               for (i=0;i<count;i++)
+                       g_hash_table_insert(__ctsvc_db_view_hash_table, __db_tables[i].view_uri, GINT_TO_POINTER(&(__db_tables[i])));
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_plugin_deinit()
+{
+#ifdef _CONTACTS_NATIVE
+       __ctsvc_db_view_ref_count--;
+       if (__ctsvc_db_view_ref_count != 0)
+               return;
+#endif
+
+       if (!__ctsvc_db_view_hash_table) {
+               return CONTACTS_ERROR_NONE;
+       }
+       g_hash_table_destroy(__ctsvc_db_view_hash_table);
+       __ctsvc_db_view_hash_table = NULL;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_get_table_name(const char *view_uri, const char **out_table)
+{
+       db_table_info_s* db_view_info = NULL;
+
+       if(__ctsvc_db_view_hash_table){
+               db_view_info = g_hash_table_lookup(__ctsvc_db_view_hash_table, view_uri);
+               if (db_view_info) {
+                       *out_table = db_view_info->table_name;
+                       return CONTACTS_ERROR_NONE;
+               }
+       }
+       else
+               CTS_ERR("Please check contact_connect()");
+
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+int ctsvc_required_read_permission(const char *view_uri)
+{
+       db_table_info_s* db_view_info = NULL;
+
+       if(__ctsvc_db_view_hash_table){
+               db_view_info = g_hash_table_lookup(__ctsvc_db_view_hash_table, view_uri);
+               if (db_view_info) {
+                       return db_view_info->read_permission;
+               }
+       }
+       else
+               CTS_ERR("Please check contact_connect()");
+
+       return CTSVC_PERMISSION_CONTACT_NONE;
+}
+
+int ctsvc_required_write_permission(const char *view_uri)
+{
+       db_table_info_s* db_view_info = NULL;
+
+       if(__ctsvc_db_view_hash_table){
+               db_view_info = g_hash_table_lookup(__ctsvc_db_view_hash_table, view_uri);
+               if (db_view_info) {
+                       return db_view_info->write_permission;
+               }
+       }
+       else
+               CTS_ERR("Please check contact_connect()");
+
+       return CTSVC_PERMISSION_CONTACT_NONE;
+}
+
+bool ctsvc_should_ab_access_control(const char *view_uri)
+{
+       db_table_info_s* db_view_info = NULL;
+
+       if(__ctsvc_db_view_hash_table){
+               db_view_info = g_hash_table_lookup(__ctsvc_db_view_hash_table, view_uri);
+               if (db_view_info) {
+                       return db_view_info->need_ab_access_control;
+               }
+       }
+       else
+               CTS_ERR("Please check contact_connect()");
+
+       return false;
+}
+
+ctsvc_db_plugin_info_s* ctsvc_db_get_plugin_info(ctsvc_record_type_e type)
+{
+       switch((int)type) {
+       case CTSVC_RECORD_ADDRESSBOOK:
+               return &ctsvc_db_plugin_addressbook;
+       case CTSVC_RECORD_GROUP:
+               return &ctsvc_db_plugin_group;
+       case CTSVC_RECORD_PERSON:
+               return &ctsvc_db_plugin_person;
+       case CTSVC_RECORD_CONTACT:
+               return &ctsvc_db_plugin_contact;
+       case CTSVC_RECORD_MY_PROFILE:
+               return &ctsvc_db_plugin_my_profile;
+       case CTSVC_RECORD_SIMPLE_CONTACT:
+               return &ctsvc_db_plugin_simple_contact;
+       case CTSVC_RECORD_NAME:
+               return &ctsvc_db_plugin_name;
+       case CTSVC_RECORD_COMPANY:
+               return &ctsvc_db_plugin_company;
+       case CTSVC_RECORD_NOTE:
+               return &ctsvc_db_plugin_note;
+       case CTSVC_RECORD_NUMBER:
+               return &ctsvc_db_plugin_number;
+       case CTSVC_RECORD_EMAIL:
+               return &ctsvc_db_plugin_email;
+       case CTSVC_RECORD_URL:
+               return &ctsvc_db_plugin_url;
+       case CTSVC_RECORD_EVENT:
+               return &ctsvc_db_plugin_event;
+       case CTSVC_RECORD_NICKNAME:
+               return &ctsvc_db_plugin_nickname;
+       case CTSVC_RECORD_ADDRESS:
+               return &ctsvc_db_plugin_address;
+       case CTSVC_RECORD_MESSENGER:
+               return &ctsvc_db_plugin_messenger;
+       case CTSVC_RECORD_GROUP_RELATION:
+               return &ctsvc_db_plugin_grouprelation;
+       case CTSVC_RECORD_ACTIVITY:
+               return &ctsvc_db_plugin_activity;
+       case CTSVC_RECORD_ACTIVITY_PHOTO:
+               return &ctsvc_db_plugin_activity_photo;
+       case CTSVC_RECORD_PROFILE:
+               return &ctsvc_db_plugin_profile;
+       case CTSVC_RECORD_RELATIONSHIP:
+               return &ctsvc_db_plugin_relationship;
+       case CTSVC_RECORD_IMAGE:
+               return &ctsvc_db_plugin_image;
+       case CTSVC_RECORD_EXTENSION:
+               return &ctsvc_db_plugin_extension;
+#ifdef ENABLE_LOG_FEATURE
+       case CTSVC_RECORD_PHONELOG:
+               return &ctsvc_db_plugin_phonelog;
+#endif // ENABLE_LOG_FEATURE
+#ifdef ENABLE_SIM_FEATURE
+       case CTSVC_RECORD_SPEEDDIAL:
+               return &ctsvc_db_plugin_speeddial;
+       case CTSVC_RECORD_SDN:
+               return &ctsvc_db_plugin_sdn;
+#endif // ENABLE_SIM_FEATURE
+       case CTSVC_RECORD_UPDATED_INFO:
+       case CTSVC_RECORD_RESULT:
+       default:
+               return NULL;
+       }
+}
+
+#ifdef _CONTACTS_IPC_SERVER
+static int __ctsvc_db_create_views()
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       if( __ctsvc_db_view_already_created )
+               return CONTACTS_ERROR_NONE;
+
+       // CTSVC_DB_VIEW_CONTACT
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_CONTACT" AS "
+                       "SELECT * FROM "CTS_TABLE_CONTACTS" WHERE deleted = 0");
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_execs() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_MY_PROFILE
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_MY_PROFILE" AS "
+                       "SELECT * FROM "CTS_TABLE_MY_PROFILES" WHERE deleted = 0");
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_PERSON
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_PERSON" AS "
+                       "SELECT persons.person_id, "
+                                       "display_name, reverse_display_name, "
+                                       "display_name_language, "
+                                       "reverse_display_name_language, "
+                                       "sort_name, reverse_sort_name, "
+                                       "sortkey, reverse_sortkey, "
+                                       "name_contact_id, "
+                                       "persons.ringtone_path, "
+                                       "persons.image_thumbnail_path, "
+                                       "persons.vibration, "
+                                       "persons.message_alert, "
+                                       "status, "
+                                       "link_count, "
+                                       "addressbook_ids, "
+                                       "persons.has_phonenumber, "
+                                       "persons.has_email, "
+                                       "EXISTS(SELECT person_id FROM "CTS_TABLE_FAVORITES" WHERE person_id=persons.person_id) is_favorite, "
+                                       "(SELECT favorite_prio FROM "CTS_TABLE_FAVORITES" WHERE person_id=persons.person_id) favorite_prio "
+                       "FROM "CTS_TABLE_CONTACTS", "CTS_TABLE_PERSONS" "
+                       "ON (name_contact_id = contacts.contact_id) ");
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_NAME
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_NAME" AS "
+                       "SELECT id, "
+                               "data.contact_id, "
+                               "addressbook_id, "
+                               "data2, "
+                               "data3, "
+                               "data4, "
+                               "data5, "
+                               "data6, "
+                               "data7, "
+                               "data8, "
+                               "data9 "
+                       "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                       "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                       "WHERE datatype = %d AND is_my_profile = 0 ",
+                               CTSVC_DATA_NAME);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_NUMBER
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_NUMBER" AS "
+                       "SELECT id, "
+                                       "data.contact_id, "
+                                       "addressbook_id, "
+                                       "is_default, "
+                                       "data1, "
+                                       "data2, "
+                                       "data3, "
+                                       "data4, "
+                                       "data5, "
+                                       "data6 "
+                       "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                       "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                       "WHERE datatype = %d AND is_my_profile = 0 ",
+                               CTSVC_DATA_NUMBER);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_EMAIL
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_EMAIL" AS "
+                       "SELECT id, "
+                                       "data.contact_id, "
+                                       "addressbook_id, "
+                                       "is_default, "
+                                       "data1, "
+                                       "data2, "
+                                       "data3 "
+                       "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                       "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                       "WHERE datatype = %d AND is_my_profile = 0 ",
+                               CTSVC_DATA_EMAIL);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_ADDRESS
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_ADDRESS" AS "
+                       "SELECT id, "
+                                       "data.contact_id, "
+                                       "addressbook_id, "
+                                       "is_default, "
+                                       "data1, "
+                                       "data2, "
+                                       "data3, "
+                                       "data4, "
+                                       "data5, "
+                                       "data6, "
+                                       "data7, "
+                                       "data8, "
+                                       "data9 "
+                       "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                       "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                       "WHERE datatype = %d AND is_my_profile = 0 ",
+                               CTSVC_DATA_POSTAL);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_URL
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_URL" AS "
+                       "SELECT id, "
+                                       "data.contact_id, "
+                                       "addressbook_id, "
+                                       "data1, "
+                                       "data2, "
+                                       "data3 "
+                       "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                       "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                       "WHERE datatype = %d AND is_my_profile = 0 ",
+                               CTSVC_DATA_URL);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_EVENT
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_EVENT" AS "
+                       "SELECT id, "
+                                       "data.contact_id, "
+                                       "addressbook_id, "
+                                       "data1, "
+                                       "data2, "
+                                       "data3, "
+                                       "data4, "
+                                       "data5 "
+                       "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                       "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                       "WHERE datatype = %d AND is_my_profile = 0 ",
+                               CTSVC_DATA_EVENT);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_GROUP_RELATION
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_GROUP_RELATION" AS "
+                       "SELECT "CTS_TABLE_GROUP_RELATIONS".group_id, "
+                                       "contact_id, "
+                                       "addressbook_id, "
+                                       "group_name "
+                       "FROM "CTS_TABLE_GROUP_RELATIONS", "CTS_TABLE_GROUPS" "
+                       "ON "CTS_TABLE_GROUP_RELATIONS".group_id = "CTS_TABLE_GROUPS".group_id AND deleted = 0 "
+                       "ORDER BY group_prio");
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_RELATIONSHIP
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_RELATIONSHIP" AS "
+                       "SELECT id, "
+                                       "data.contact_id, "
+                                       "addressbook_id, "
+                                       "data1, "
+                                       "data2, "
+                                       "data3  "
+                       "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                       "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                       "WHERE datatype = %d AND is_my_profile = 0 ",
+                               CTSVC_DATA_RELATIONSHIP);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_IMAGE
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_IMAGE" AS "
+                       "SELECT id, "
+                                       "is_default, "
+                                       "data.contact_id, "
+                                       "addressbook_id, "
+                                       "data1, "
+                                       "data2, "
+                                       "data3 "
+                       "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                       "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                       "WHERE datatype = %d AND is_my_profile = 0 ",
+                               CTSVC_DATA_IMAGE);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_COMPANY
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_COMPANY" AS "
+                       "SELECT id, "
+                                       "data.contact_id, "
+                                       "addressbook_id, "
+                                       "data1, "
+                                       "data2, "
+                                       "data3, "
+                                       "data4, "
+                                       "data5, "
+                                       "data6, "
+                                       "data7, "
+                                       "data8, "
+                                       "data9, "
+                                       "data10, "
+                                       "data11 "
+                       "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                       "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                       "WHERE datatype = %d AND is_my_profile = 0 ",
+                               CTSVC_DATA_COMPANY);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_NICKNAME
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_NICKNAME" AS "
+                       "SELECT id, "
+                                       "data.contact_id, "
+                                       "addressbook_id, "
+                                       "data3 "
+                       "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                       "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                       "WHERE datatype = %d AND is_my_profile = 0 ",
+                               CTSVC_DATA_NICKNAME);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_MESSENGER
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_MESSENGER" AS "
+                       "SELECT id, "
+                                       "data.contact_id, "
+                                       "addressbook_id, "
+                                       "data1, "
+                                       "data2, "
+                                       "data3 "
+                       "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                       "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                       "WHERE datatype = %d AND is_my_profile = 0 ",
+                               CTSVC_DATA_MESSENGER);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_NOTE
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_NOTE" AS "
+                       "SELECT id, "
+                                       "data.contact_id, "
+                                       "addressbook_id, "
+                                       "data3 "
+                       "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                       "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                       "WHERE datatype = %d AND is_my_profile = 0 ",
+                               CTSVC_DATA_NOTE);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_PROFILE
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_PROFILE" AS "
+                       "SELECT id, "
+                                       "data.contact_id, "
+                                       "addressbook_id, "
+                                       "data1, "
+                                       "data2, "
+                                       "data3, "
+                                       "data4, "
+                                       "data5, "
+                                       "data6, "
+                                       "data7, "
+                                       "data8, "
+                                       "data9, "
+                                       "data10, "
+                                       "data11 "
+                       "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                       "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                       "WHERE datatype = %d AND is_my_profile = 0 ",
+                               CTSVC_DATA_PROFILE);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_EXTENSION
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_EXTENSION" AS "
+                       "SELECT id, "
+                                       "data.contact_id, "
+                                       "addressbook_id, "
+                                       "data1, "
+                                       "data2, "
+                                       "data3, "
+                                       "data4, "
+                                       "data5, "
+                                       "data6, "
+                                       "data7, "
+                                       "data8, "
+                                       "data9, "
+                                       "data10, "
+                                       "data11, "
+                                       "data12 "
+                       "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                       "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                       "WHERE datatype = %d AND is_my_profile = 0 ",
+                               CTSVC_DATA_EXTENSION);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_ACTIVITY
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_ACTIVITY" AS "
+                       "SELECT id, "
+                                       "activities.contact_id, "
+                                       "addressbook_id, "
+                                       "source_name, "
+                                       "status, "
+                                       "timestamp, "
+                                       "service_operation, "
+                                       "uri "
+                       "FROM "CTS_TABLE_ACTIVITIES", "CTSVC_DB_VIEW_CONTACT" "
+                       "ON "CTS_TABLE_ACTIVITIES".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                       "ORDER BY timestamp DESC");
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_ACTIVITY_PHOTOS
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_ACTIVITY_PHOTOS" AS "
+                       "SELECT "CTS_TABLE_ACTIVITY_PHOTOS".id, "
+                                       "activity_id, "
+                                       "photo_url, "
+                                       "sort_index "
+                       "FROM "CTS_TABLE_ACTIVITY_PHOTOS", "CTSVC_DB_VIEW_ACTIVITY" "
+                       "ON "CTS_TABLE_ACTIVITY_PHOTOS".activity_id = "CTSVC_DB_VIEW_ACTIVITY".id");
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+#ifdef ENABLE_SIM_FEATURE
+       // CTSVC_DB_VIEW_SPEEDIDAL
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_SPEEDIDAL" AS "
+                       "SELECT persons.person_id, "
+                                       "name_contacts.display_name, name_contacts.reverse_display_name, "
+                                       "name_contacts.display_name_language, "
+                                       "name_contacts.reverse_display_name_language, "
+                                       "name_contacts.sort_name, name_contacts.reverse_sort_name, "
+                                       "name_contacts.sortkey, name_contacts.reverse_sortkey, "
+                                       "persons.image_thumbnail_path, "
+                                       "data.id number_id, "
+                                       "data.data1 type, "
+                                       "data.data2 label, "
+                                       "data.data3 number, "
+                                       "data.data4 minmatch, "
+                                       "data.data5 normalized_number, "
+                                       "data.data6 cleaned_number, "
+                                       "speeddials.speed_number  "
+                       "FROM "CTS_TABLE_PERSONS", "CTS_TABLE_CONTACTS" AS name_contacts, "
+                                       CTSVC_DB_VIEW_CONTACT" AS temp_contacts, "
+                                       CTS_TABLE_DATA", "CTS_TABLE_SPEEDDIALS" "
+                       "ON (persons.name_contact_id = name_contacts.contact_id "
+                               "AND persons.person_id = temp_contacts.person_id "
+                               "AND temp_contacts.contact_id = data.contact_id "
+                               "AND data.id = speeddials.number_id) "
+                       "ORDER BY speeddials.speed_number");
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+#endif // ENABLE_SIM_FEATURE
+
+
+       // CTSVC_DB_VIEW_PERSON_CONTACT
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_PERSON_CONTACT" AS "
+                       "SELECT * FROM "CTSVC_DB_VIEW_PERSON" "
+                       "JOIN (SELECT contact_id, "
+                                               "addressbook_id, "
+                                               "person_id person_id_in_contact "
+                                       "FROM "CTSVC_DB_VIEW_CONTACT") temp_contacts "
+                       "JOIN (SELECT addressbook_id addressbook_id_in_addressbooks, addressbook_name, mode addressbook_mode "
+                                       "FROM "CTS_TABLE_ADDRESSBOOKS") temp_addressbooks "
+                       "ON temp_contacts.person_id_in_contact = "CTSVC_DB_VIEW_PERSON".person_id "
+                               "AND addressbook_id = temp_addressbooks.addressbook_id_in_addressbooks");
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_PERSON_NUMBER
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_PERSON_NUMBER" AS "
+                       "SELECT * FROM "CTSVC_DB_VIEW_PERSON_CONTACT" "
+                       "JOIN (SELECT id number_id, "
+                                                               "contact_id, "
+                                                               "data1 type, "
+                                                               "is_primary_default, "
+                                                               "data2 label, "
+                                                               "data3 number, "
+                                                               "data4 minmatch, "
+                                                               "data5 normalized_number, "
+                                                               "data6 cleaned_number "
+                                       "FROM "CTS_TABLE_DATA" WHERE datatype = %d AND is_my_profile = 0) temp_data "
+                       "ON temp_data.contact_id = "CTSVC_DB_VIEW_PERSON_CONTACT".contact_id",
+                               CTSVC_DATA_NUMBER);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_PERSON_EMAIL
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_PERSON_EMAIL" AS "
+                       "SELECT * FROM "CTSVC_DB_VIEW_PERSON_CONTACT" "
+                       "JOIN (SELECT id email_id, "
+                                                               "contact_id, "
+                                                               "data1 type, "
+                                                               "is_primary_default, "
+                                                               "data2 label, "
+                                                               "data3 email "
+                                       "FROM "CTS_TABLE_DATA" WHERE datatype = %d AND is_my_profile = 0) temp_data "
+                       "ON temp_data.contact_id = "CTSVC_DB_VIEW_PERSON_CONTACT".contact_id",
+                               CTSVC_DATA_EMAIL);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+#ifdef ENABLE_LOG_FEATURE
+       // CTSVC_DB_VIEW_PERSON_PHONELOG
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_PERSON_PHONELOG" AS "
+                       "SELECT L.id phonelog_id, "
+                                       "C.display_name, "
+                                       "C.reverse_display_name, "
+                                       "C.display_name_language, "
+                                       "C.reverse_display_name_language, "
+                                       "C.sort_name, C.reverse_sort_name, "
+                                       "C.sortkey, C.reverse_sortkey, "
+                                       "P.image_thumbnail_path, "
+                                       "L.number address, "
+                                       "L.normal_num, "
+                                       "L.minmatch, "
+                                       "L.clean_num, "
+                                       "L.log_type, "
+                                       "L.log_time, "
+                                       "L.data1, "
+                                       "L.data2, "
+                                       "L.sim_id, "
+                                       "L.person_id id, "
+                                       "L.number_type address_type "
+                       "FROM "CTS_TABLE_PHONELOGS" L "
+                                       "LEFT JOIN "CTS_TABLE_PERSONS" P "
+                                               "ON P.person_id = L.person_id "
+                                       "LEFT JOIN "CTS_TABLE_CONTACTS" C "
+                                               "ON P.name_contact_id = C.contact_id AND C.deleted = 0 "
+                       "ORDER BY L.log_time DESC");
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+#endif // ENABLE_LOG_FEATURE
+
+       // CTSVC_DB_VIEW_PERSON_USAGE
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_PERSON_USAGE" AS "
+                       "SELECT * FROM "CTSVC_DB_VIEW_PERSON" "
+                       "LEFT JOIN (SELECT usage_type, "
+                                                       "person_id, "
+                                                       "times_used "
+                                       "FROM "CTS_TABLE_CONTACT_STAT") usage "
+                       "ON usage.person_id = "CTSVC_DB_VIEW_PERSON".person_id "
+                       "ORDER BY usage.times_used");
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_PERSON_GROUP
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_PERSON_GROUP" AS "
+                       "SELECT view_person_contact.*, groups.group_id, group_prio "
+                               "FROM "CTSVC_DB_VIEW_PERSON_CONTACT" "
+                                       "LEFT JOIN "CTS_TABLE_GROUP_RELATIONS" "
+                                               "ON "CTS_TABLE_GROUP_RELATIONS".deleted = 0 AND "
+                                                       CTS_TABLE_GROUP_RELATIONS".contact_id = "CTSVC_DB_VIEW_PERSON_CONTACT".contact_id "
+                                       "LEFT JOIN "CTS_TABLE_GROUPS" "
+                                               "ON "CTS_TABLE_GROUP_RELATIONS".group_id = "CTS_TABLE_GROUPS".group_id "
+                                       "ORDER BY group_prio");
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_PERSON_GROUP_NOT_ASSIGNED
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_PERSON_GROUP_NOT_ASSIGNED" AS "
+                       "SELECT * FROM "CTSVC_DB_VIEW_PERSON_CONTACT" "
+                       "WHERE contact_id NOT IN (select contact_id FROM "CTS_TABLE_GROUP_RELATIONS" WHERE deleted = 0)");
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_PERSON_GROUP_ASSIGNED
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_PERSON_GROUP_ASSIGNED" AS "
+                       "SELECT "CTSVC_DB_VIEW_PERSON_CONTACT".*, groups.group_id, group_prio "
+                               "FROM "CTSVC_DB_VIEW_PERSON_CONTACT", "
+                                       CTS_TABLE_GROUP_RELATIONS", "CTS_TABLE_GROUPS" "
+                               "ON "
+                       CTS_TABLE_GROUP_RELATIONS".contact_id = "CTSVC_DB_VIEW_PERSON_CONTACT".contact_id AND "
+                       CTS_TABLE_GROUP_RELATIONS".group_id = "CTS_TABLE_GROUPS".group_id AND "
+                       CTS_TABLE_GROUP_RELATIONS".deleted = 0 "
+                       "ORDER BY group_prio");
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_CONTACT_NUMBER
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_CONTACT_NUMBER" AS "
+                       "SELECT * FROM "CTSVC_DB_VIEW_CONTACT" "
+                       "JOIN (SELECT id number_id, "
+                                                               "contact_id, "
+                                                               "data1 type, "
+                                                               "is_default, "
+                                                               "data2 label, "
+                                                               "data3 number, "
+                                                               "data4 minmatch, "
+                                                               "data5 normalized_number, "
+                                                               "data6 cleaned_number "
+                                       "FROM "CTS_TABLE_DATA" WHERE datatype = %d AND is_my_profile = 0) temp_data "
+                       "ON temp_data.contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id",
+                               CTSVC_DATA_NUMBER);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_CONTACT_EMAIL
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_CONTACT_EMAIL" AS "
+                       "SELECT * FROM "CTSVC_DB_VIEW_CONTACT" "
+                       "JOIN (SELECT id email_id, "
+                                                               "contact_id, "
+                                                               "data1 type, "
+                                                               "is_default, "
+                                                               "data2 label, "
+                                                               "data3 email "
+                                       "FROM "CTS_TABLE_DATA" WHERE datatype = %d AND is_my_profile = 0) temp_data "
+                       "ON temp_data.contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id",
+                               CTSVC_DATA_EMAIL);
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_CONTACT_GROUP
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_CONTACT_GROUP" AS "
+                       "SELECT C.*, groups.group_id, group_name "
+                               "FROM "CTSVC_DB_VIEW_CONTACT" C "
+                               "LEFT JOIN "CTS_TABLE_GROUP_RELATIONS" "
+                                       "ON "CTS_TABLE_GROUP_RELATIONS".deleted = 0 AND "
+                                                       CTS_TABLE_GROUP_RELATIONS".contact_id = C.contact_id "
+                               "LEFT JOIN "CTS_TABLE_GROUPS" "
+                                       "ON "CTS_TABLE_GROUP_RELATIONS".group_id = "CTS_TABLE_GROUPS".group_id");
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       // CTSVC_DB_VIEW_CONTACT_ACTIVITY
+       snprintf(query, sizeof(query),
+               "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_CONTACT_ACTIVITY" AS "
+                       "SELECT A.contact_id, "
+                                       "A.display_name, "
+                                       "A.display_name_source, "
+                                       "A.reverse_display_name, "
+                                       "A.display_name_language, "
+                                       "A.reverse_display_name_language, "
+                                       "A.sort_name, A.reverse_sort_name, "
+                                       "A.sortkey, A.reverse_sortkey, "
+                                       "A.addressbook_id, "
+                                       "AB.account_id, "
+                                       "A.person_id, "
+                                       "A.ringtone_path, "
+                                       "A.image_thumbnail_path, "
+                                       "AC.id activity_id, "
+                                       "AC.source_name, "
+                                       "AC.status, "
+                                       "AC.timestamp, "
+                                       "AC.service_operation, "
+                                       "AC.uri "
+                                       "FROM "CTSVC_DB_VIEW_CONTACT" A, "CTS_TABLE_ACTIVITIES" AC, "CTS_TABLE_ADDRESSBOOKS" AB "
+                       "ON A.contact_id = AC.contact_id "
+                       "AND A.addressbook_id = AB.addressbook_id "
+                       "ORDER BY timestamp DESC");
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       __ctsvc_db_view_already_created = true;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+#endif
+
+int ctsvc_db_init()
+{
+       int ret = CONTACTS_ERROR_NONE;
+       ret = ctsvc_db_open();
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_db_open() Failed(%d)", ret);
+               return ret;
+       }
+
+#ifdef _CONTACTS_IPC_SERVER
+       ret = __ctsvc_db_create_views();
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("__ctsvc_db_create_views() Failed(%d)", ret);
+               return ret;
+       }
+#endif
+
+       return ret;
+}
+
+int ctsvc_db_deinit()
+{
+       int ret = CONTACTS_ERROR_NONE;
+       ret = ctsvc_db_close();
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_db_close() Failed(%d)", ret);
+               return ret;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+
diff --git a/native/ctsvc_db_init.h b/native/ctsvc_db_init.h
new file mode 100644 (file)
index 0000000..7eb082e
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 __TIZEN_SOCIAL_CTSVC_DB_INIT_H__
+#define __TIZEN_SOCIAL_CTSVC_DB_INIT_H__
+
+#include "contacts.h"
+#include "ctsvc_struct.h"
+
+typedef int (*ctsvc_db_insert_record_cb)( contacts_record_h record, int *id );
+typedef int (*ctsvc_db_get_record_cb)( int id, contacts_record_h* out_record );
+typedef int (*ctsvc_db_update_record_cb)( contacts_record_h record );
+typedef int (*ctsvc_db_delete_record_cb)( int id );
+typedef int (*ctsvc_db_replace_record_cb)( contacts_record_h record, int id );
+
+typedef int (*ctsvc_db_insert_records_cb)(const contacts_list_h in_list, int **ids);
+typedef int (*ctsvc_db_update_records_cb)(const contacts_list_h in_list);
+typedef int (*ctsvc_db_delete_records_cb)(int ids[], int count);
+typedef int (*ctsvc_db_replace_records_cb)(const contacts_list_h in_list, int ids[], int count);
+
+typedef int (*ctsvc_db_get_all_records_cb)( int offset, int limit, contacts_list_h* out_list );
+typedef int (*ctsvc_db_get_records_with_query_cb)( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+typedef int (*ctsvc_db_get_count_cb)( int *out_count);
+typedef int (*ctsvc_db_get_count_with_query_cb)( contacts_query_h query, int *out_count);
+
+typedef struct {
+    bool is_query_only;
+    ctsvc_db_insert_record_cb insert_record;
+    ctsvc_db_get_record_cb get_record;
+    ctsvc_db_update_record_cb update_record;
+    ctsvc_db_delete_record_cb delete_record;
+    ctsvc_db_replace_record_cb replace_record;
+    ctsvc_db_get_all_records_cb get_all_records;
+    ctsvc_db_get_records_with_query_cb get_records_with_query;
+    ctsvc_db_insert_records_cb insert_records;
+    ctsvc_db_update_records_cb update_records;
+    ctsvc_db_delete_records_cb delete_records;
+    ctsvc_db_replace_records_cb replace_records;
+    ctsvc_db_get_count_cb get_count;
+    ctsvc_db_get_count_with_query_cb get_count_with_query;
+} ctsvc_db_plugin_info_s;
+
+int ctsvc_db_init();
+int ctsvc_db_deinit();
+
+int ctsvc_db_plugin_init();
+int ctsvc_db_plugin_deinit();
+
+int ctsvc_db_get_table_name(const char *view_uri, const char **out_table);
+ctsvc_db_plugin_info_s* ctsvc_db_get_plugin_info(ctsvc_record_type_e type);
+
+int ctsvc_required_read_permission(const char *view_uri);
+int ctsvc_required_write_permission(const char *view_uri);
+
+bool ctsvc_should_ab_access_control(const char *view_uri);
+
+#endif // __TIZEN_SOCIAL_CTSVC_DB_INIT_H__
diff --git a/native/ctsvc_db_plugin_activity.c b/native/ctsvc_db_plugin_activity.c
new file mode 100644 (file)
index 0000000..22048d2
--- /dev/null
@@ -0,0 +1,448 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_list.h"
+#include "ctsvc_db_plugin_activity_photo_helper.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_record.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_access_control.h"
+
+static int __ctsvc_db_activity_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_activity_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_activity_update_record( contacts_record_h record );
+static int __ctsvc_db_activity_delete_record( int id );
+static int __ctsvc_db_activity_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_activity_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_activity_insert_records(const contacts_list_h in_list, int **ds);
+//static int __ctsvc_db_activity_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_activity_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_activity = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_activity_insert_record,
+       .get_record = __ctsvc_db_activity_get_record,
+       .update_record = __ctsvc_db_activity_update_record,
+       .delete_record = __ctsvc_db_activity_delete_record,
+       .get_all_records = __ctsvc_db_activity_get_all_records,
+       .get_records_with_query = __ctsvc_db_activity_get_records_with_query,
+       .insert_records = NULL, //__ctsvc_db_activity_insert_records,
+       .update_records = NULL, //__ctsvc_db_activity_update_records,
+       .delete_records = NULL, //__ctsvc_db_activity_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_activity_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int activity_id;
+       int addressbook_id;
+       cts_stmt stmt = NULL;
+       int count = 0;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_activity_s *activity = (ctsvc_activity_s *)record;
+
+       RETV_IF(NULL == activity, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETVM_IF(activity->id, CONTACTS_ERROR_INVALID_PARAMETER,
+               "The activity has ID(%d)", activity->id);
+
+       RETVM_IF(activity->contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+               "The contact_id(%d) does not exist", activity->contact_id);
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id from %s WHERE contact_id = %d",
+                               CTSVC_DB_VIEW_CONTACT, activity->contact_id);
+
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret ) {
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       CTS_ERR("No data : contact id (%d)", activity->contact_id);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               else {
+                       CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+                       return ret;
+               }
+       }
+
+       ret = ctsvc_is_owner(addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               if (CONTACTS_ERROR_PERMISSION_DENIED == ret)
+                       CTS_ERR("Does not have permission of address_book (%d)", addressbook_id);
+               else
+                       CTS_ERR("ctsvc_is_owner Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query), "INSERT INTO "CTS_TABLE_ACTIVITIES"("
+                       "contact_id, source_name, status, timestamp, "
+                       "service_operation, uri) "
+                       "VALUES(%d, ?, ?, %d, ?, ?)",
+                       activity->contact_id, activity->timestamp);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed9(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (activity->source_name)
+               ctsvc_stmt_bind_text(stmt, 1, activity->source_name);
+       if (activity->status)
+               ctsvc_stmt_bind_text(stmt, 2, activity->status);
+       if (activity->service_operation)
+               ctsvc_stmt_bind_text(stmt, 3, activity->service_operation);
+       if (activity->uri)
+               ctsvc_stmt_bind_text(stmt, 4, activity->uri);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       activity_id = ctsvc_db_get_last_insert_id();
+
+       ctsvc_stmt_finalize(stmt);
+
+       if (activity->photos) {
+               ret = contacts_list_get_count((contacts_list_h)activity->photos, &count);
+               if(CONTACTS_ERROR_NONE == ret && 0 < count) {
+                       ctsvc_activity_photo_s *photo = NULL;
+                       contacts_record_h record = NULL;
+
+                       contacts_list_first((contacts_list_h)activity->photos);
+                       do {
+                               contacts_list_get_current_record_p((contacts_list_h)activity->photos, &record);
+                               photo = (ctsvc_activity_photo_s*)record;
+                               ret = ctsvc_db_activity_photo_insert((contacts_record_h)photo, activity_id, NULL);
+                               if (CONTACTS_ERROR_DB == ret){
+                                       CTS_ERR("DB error : return (%d)", ret);
+                                       break;
+                               }
+                       }while(CONTACTS_ERROR_NONE == contacts_list_next((contacts_list_h)activity->photos));
+               }
+       }
+
+       ctsvc_set_activity_noti();
+       ctsvc_set_person_noti();
+
+       if (id)
+               *id = activity_id;
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+               return ret;
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_activity_value_set(cts_stmt stmt, contacts_record_h *record)
+{
+       int i = 0;
+       char *temp;
+       ctsvc_activity_s *activity;
+
+       contacts_record_create(_contacts_activity._uri, record);
+       activity = (ctsvc_activity_s*)*record;
+
+       activity->id = ctsvc_stmt_get_int(stmt, i++);
+       activity->contact_id = ctsvc_stmt_get_int(stmt, i++);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       activity->source_name = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       activity->status = SAFE_STRDUP(temp);
+       activity->timestamp = ctsvc_stmt_get_int(stmt, i++);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       activity->service_operation = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       activity->uri = SAFE_STRDUP(temp);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+
+static int __ctsvc_db_activity_get_record( int id, contacts_record_h* out_record )
+{
+       char query[CTS_SQL_MAX_LEN] = {0};
+       int ret;
+       cts_stmt stmt = NULL;
+       contacts_record_h record;
+
+       snprintf(query, sizeof(query), "SELECT id, contact_id, source_name, status, "
+                                       "timestamp, service_operation, uri "
+                                       "FROM "CTSVC_DB_VIEW_ACTIVITY" WHERE id = %d", id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       __ctsvc_db_activity_value_set(stmt, &record);
+       ctsvc_stmt_finalize(stmt);
+
+       ctsvc_db_activity_photo_get_records(id, record);
+
+       *out_record = (contacts_record_h)record;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_activity_update_record( contacts_record_h record )
+{
+       CTS_ERR("Invalid operation : activity can not update, only insert/delete");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_db_activity_delete_record( int id )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" "
+                               "WHERE contact_id = (SELECT contact_id FROM "CTSVC_DB_VIEW_ACTIVITY" WHERE id = %d)", id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret ) {
+               CTS_ERR("No data : id (%d)", id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_is_owner(addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               if (CONTACTS_ERROR_PERMISSION_DENIED == ret)
+                       CTS_ERR("Does not have permission of address_book (%d)", addressbook_id);
+               else
+                       CTS_ERR("ctsvc_is_owner Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "DELETE FROM "CTS_TABLE_ACTIVITIES" WHERE id = %d", id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_set_activity_noti();
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+               return ret;
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_activity_get_all_records( int offset, int limit,
+       contacts_list_h* out_list )
+{
+       int ret;
+       int len;
+       int activity_id;
+       cts_stmt stmt;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_list_h list;
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTSVC_DB_VIEW_ACTIVITY);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               activity_id = ctsvc_stmt_get_int(stmt, 0);
+               ret = contacts_db_get_record(_contacts_activity._uri, activity_id, &record);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : contacts_db_get_record() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_activity_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       int activity_id = 0;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_activity_s *activity;
+       bool had_activity_id = false;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       if (s_query->projection) {
+               for (i=0;i<s_query->projection_count;i++) {
+                       if (s_query->projection[i] == CTSVC_PROPERTY_ACTIVITY_ID) {
+                               had_activity_id = true;
+                               break;
+                       }
+               }
+       }
+       else
+               had_activity_id = true;
+
+       if (!had_activity_id) {
+               unsigned int *temp = realloc(s_query->projection, s_query->projection_count+1);
+               RETVM_IF(NULL == temp, CONTACTS_ERROR_OUT_OF_MEMORY, "realloc() return NULL");
+               s_query->projection = temp;
+               s_query->projection[s_query->projection_count] = CTSVC_PROPERTY_ACTIVITY_ID;
+               s_query->projection_count++;
+       }
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_activity._uri, &record);
+               activity = (ctsvc_activity_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if(CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_ACTIVITY_ID:
+                               activity_id = ctsvc_stmt_get_int(stmt, i);
+                               if (had_activity_id)
+                                       activity->id = activity_id;
+                               break;
+                       case CTSVC_PROPERTY_ACTIVITY_CONTACT_ID:
+                               activity->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_ACTIVITY_SOURCE_NAME:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               activity->source_name = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_ACTIVITY_STATUS:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               activity->status = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_ACTIVITY_TIMESTAMP:
+                               activity->timestamp = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_ACTIVITY_SERVICE_OPERATION:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               activity->service_operation = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_ACTIVITY_URI:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               activity->uri = SAFE_STRDUP(temp);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_db_activity_photo_get_records(activity_id, record);
+
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+//static int __ctsvc_db_activity_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_activity_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_activity_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_activity_photo.c b/native/ctsvc_db_plugin_activity_photo.c
new file mode 100644 (file)
index 0000000..a25c77e
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_activity_photo_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_list.h"
+
+static int __ctsvc_db_activity_photo_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_activity_photo_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_activity_photo_update_record( contacts_record_h record );
+static int __ctsvc_db_activity_photo_delete_record( int id );
+static int __ctsvc_db_activity_photo_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_activity_photo_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_activity_photo = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_activity_photo_insert_record,
+       .get_record = __ctsvc_db_activity_photo_get_record,
+       .update_record = __ctsvc_db_activity_photo_update_record,
+       .delete_record = __ctsvc_db_activity_photo_delete_record,
+       .get_all_records = __ctsvc_db_activity_photo_get_all_records,
+       .get_records_with_query = __ctsvc_db_activity_photo_get_records_with_query,
+       .insert_records = NULL,
+       .update_records = NULL,
+       .delete_records = NULL,
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_activity_photo_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_activity_photo_s *activity_photo = (ctsvc_activity_photo_s *)record;
+
+       RETVM_IF(NULL == activity_photo->photo_url, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : photo_url is NULL");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id from "CTSVC_DB_VIEW_CONTACT" "
+                       "WHERE contact_id = (SELECT contact_id from "CTS_TABLE_ACTIVITIES" WHERE id = %d)", activity_photo->activity_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       CTS_ERR("No data : activity_id (%d) is not exist", activity_photo->activity_id);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               else {
+                       CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to insert this activity_photo record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_activity_photo_insert(record, activity_photo->activity_id, id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_activity_photo_insert() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_end_trans(true);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "DB error : ctsvc_end_trans() Failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_activity_photo_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT id, activity_id, photo_url, sort_index "
+                       "FROM "CTSVC_DB_VIEW_ACTIVITY_PHOTOS" "
+                       "WHERE id = %d",
+                       id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ctsvc_db_activity_photo_get_value_from_stmt(stmt, out_record);
+
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_activity_photo_update_record( contacts_record_h record )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_activity_photo_s *activity_photo = (ctsvc_activity_photo_s *)record;
+
+       RETVM_IF(NULL == activity_photo->photo_url, CONTACTS_ERROR_INVALID_PARAMETER, "photo_url is empty");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id from "CTSVC_DB_VIEW_CONTACT" "
+                       "WHERE contact_id = (SELECT contact_id from "CTS_TABLE_ACTIVITIES" WHERE id = %d)",
+                       activity_photo->activity_id);
+
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : activity_id (%d) is not exist", activity_photo->activity_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this activity_photo record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_activity_photo_update(record);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("Update record Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_end_trans(true);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "DB error : ctsvc_end_trans() Failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_activity_photo_delete_record( int id )
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       int addressbook_id;
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT C.addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" C, "CTSVC_DB_VIEW_ACTIVITY" A, "CTSVC_DB_VIEW_ACTIVITY_PHOTOS" P "
+                       "ON C.contact_id = A.contact_id AND A.id = P.activity_id "
+                       "WHERE P.id = %d", id);
+
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : id (%d) is not exist", id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this activity_photo record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_activity_photo_delete(id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_activity_photo_delete() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_end_trans(true);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "DB error : ctsvc_end_trans() Failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_activity_photo_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int len;
+       int ret;
+       contacts_list_h list;
+       ctsvc_activity_photo_s *activity_photo;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT P.id, P.activity_id, P.photo_url, P.sort_index "
+                               "FROM "CTSVC_DB_VIEW_CONTACT" C, "CTSVC_DB_VIEW_ACTIVITY" A, "CTSVC_DB_VIEW_ACTIVITY_PHOTOS" P "
+                               "ON C.contact_id = A.contact_id AND A.id = P.activity_id ");
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB : ctsvc_stmt_step fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_db_activity_photo_get_value_from_stmt(stmt, (contacts_record_h*)&activity_photo);
+               ctsvc_list_prepend(list, (contacts_record_h)activity_photo);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_activity_photo_get_records_with_query(contacts_query_h query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_activity_photo_s *activity_photo;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_activity_photo._uri, &record);
+               activity_photo = (ctsvc_activity_photo_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if(CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_ACTIVITY_PHOTO_ID:
+                               activity_photo->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_ACTIVITY_PHOTO_ACTIVITY_ID:
+                               activity_photo->activity_id= ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_ACTIVITY_PHOTO_URL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               activity_photo->photo_url = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_ACTIVITY_PHOTO_SORT_INDEX:
+                               activity_photo->sort_index= ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/native/ctsvc_db_plugin_activity_photo_helper.c b/native/ctsvc_db_plugin_activity_photo_helper.c
new file mode 100644 (file)
index 0000000..2778c84
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_plugin_activity_photo_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_list.h"
+#include "ctsvc_notification.h"
+
+
+int ctsvc_db_activity_photo_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record)
+{
+       int ret;
+       char *temp;
+       ctsvc_activity_photo_s *activity_photo;
+       int start_count = 0;
+
+       ret = contacts_record_create(_contacts_activity_photo._uri, (contacts_record_h *)&activity_photo);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+
+       activity_photo->id = ctsvc_stmt_get_int(stmt, start_count++);
+       activity_photo->activity_id = ctsvc_stmt_get_int(stmt, start_count++);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       activity_photo->photo_url = SAFE_STRDUP(temp);
+       activity_photo->sort_index = ctsvc_stmt_get_int(stmt, start_count++);
+
+       *record = (contacts_record_h)activity_photo;
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_activity_photo_insert(contacts_record_h record, int activity_id, int *id)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       ctsvc_activity_photo_s *activity_photo =(ctsvc_activity_photo_s*)record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(activity_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : activity_id(%d) is mandatory field to insert activity_photo record ", activity_id);
+
+       RETVM_IF(0 < activity_photo->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : id(%d), This record is already inserted", activity_photo->id);
+
+       RETVM_IF(NULL == activity_photo->photo_url, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : activity_photo->photo_url is NULL");
+
+       snprintf(query, sizeof(query),
+               "INSERT INTO "CTS_TABLE_ACTIVITY_PHOTOS"(activity_id, photo_url, sort_index) "
+                                       "VALUES(%d, ?, %d)",
+                       activity_id, activity_photo->sort_index);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       sqlite3_bind_text(stmt, 1, activity_photo->photo_url, strlen(activity_photo->photo_url), SQLITE_STATIC);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+       if (id)
+               *id = ctsvc_db_get_last_insert_id();
+       ctsvc_stmt_finalize(stmt);
+
+       ctsvc_set_activity_noti();
+       ctsvc_set_activity_photo_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_activity_photo_update(contacts_record_h record)
+{
+       int id;
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       ctsvc_activity_photo_s *activity_photo = (ctsvc_activity_photo_s*)record;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       RETVM_IF(!activity_photo->id, CONTACTS_ERROR_INVALID_PARAMETER, "activity_photo has no ID.");
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (activity_photo->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_ACTIVITY_PHOTOS" WHERE id = %d", activity_photo->id);
+
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       RETV_IF(ret != CONTACTS_ERROR_NONE, ret);
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_ACTIVITY_PHOTOS, activity_photo->id))) break;
+               ctsvc_set_activity_noti();
+               ctsvc_set_activity_photo_noti();
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       return ret;
+}
+
+int ctsvc_db_activity_photo_delete(int id)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_ACTIVITY_PHOTOS" WHERE id = %d", id);
+
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_exec() Failed(%d)", ret);
+
+       ctsvc_set_activity_noti();
+       ctsvc_set_activity_photo_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
+
+int ctsvc_db_activity_photo_get_records(int activity_id, contacts_record_h record_activity)
+{
+       char query[CTS_SQL_MAX_LEN] = {0};
+       int ret;
+       cts_stmt stmt = NULL;
+       contacts_list_h list;
+
+       snprintf(query, sizeof(query), "SELECT activity_id, activity_id, photo_url, sort_index "
+                                               "FROM "CTSVC_DB_VIEW_ACTIVITY_PHOTOS" WHERE activity_id = %d "
+                                               "ORDER BY sort_index ASC", activity_id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               contacts_record_h record = NULL;
+               ctsvc_db_activity_photo_get_value_from_stmt(stmt, &record);
+               ctsvc_list_prepend(list, record);
+       }
+
+       ctsvc_stmt_finalize(stmt);
+
+       ((ctsvc_activity_s*)record_activity)->photos = (ctsvc_list_s*)list;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+
+
+
diff --git a/native/ctsvc_db_plugin_activity_photo_helper.h b/native/ctsvc_db_plugin_activity_photo_helper.h
new file mode 100644 (file)
index 0000000..e65515c
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_ACTIVITY_PHOTO_HELPER_H__
+#define __CTSVC_DB_PLUGIN_ACTIVITY_PHOTO_HELPER_H__
+
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
+
+int ctsvc_db_activity_photo_insert(contacts_record_h record, int activity_id, int *id);
+int ctsvc_db_activity_photo_update(contacts_record_h record);
+int ctsvc_db_activity_photo_delete(int id);
+int ctsvc_db_activity_photo_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record);
+int ctsvc_db_activity_photo_get_records(int activity_id, contacts_record_h record_activity);
+
+#endif // __CTSVC_DB_PLUGIN_ACTIVITY_PHOTO_HELPER_H__
\ No newline at end of file
diff --git a/native/ctsvc_db_plugin_address.c b/native/ctsvc_db_plugin_address.c
new file mode 100644 (file)
index 0000000..036a17b
--- /dev/null
@@ -0,0 +1,427 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_db_plugin_address_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_list.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_access_control.h"
+
+static int __ctsvc_db_address_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_address_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_address_update_record( contacts_record_h record );
+static int __ctsvc_db_address_delete_record( int id );
+static int __ctsvc_db_address_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_address_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_address_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_address_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_address_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_address = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_address_insert_record,
+       .get_record = __ctsvc_db_address_get_record,
+       .update_record = __ctsvc_db_address_update_record,
+       .delete_record = __ctsvc_db_address_delete_record,
+       .get_all_records = __ctsvc_db_address_get_all_records,
+       .get_records_with_query = __ctsvc_db_address_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_address_insert_records,
+       .update_records = NULL,//__ctsvc_db_address_update_records,
+       .delete_records = NULL,//__ctsvc_db_address_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_address_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_address_s *address = (ctsvc_address_s*)record;
+
+       RETVM_IF(NULL == address->pobox && NULL == address->postalcode && NULL == address->region
+               && NULL == address->locality && NULL == address->street && NULL == address->extended
+               && NULL == address->country,
+               CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : address is NULL");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", address->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       CTS_ERR("No data : contact_id (%d) is not exist", address->contact_id);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               else {
+                       CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this address record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_address_insert(record, address->contact_id, false, id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(address->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+               return ret;
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_address_update_record( contacts_record_h record )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_address_s *address = (ctsvc_address_s*)record;
+
+       RETVM_IF(NULL == address->pobox && NULL == address->postalcode && NULL == address->region &&
+                       NULL == address->locality && NULL == address->street && NULL == address->extended &&
+                       NULL == address->country, CONTACTS_ERROR_INVALID_PARAMETER, "address is empty");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", address->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : contact_id (%d) is not exist", address->contact_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this address record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_address_update(record, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("update record failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(address->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+               return ret;
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_address_delete_record( int id )
+{
+       int ret;
+       int contact_id;
+       cts_stmt stmt = NULL;
+       int addressbook_id;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" "
+                               "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error :ctsvc_query_prepare Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("The id(%d) is Invalid(%d)", id, ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       contact_id = ctsvc_stmt_get_int(stmt, 0);
+       addressbook_id = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this address record : addresbook_id(%d)", addressbook_id);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_address_delete(id, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_address_delete() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+
+       if (ret < CONTACTS_ERROR_NONE)
+               return ret;
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_address_get_record( int id, contacts_record_h* out_record )
+{
+       char query[CTS_SQL_MAX_LEN] = {0};
+       int ret;
+       cts_stmt stmt = NULL;
+       ctsvc_address_s *address;
+
+       snprintf(query, sizeof(query),
+                               "SELECT id, data.contact_id, is_default, "
+                                               "data1, data2, data3, data4, data5, data6, data7, data8, data9 "
+                                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                                               "WHERE datatype=%d AND id = %d ",
+                                               CTSVC_DATA_POSTAL, id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/  != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ctsvc_db_address_get_value_from_stmt(stmt, (contacts_record_h*)&address, 0);
+       ctsvc_stmt_finalize(stmt);
+
+       *out_record = (contacts_record_h)address;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_address_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int len;
+       int ret;
+       contacts_list_h list;
+       ctsvc_address_s *address;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT data.contact_id, is_default, "
+                                               "data1, data2, data3, data4, data5, data6, data7, data8, data9 "
+                                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                                               "WHERE datatype=%d AND is_my_profile=0 ",
+                                               CTSVC_DATA_POSTAL);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_db_address_get_value_from_stmt(stmt, (contacts_record_h*)&address, 0);
+               ctsvc_list_prepend(list, (contacts_record_h)address);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_address_get_records_with_query( contacts_query_h query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_address_s *address;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_address._uri, &record);
+               address = (ctsvc_address_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if(CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_ADDRESS_ID:
+                               address->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_ADDRESS_CONTACT_ID:
+                               address->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_ADDRESS_TYPE:
+                               address->type = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_ADDRESS_IS_DEFAULT:
+                               address->is_default = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_ADDRESS_LABEL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               address->label = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_ADDRESS_POSTBOX:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               address->pobox = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_ADDRESS_POSTAL_CODE:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               address->postalcode = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_ADDRESS_REGION:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               address->region = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_ADDRESS_LOCALITY:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               address->locality = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_ADDRESS_STREET:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               address->street = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_ADDRESS_COUNTRY:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               address->country = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_ADDRESS_EXTENDED:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               address->extended = SAFE_STRDUP(temp);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_address_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_address_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_address_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_address_helper.c b/native/ctsvc_db_plugin_address_helper.c
new file mode 100644 (file)
index 0000000..e8079f8
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_plugin_address_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+
+int ctsvc_db_address_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count)
+{
+       int ret;
+       char *temp;
+       ctsvc_address_s *address;
+
+       ret = contacts_record_create(_contacts_address._uri, (contacts_record_h *)&address);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+
+       address->id = ctsvc_stmt_get_int(stmt, start_count++);
+       address->contact_id = ctsvc_stmt_get_int(stmt, start_count++);
+       address->is_default = ctsvc_stmt_get_int(stmt, start_count++);
+       address->type = ctsvc_stmt_get_int(stmt, start_count++);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       address->label = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       address->pobox = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       address->postalcode = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       address->region = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       address->locality = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       address->street = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       address->extended = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       address->country = SAFE_STRDUP(temp);
+
+       *record = (contacts_record_h)address;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_address_reset_default(int address_id, int contact_id)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_DATA" SET is_default = 0, is_primary_default = 0 "
+                                       "WHERE id != %d AND contact_id = %d AND datatype = %d",
+                       address_id, contact_id, CTSVC_DATA_POSTAL);
+       ret = ctsvc_query_exec(query);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Failed(%d)", ret);
+       return ret;
+}
+
+int ctsvc_db_address_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id)
+{
+       int ret;
+       int address_id;
+       cts_stmt stmt = NULL;
+       ctsvc_address_s *address = (ctsvc_address_s*)record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : contact_id(%d) is mandatory field to insert address record ", address->contact_id);
+       RETVM_IF(0 < address->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", address->id);
+
+       if (address->pobox || address->postalcode || address->region || address->locality
+               || address->street || address->extended || address->country) {
+               snprintf(query, sizeof(query),
+                       "INSERT INTO "CTS_TABLE_DATA"(contact_id, is_my_profile, datatype, is_default, data1, data2, data3, "
+                                               "data4, data5, data6, data7, data8, data9) "
+                                               "VALUES(%d, %d, %d, %d, %d, ?, ?, ?, ?, ?, ?, ?, ?)",
+                               contact_id, is_my_profile, CTSVC_DATA_POSTAL, address->is_default, address->type);
+
+               ret = ctsvc_query_prepare(query, &stmt);
+               RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+               if (address->label)
+                       ctsvc_stmt_bind_text(stmt, 1, address->label);
+               if (address->pobox)
+                       ctsvc_stmt_bind_text(stmt, 2, address->pobox);
+               if (address->postalcode)
+                       ctsvc_stmt_bind_text(stmt, 3, address->postalcode);
+               if (address->region)
+                       ctsvc_stmt_bind_text(stmt, 4, address->region);
+               if (address->locality)
+                       ctsvc_stmt_bind_text(stmt, 5, address->locality);
+               if (address->street)
+                       ctsvc_stmt_bind_text(stmt, 6, address->street);
+               if (address->extended)
+                       ctsvc_stmt_bind_text(stmt, 7, address->extended);
+               if (address->country)
+                       ctsvc_stmt_bind_text(stmt, 8, address->country);
+
+               ret = ctsvc_stmt_step(stmt);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       return ret;
+               }
+               address_id = ctsvc_db_get_last_insert_id();
+               if (id)
+                       *id = address_id;
+               ctsvc_stmt_finalize(stmt);
+
+               if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_address.is_default, CTSVC_PROPERTY_FLAG_DIRTY)) {
+                       if (address->is_default)
+                               __ctsvc_db_address_reset_default(address_id, contact_id);
+               }
+
+               if (!is_my_profile)
+                       ctsvc_set_address_noti();
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_address_update(contacts_record_h record, bool is_my_profile)
+{
+       int id;
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       ctsvc_address_s *address = (ctsvc_address_s*)record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(address->id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", address->id);
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (address->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+       RETVM_IF(NULL == address->pobox && NULL == address->postalcode && address->region
+                       && address->locality && address->street && address->extended && address->country,
+                       CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : address is NULL");
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE id = %d", address->id);
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       RETV_IF(ret != CONTACTS_ERROR_NONE, ret);
+
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_address.is_default, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               if (address->is_default)
+                       __ctsvc_db_address_reset_default(address->id, address->contact_id);
+       }
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_DATA, address->id))) break;
+               if (!is_my_profile)
+                       ctsvc_set_address_noti();
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       return ret;
+}
+
+int ctsvc_db_address_delete(int id, bool is_my_profile)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE datatype = %d AND id = %d",
+                       CTSVC_DATA_POSTAL, id);
+
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Fail(%d)", ret);
+
+       if (!is_my_profile)
+               ctsvc_set_address_noti();
+
+       return ret;
+}
diff --git a/native/ctsvc_db_plugin_address_helper.h b/native/ctsvc_db_plugin_address_helper.h
new file mode 100644 (file)
index 0000000..263e972
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_ADDRESS_HELPER_H__
+#define __CTSVC_DB_PLUGIN_ADDRESS_HELPER_H__
+
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
+
+int ctsvc_db_address_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id);
+int ctsvc_db_address_update(contacts_record_h record, bool is_my_profile);
+int ctsvc_db_address_delete(int id, bool is_my_profile);
+int ctsvc_db_address_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count);
+
+#endif // __CTSVC_DB_PLUGIN_ADDRESS_HELPER_H__
diff --git a/native/ctsvc_db_plugin_addressbook.c b/native/ctsvc_db_plugin_addressbook.c
new file mode 100644 (file)
index 0000000..032be09
--- /dev/null
@@ -0,0 +1,527 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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.
+ *
+ */
+#ifdef CTS_MOBILE
+#include <account.h>
+#endif // CTS_MOBILE
+
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_list.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_plugin_person_helper.h"
+#include "ctsvc_person.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_addressbook_helper.h"
+
+static int __ctsvc_db_addressbook_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_addressbook_get_record( int id, contacts_record_h* record );
+static int __ctsvc_db_addressbook_update_record( contacts_record_h record );
+static int __ctsvc_db_addressbook_delete_record( int id );
+static int __ctsvc_db_addressbook_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_addressbook_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_addressbook_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_addressbook_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_addressbook_delete_records(int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_addressbook = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_addressbook_insert_record,
+       .get_record = __ctsvc_db_addressbook_get_record,
+       .update_record = __ctsvc_db_addressbook_update_record,
+       .delete_record = __ctsvc_db_addressbook_delete_record,
+       .get_all_records = __ctsvc_db_addressbook_get_all_records,
+       .get_records_with_query = __ctsvc_db_addressbook_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_addressbook_insert_records,
+       .update_records = NULL,//__ctsvc_db_addressbook_update_records,
+       .delete_records = NULL,//__ctsvc_db_addressbook_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_addressbook_value_set(cts_stmt stmt, contacts_record_h *record)
+{
+       int i;
+       int ret;
+       char *temp;
+       ctsvc_addressbook_s *addressbook;
+
+       ret = contacts_record_create(_contacts_address_book._uri, record);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+       addressbook = (ctsvc_addressbook_s*)*record;
+
+       i = 0;
+       addressbook->id = ctsvc_stmt_get_int(stmt, i++);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       addressbook->name = SAFE_STRDUP(temp);
+       addressbook->account_id = ctsvc_stmt_get_int(stmt, i++);
+       addressbook->mode = ctsvc_stmt_get_int(stmt, i++);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_addressbook_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_record_h record;
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                               "SELECT addressbook_id, addressbook_name, account_id, mode, last_sync_ver "
+                               "FROM "CTS_TABLE_ADDRESSBOOKS" WHERE addressbook_id = %d", id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ret = __ctsvc_db_addressbook_value_set(stmt, &record);
+
+       ctsvc_stmt_finalize(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_db_addressbook_value_set(ALL) Failed(%d)", ret);
+               return ret;
+       }
+
+       *out_record = record;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+
+static int __ctsvc_db_addressbook_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       char *smack = NULL;
+       ctsvc_addressbook_s *addressbook = (ctsvc_addressbook_s*)record;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == addressbook->name, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETVM_IF(CTSVC_RECORD_ADDRESSBOOK != addressbook->base.r_type, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : record is invalid type(%d)", addressbook->base.r_type);
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret);
+
+       // Can not insert addressbook which has same account_id
+       int addresbook_id;
+       snprintf(query, sizeof(query),
+               "SELECT addressbook_id FROM "CTS_TABLE_ADDRESSBOOKS" WHERE account_id = %d",
+               addressbook->account_id);
+       ret = ctsvc_query_get_first_int_result(query, &addresbook_id);
+       if (CONTACTS_ERROR_NO_DATA != ret) {
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       CTS_ERR("One addressbook which has account_id(%d) already exists", addressbook->account_id);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               else {
+                       CTS_ERR("DB error : ctsvc_query_get_first_int_result() Failed (%d)", ret);
+                       return ret;
+               }
+       }
+#ifdef CTS_MOBILE
+       account_h account = NULL;
+       ret = account_connect();
+       if (ACCOUNT_ERROR_NONE != ret) {
+               CTS_ERR("account_connect Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+       // check account_id validation
+       ret = account_create(&account);
+       if (ACCOUNT_ERROR_NONE != ret) {
+               CTS_ERR("account_create() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               account_disconnect();
+               return CONTACTS_ERROR_SYSTEM;
+       }
+       ret = account_query_account_by_account_id(addressbook->account_id, &account);
+       if (ACCOUNT_ERROR_NONE != ret) {
+               CTS_ERR("account_query_account_by_account_id Faild(%d) : account_id(%d)", ret, addressbook->account_id);
+               ret = account_destroy(account);
+               WARN_IF(ret != ACCOUNT_ERROR_NONE, "account_destroy Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               account_disconnect();
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       ret = account_destroy(account);
+       WARN_IF(ret != ACCOUNT_ERROR_NONE, "account_destroy Fail(%d)", ret);
+
+       ret = account_disconnect();
+       WARN_IF(ret != ACCOUNT_ERROR_NONE, "account_disconnect Fail(%d)", ret);
+#endif // CTS_MOBILE
+
+       snprintf(query, sizeof(query),
+                       "INSERT INTO %s(addressbook_name, account_id, mode, smack_label) "
+                       "VALUES(?, %d, %d, ?)",
+                       CTS_TABLE_ADDRESSBOOKS, addressbook->account_id, addressbook->mode);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_stmt_bind_text(stmt, 1, addressbook->name);
+
+       smack = ctsvc_get_client_smack_label();
+       if (smack)
+               ctsvc_stmt_bind_text(stmt, 2, smack);
+
+       /* DOING JOB */
+       do {
+               ret = ctsvc_stmt_step(stmt);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       break;
+               }
+
+               //int index = ctsvc_db_get_last_insert_id();
+               if (id)
+                       *id = ctsvc_db_get_last_insert_id();
+               ctsvc_stmt_finalize(stmt);
+
+               ctsvc_set_addressbook_noti();
+               ret = ctsvc_end_trans(true);
+               if(ret < CONTACTS_ERROR_NONE )
+               {
+                       CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+                       free(smack);
+                       return ret;
+               }
+               //addressbook->id = index;
+
+               // SUCCESS
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       /* ROLLBACK TRANSACTION */
+       ctsvc_end_trans(false);
+       free(smack);
+       return ret;
+}
+
+static int __ctsvc_db_addressbook_update_record( contacts_record_h record )
+{
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       ctsvc_addressbook_s *addressbook = (ctsvc_addressbook_s *)record;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (addressbook->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+       RETV_IF(NULL == addressbook->name, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETVM_IF(CTSVC_RECORD_ADDRESSBOOK != addressbook->base.r_type, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : record is invalid type(%d)", addressbook->base.r_type);
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       ret = ctsvc_is_owner(addressbook->id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               if (CONTACTS_ERROR_PERMISSION_DENIED == ret)
+                       CTS_ERR("Does not have permission of address_book (%d)", addressbook->id);
+               else
+                       CTS_ERR("ctsvc_is_owner Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       do {
+               char query[CTS_SQL_MAX_LEN] = {0};
+               cts_stmt stmt = NULL;
+
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (NULL == set || '\0' == *set)
+                       break;
+
+               snprintf(query, sizeof(query), "UPDATE %s SET %s WHERE addressbook_id = %d", CTS_TABLE_ADDRESSBOOKS, set, addressbook->id);
+               ret = ctsvc_query_prepare(query, &stmt);
+               if (NULL == stmt) {
+                       CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+                       break;
+               }
+               if (bind_text) {
+                       int i = 0;
+                       for (cursor=bind_text,i=1;cursor;cursor=cursor->next,i++) {
+                               const char *text = cursor->data;
+                               if (text && *text)
+                                       ctsvc_stmt_bind_text(stmt, i, text);
+                       }
+               }
+               ret = ctsvc_stmt_step(stmt);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       break;
+               }
+               ctsvc_stmt_finalize(stmt);
+
+               ctsvc_set_addressbook_noti();
+       } while (0);
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_end_trans(true);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "DB error : ctsvc_end_trans() Failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_addressbook_delete_record( int addressbook_id )
+{
+       CTS_FN_CALL;
+
+       if (0 /*CTS_ADDRESSBOOK_INTERNAL*/ == addressbook_id)
+               return ctsvc_addressbook_reset_internal_addressbook();
+
+       char query[CTS_SQL_MAX_LEN] = {0};
+       int ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE > ret, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret);
+
+       ret = ctsvc_is_owner(addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               if (CONTACTS_ERROR_PERMISSION_DENIED == ret)
+                       CTS_ERR("Does not have permission to delete address_book (%d)", addressbook_id);
+               else
+                       CTS_ERR("ctsvc_is_owner Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE addressbook_id = %d",
+                       CTS_TABLE_ADDRESSBOOKS, addressbook_id);
+
+       /* DOING JOB */
+       do {
+               ret = ctsvc_query_exec(query);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret);
+                       break;
+               }
+
+               ret = ctsvc_db_change();
+               if (0 < ret) {
+                       ctsvc_set_my_profile_noti();
+                       ctsvc_set_contact_noti();
+                       // person noti will set in ctsvc_person_do_garbage_collection : ctsvc_set_person_noti();
+                       ctsvc_set_group_noti();
+                       ctsvc_set_addressbook_noti();
+               }
+               else {
+                       ret = CONTACTS_ERROR_NO_DATA;
+                       break;
+               }
+
+               ret = ctsvc_person_do_garbage_collection();
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : ctsvc_person_garbagecollection() Failed(%d)", ret);
+                       break;
+               }
+
+               ret = ctsvc_end_trans(true);
+               if (ret < CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+                       return ret;
+               }
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       ctsvc_end_trans(false);
+
+       return ret;
+}
+
+static int __ctsvc_db_addressbook_get_all_records( int offset, int limit,
+       contacts_list_h* out_list )
+{
+       int ret;
+       int len;
+       cts_stmt stmt;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_list_h list;
+
+       len = snprintf(query, sizeof(query),
+                               "SELECT addressbook_id, addressbook_name, account_id, mode, last_sync_ver "
+                               "FROM "CTS_TABLE_ADDRESSBOOKS);
+
+       len += snprintf(query+len, sizeof(query)-len,
+                               " ORDER BY account_id, addressbook_id");
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               __ctsvc_db_addressbook_value_set(stmt, &record);
+
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_addressbook_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_addressbook_s *addressbook;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_address_book._uri, &record);
+               addressbook = (ctsvc_addressbook_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if (CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_ADDRESSBOOK_ID:
+                               addressbook->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_ADDRESSBOOK_NAME:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               addressbook->name = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_ADDRESSBOOK_MODE:
+                               addressbook->mode = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_ADDRESSBOOK_ACCOUNT_ID:
+                               addressbook->account_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+#if 0
+static int __ctsvc_db_addressbook_insert_records(const contacts_list_h in_list, int **ids)
+{
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_addressbook_update_records(const contacts_list_h in_list)
+{
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_addressbook_delete_records(int ids[], int count)
+{
+       return CONTACTS_ERROR_NONE;
+}
+#endif
diff --git a/native/ctsvc_db_plugin_addressbook_helper.c b/native/ctsvc_db_plugin_addressbook_helper.c
new file mode 100644 (file)
index 0000000..a62d5f0
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_person.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_addressbook_helper.h"
+
+int ctsvc_addressbook_reset_internal_addressbook(void)
+{
+       CTS_FN_CALL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+       int ret;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE > ret, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret);
+
+       ret = ctsvc_is_owner(0);
+       if (CONTACTS_ERROR_NONE != ret) {
+               if (CONTACTS_ERROR_PERMISSION_DENIED == ret)
+                       CTS_ERR("Does not have permission of address_book (0)");
+               else
+                       CTS_ERR("ctsvc_is_owner Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query), "UPDATE %s SET deleted=1, person_id=0, "
+                       "changed_ver = ((SELECT ver FROM cts_version) + 1) WHERE addressbook_id = %d",
+                       CTS_TABLE_CONTACTS, 0 /*CTS_ADDRESSBOOK_INTERNAL*/);
+
+       /* DOING JOB */
+       do {
+               ret = ctsvc_query_exec(query);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret);
+                       break;
+               }
+
+               snprintf(query, sizeof(query), "DELETE FROM %s WHERE addressbook_id = %d",
+                               CTS_TABLE_MY_PROFILES, 0);
+
+               ret = ctsvc_query_exec(query);
+               if (CONTACTS_ERROR_NONE != ret)
+               {
+                       CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret);
+                       break;
+               }
+
+               snprintf(query, sizeof(query), "DELETE FROM %s WHERE addressbook_id = %d",
+                               CTS_TABLE_GROUPS, 0 /*CTS_ADDRESSBOOK_INTERNAL*/);
+               ret = ctsvc_query_exec(query);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret);
+                       break;
+               }
+
+               snprintf(query, sizeof(query), "DELETE FROM %s WHERE addressbook_id = %d",
+                               CTS_TABLE_GROUP_DELETEDS, 0 /*CTS_ADDRESSBOOK_INTERNAL*/);
+               ret = ctsvc_query_exec(query);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret);
+                       break;
+               }
+
+               snprintf(query, sizeof(query), "DELETE FROM %s WHERE addressbook_id = %d",
+                               CTS_TABLE_DELETEDS, 0 /*CTS_ADDRESSBOOK_INTERNAL*/);
+               ret = ctsvc_query_exec(query);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret);
+                       break;
+               }
+
+               ret = ctsvc_person_do_garbage_collection();
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : ctsvc_person_garbagecollection() Failed(%d)", ret);
+                       break;
+               }
+
+               ctsvc_set_contact_noti();
+               ctsvc_set_my_profile_noti();
+               // person noti will set in ctsvc_person_do_garbage_collection : ctsvc_set_person_noti();
+               ctsvc_set_group_noti();
+               ret = ctsvc_end_trans(true);
+               if (ret < CONTACTS_ERROR_NONE) {
+                       CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+                       return ret;
+               }
+
+               return CONTACTS_ERROR_NONE;
+       } while(0);
+
+       /* ROLLBACK TRANSACTION */
+       ctsvc_end_trans(false);
+
+       return ret;
+}
+
+int ctsvc_addressbook_delete(int account_id)
+{
+       CTS_FN_CALL;
+       int ret;
+       int addressbook_id = -1;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       RETVM_IF(account_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "Account_id(%d) is invalid", account_id);
+
+       // delete addressbook whish has account_id
+       ret = ctsvc_begin_trans();
+       RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query), "SELECT addressbook_id FROM %s WHERE account_id = %d",
+                       CTS_TABLE_ADDRESSBOOKS, account_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_query_get_first_int_result() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (addressbook_id == 0) {
+               ret = ctsvc_addressbook_reset_internal_addressbook();
+               if (ret == CONTACTS_ERROR_NONE)
+                       ret = ctsvc_end_trans(true);
+               else
+                       ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE account_id = %d",
+                       CTS_TABLE_ADDRESSBOOKS, account_id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_change();
+       if (0 < ret) {
+               ctsvc_set_my_profile_noti();
+               ctsvc_set_contact_noti();
+               // person noti will set in ctsvc_person_do_garbage_collection : ctsvc_set_person_noti();
+               ctsvc_set_group_noti();
+               ctsvc_set_addressbook_noti();
+       }
+       else {
+               CTS_ERR("There is no addressbook which has account_id (%d)", account_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_NO_DATA;
+       }
+
+       ret = ctsvc_person_do_garbage_collection();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_person_garbagecollection() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       return ctsvc_end_trans(true);
+}
+
diff --git a/native/ctsvc_db_plugin_addressbook_helper.h b/native/ctsvc_db_plugin_addressbook_helper.h
new file mode 100644 (file)
index 0000000..23c6a6a
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_ADDRESS_BOOK_HELPER_H__
+#define __CTSVC_DB_PLUGIN_ADDRESS_BOOK_HELPER_H__
+
+int ctsvc_addressbook_delete(int account_id);
+int ctsvc_addressbook_reset_internal_addressbook(void);
+
+#endif // __CTSVC_DB_PLUGIN_ADDRESS_BOOK_HELPER_H__
diff --git a/native/ctsvc_db_plugin_company.c b/native/ctsvc_db_plugin_company.c
new file mode 100644 (file)
index 0000000..f6c82f8
--- /dev/null
@@ -0,0 +1,454 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <unistd.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_db_plugin_company_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_list.h"
+
+static int __ctsvc_db_company_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_company_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_company_update_record( contacts_record_h record );
+static int __ctsvc_db_company_delete_record( int id );
+static int __ctsvc_db_company_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_company_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_company_insert_records(const contacts_list_h in_list, int **ds);
+//static int __ctsvc_db_company_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_company_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_company = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_company_insert_record,
+       .get_record = __ctsvc_db_company_get_record,
+       .update_record = __ctsvc_db_company_update_record,
+       .delete_record = __ctsvc_db_company_delete_record,
+       .get_all_records = __ctsvc_db_company_get_all_records,
+       .get_records_with_query = __ctsvc_db_company_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_company_insert_records,
+       .update_records = NULL,//__ctsvc_db_company_update_records,
+       .delete_records = NULL,//__ctsvc_db_company_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_company_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, "
+                               "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE id = %d AND datatype = %d ",
+                               id, CTSVC_DATA_COMPANY);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ctsvc_db_company_get_value_from_stmt(stmt, out_record, 0);
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_company_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_company_s *company = (ctsvc_company_s *)record;
+
+       RETVM_IF(NULL == company->name && NULL == company->department && NULL == company->job_title
+               && NULL == company->role && NULL == company->assistant_name && NULL == company->logo
+               && NULL == company->location && NULL == company->description && NULL == company->phonetic_name,
+               CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : company is NULL");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", company->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       CTS_ERR("No data : contact_id (%d) is not exist", company->contact_id);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               else {
+                       CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this company record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_company_insert(record, company->contact_id, false, id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_contact_update_display_name(company->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_COMPANY);
+
+       ret = ctsvc_db_contact_update_changed_time(company->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_company_update_record( contacts_record_h record )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_company_s *company = (ctsvc_company_s *)record;
+
+       RETVM_IF(NULL == company->name && NULL == company->department &&        NULL == company->job_title &&
+                       NULL == company->role && NULL == company->assistant_name && NULL == company->logo &&
+                       NULL == company->location &&    NULL == company->description && NULL == company->phonetic_name,
+                       CONTACTS_ERROR_INVALID_PARAMETER, "company is empty");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", company->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : contact_id (%d) is not exist", company->contact_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this company record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_company_update(record, company->contact_id, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("Update record Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_contact_update_display_name(company->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_COMPANY);
+
+       ret = ctsvc_db_contact_update_changed_time(company->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+
+static int __ctsvc_db_company_delete_record( int id )
+{
+       int ret;
+       int contact_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt;
+       int addressbook_id;
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" "
+                               "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("The id(%d) is Invalid(%d)", id, ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       contact_id = ctsvc_stmt_get_int(stmt, 0);
+       addressbook_id = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this company record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_company_delete(id, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_contact_update_display_name(contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_COMPANY);
+
+       ret = ctsvc_db_contact_update_changed_time(contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_company_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int len;
+       int ret;
+       contacts_list_h list;
+       ctsvc_company_s *company;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, "
+                               "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE datatype=%d AND is_my_profile=0 ",
+                               CTSVC_DATA_COMPANY);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB : ctsvc_stmt_step fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_db_company_get_value_from_stmt(stmt, (contacts_record_h*)&company, 0);
+               ctsvc_list_prepend(list, (contacts_record_h)company);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_company_get_records_with_query( contacts_query_h query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_company_s *company;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_company._uri, &record);
+               company = (ctsvc_company_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if(CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_COMPANY_ID:
+                               company->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_COMPANY_CONTACT_ID:
+                               company->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_COMPANY_TYPE:
+                               company->type = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_COMPANY_LABEL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               company->label = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_COMPANY_NAME:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               company->name = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_COMPANY_DEPARTMENT:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               company->department = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_COMPANY_JOB_TITLE:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               company->job_title = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_COMPANY_ASSISTANT_NAME:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               company->assistant_name = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_COMPANY_ROLE:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               company->role = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_COMPANY_LOGO:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               company->logo = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_COMPANY_LOCATION:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               company->location = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_COMPANY_DESCRIPTION:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               company->description = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_COMPANY_PHONETIC_NAME:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               company->phonetic_name = SAFE_STRDUP(temp);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_company_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_company_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_company_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_company_helper.c b/native/ctsvc_db_plugin_company_helper.c
new file mode 100644 (file)
index 0000000..5dcb09b
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <ctype.h>
+#include <unistd.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_plugin_company_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_access_control.h"
+
+static int __ctsvc_company_bind_stmt(cts_stmt stmt, ctsvc_company_s *company, int start_cnt)
+{
+       ctsvc_stmt_bind_int(stmt, start_cnt, company->is_default);
+       ctsvc_stmt_bind_int(stmt, start_cnt+1, company->type);
+       if (company->label)
+               sqlite3_bind_text(stmt, start_cnt+2, company->label,
+                       strlen(company->label), SQLITE_STATIC);
+       if (company->name)
+               sqlite3_bind_text(stmt, start_cnt+3, company->name,
+                       strlen(company->name), SQLITE_STATIC);
+       if (company->department)
+               sqlite3_bind_text(stmt, start_cnt+4, company->department,
+                               strlen(company->department), SQLITE_STATIC);
+       if (company->job_title)
+               sqlite3_bind_text(stmt, start_cnt+5, company->job_title,
+                               strlen(company->job_title), SQLITE_STATIC);
+       if (company->role)
+               sqlite3_bind_text(stmt, start_cnt+6, company->role,
+                               strlen(company->role), SQLITE_STATIC);
+       if (company->assistant_name)
+               sqlite3_bind_text(stmt, start_cnt+7, company->assistant_name,
+                       strlen(company->assistant_name), SQLITE_STATIC);
+
+       // skip logo here
+
+       if (company->location)
+               sqlite3_bind_text(stmt, start_cnt+9, company->location,
+                       strlen(company->location), SQLITE_STATIC);
+       if (company->description)
+               sqlite3_bind_text(stmt, start_cnt+10, company->description,
+                       strlen(company->description), SQLITE_STATIC);
+       if (company->phonetic_name)
+               sqlite3_bind_text(stmt, start_cnt+11, company->phonetic_name,
+                       strlen(company->phonetic_name), SQLITE_STATIC);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_company_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id)
+{
+       int ret;
+       int company_id = 0;
+       cts_stmt stmt = NULL;
+       ctsvc_company_s *company = (ctsvc_company_s*)record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : contact_id(%d) is mandatory field to insert company record ", company->contact_id);
+       RETVM_IF(0 < company->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", company->id);
+
+       if (company->name || company->department || company->job_title || company->role
+                       || company->assistant_name || company->logo || company->location || company->description
+                       || company->phonetic_name) {
+
+               ret = ctsvc_db_get_next_id(CTS_TABLE_DATA);
+               if (ret < CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_db_get_next_id() Failed(%d)", ret);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+               company_id = ret;
+
+               snprintf(query, sizeof(query),
+                       "INSERT INTO "CTS_TABLE_DATA"(id, contact_id, is_my_profile, datatype, is_default, data1, data2, data3, data4, "
+                                       "data5, data6, data7, data8, data9, data10, data11, data12) "
+                                       "VALUES(%d, %d, %d, %d, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+                                       company_id, contact_id, is_my_profile, CTSVC_DATA_COMPANY);
+
+               ret = ctsvc_query_prepare(query, &stmt);
+               RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+               __ctsvc_company_bind_stmt(stmt, company, 1);
+               if (company->logo) {
+                       char image[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+                       ret = ctsvc_have_file_read_permission(company->logo);
+                       if (ret != CONTACTS_ERROR_NONE) {
+                               CTS_ERR("ctsvc_have_file_read_permission Fail(%d)", ret);
+                               ctsvc_stmt_finalize(stmt);
+                               return ret;
+                       }
+                       ctsvc_utils_make_image_file_name(contact_id, company_id, company->logo, image, sizeof(image));
+                       ret = ctsvc_utils_copy_image(CTS_LOGO_IMAGE_LOCATION, company->logo, image);
+                       if (CONTACTS_ERROR_NONE != ret) {
+                               CTS_ERR("ctsvc_utils_copy_image() Failed(%d)", ret);
+                               ctsvc_stmt_finalize(stmt);
+                               return ret;
+                       }
+                       ctsvc_stmt_bind_text(stmt, 9, image);
+               }
+
+               ret = ctsvc_stmt_step(stmt);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       return ret;
+               }
+               ctsvc_stmt_finalize(stmt);
+
+               company->id = company_id;
+               if (id)
+                       *id = company_id;
+
+               if (!is_my_profile)
+                       ctsvc_set_company_noti();
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_company_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count)
+{
+       int ret;
+       char *temp;
+       ctsvc_company_s *company;
+
+       ret = contacts_record_create(_contacts_company._uri, (contacts_record_h *)&company);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+
+       company->id = ctsvc_stmt_get_int(stmt, start_count++);
+       company->contact_id = ctsvc_stmt_get_int(stmt, start_count++);
+       company->is_default = ctsvc_stmt_get_int(stmt, start_count++);
+       company->type = ctsvc_stmt_get_int(stmt, start_count++);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       company->label = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       company->name = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       company->department = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       company->job_title = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       company->role = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       company->assistant_name = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       if (temp) {
+               char tmp_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+               snprintf(tmp_path, sizeof(tmp_path), "%s/%s", CTS_LOGO_IMAGE_LOCATION, temp);
+               company->logo = strdup(tmp_path);
+       }
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       company->location = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       company->description = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       company->phonetic_name = SAFE_STRDUP(temp);
+
+       if (company->name || company->department || company->job_title || company->role
+                       || company->assistant_name || company->logo || company->location || company->description
+                       || company->phonetic_name)
+               *record = (contacts_record_h)company;
+       else {
+               contacts_record_destroy((contacts_record_h)company, true);
+               *record = NULL;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_company_update(contacts_record_h record, int contact_id, bool is_my_profile)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_company_s *company = (ctsvc_company_s*)record;
+       cts_stmt stmt = NULL;
+
+       RETVM_IF(!company->id, CONTACTS_ERROR_INVALID_PARAMETER, "company of contact has no ID.");
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (company->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+
+       snprintf(query, sizeof(query),
+                       "SELECT id, data8 FROM "CTS_TABLE_DATA" WHERE id = %d", company->id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (ret != 1) {
+               ctsvc_stmt_finalize(stmt);
+               if (ret == CONTACTS_ERROR_NONE)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)company, _contacts_company.logo, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               char *logo = ctsvc_stmt_get_text(stmt, 1);
+               bool same = false;
+               bool check_permission = false;
+
+               // delete current logo image
+               if (logo) {
+                       char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+                       snprintf(full_path, sizeof(full_path), "%s/%s", CTS_LOGO_IMAGE_LOCATION, logo);
+                       if (company->logo && strcmp(company->logo, full_path) == 0) {
+                               int index = _contacts_company.logo & 0x000000FF;
+                               ((ctsvc_record_s *)record)->properties_flags[index] = 0;
+                               same = true;
+                       }
+                       else {
+                               if (company->logo) {
+                                       ret = ctsvc_have_file_read_permission(company->logo);
+                                       if (ret != CONTACTS_ERROR_NONE) {
+                                               CTS_ERR("ctsvc_have_file_read_permission Fail(%d)", ret);
+                                               ctsvc_stmt_finalize(stmt);
+                                               return ret;
+                                       }
+                                       check_permission = true;
+                               }
+                               ret = unlink(full_path);
+                               if (ret < 0) {
+                                       CTS_WARN("unlink Failed(%d)", errno);
+                               }
+                       }
+               }
+
+               // add new logo file
+               if (!same && company->logo) {
+                       char dest[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+                       if (false == check_permission) {
+                               ret = ctsvc_have_file_read_permission(company->logo);
+                               if (ret != CONTACTS_ERROR_NONE) {
+                                       CTS_ERR("ctsvc_have_file_read_permission Fail(%d)", ret);
+                                       ctsvc_stmt_finalize(stmt);
+                                       return ret;
+                               }
+                       }
+                       ctsvc_utils_make_image_file_name(contact_id, company->id, company->logo, dest, sizeof(dest));
+                       ret = ctsvc_utils_copy_image(CTS_LOGO_IMAGE_LOCATION, company->logo, dest);
+                       if (CONTACTS_ERROR_NONE != ret) {
+                               CTS_ERR("cts_copy_file() Failed(%d)", ret);
+                               ctsvc_stmt_finalize(stmt);
+                               return ret;
+                       }
+                       free(company->logo);
+                       company->logo = strdup(dest);
+               }
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_DATA, company->id))) break;
+               if (!is_my_profile)
+                       ctsvc_set_company_noti();
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       return ret;
+}
+
+int ctsvc_db_company_delete(int id, bool is_my_profile)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE id = %d AND datatype = %d",
+                       id, CTSVC_DATA_COMPANY);
+
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_exec() Failed(%d)", ret);
+       if (!is_my_profile)
+               ctsvc_set_company_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
+// Whenever deleting company record in data table, this function will be called
+// in order to delete company logo image file
+void ctsvc_db_company_delete_callback(sqlite3_context *context, int argc, sqlite3_value ** argv)
+{
+       int ret;
+       const unsigned char* logo_path;
+
+       if (argc > 1) {
+               sqlite3_result_null(context);
+               return;
+       }
+       logo_path = sqlite3_value_text(argv[0]);
+
+       if (logo_path) {
+               char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+               snprintf(full_path, sizeof(full_path), "%s/%s", CTS_LOGO_IMAGE_LOCATION, logo_path);
+               ret = unlink(full_path);
+               if (ret < 0) {
+                       CTS_WARN("unlink Failed(%d)", errno);
+               }
+       }
+
+       return;
+}
+
+
diff --git a/native/ctsvc_db_plugin_company_helper.h b/native/ctsvc_db_plugin_company_helper.h
new file mode 100644 (file)
index 0000000..e885d48
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_COMPANY_HELPER_H__
+#define __CTSVC_DB_PLUGIN_COMPANY_HELPER_H__
+
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
+
+#define CTS_LOGO_IMAGE_LOCATION "/opt/usr/data/contacts-svc/img/logo"
+
+int ctsvc_db_company_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id);
+int ctsvc_db_company_update(contacts_record_h record, int contact_id, bool is_my_profile);
+int ctsvc_db_company_delete(int id, bool is_my_profile);
+int ctsvc_db_company_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count);
+void ctsvc_db_company_delete_callback(sqlite3_context *context, int argc, sqlite3_value ** argv);
+
+#endif // __CTSVC_DB_PLUGIN_COMPANY_HELPER_H__
diff --git a/native/ctsvc_db_plugin_contact.c b/native/ctsvc_db_plugin_contact.c
new file mode 100644 (file)
index 0000000..24c9a24
--- /dev/null
@@ -0,0 +1,2382 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <sys/types.h>
+#include <sys/syscall.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_record.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_number_utils.h"
+#include "ctsvc_list.h"
+#include "ctsvc_setting.h"
+#include "ctsvc_localize_ch.h"
+#include "ctsvc_group.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_localize.h"
+#include "ctsvc_localize_utils.h"
+#include "ctsvc_person.h"
+#ifdef ENABLE_LOG_FEATURE
+#include "ctsvc_phonelog.h"
+#endif // ENABLE_LOG_FEATURE
+#include "ctsvc_db_access_control.h"
+
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_db_plugin_person_helper.h"
+
+static int __ctsvc_db_contact_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_contact_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_contact_update_record( contacts_record_h record );
+static int __ctsvc_db_contact_delete_record( int id );
+static int __ctsvc_db_contact_replace_record( contacts_record_h record, int id );
+
+static int __ctsvc_db_contact_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_contact_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_contact_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_contact_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_contact_delete_records(int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_contact = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_contact_insert_record,
+       .get_record = __ctsvc_db_contact_get_record,
+       .update_record = __ctsvc_db_contact_update_record,
+       .delete_record = __ctsvc_db_contact_delete_record,
+       .get_all_records = __ctsvc_db_contact_get_all_records,
+       .get_records_with_query = __ctsvc_db_contact_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_contact_insert_records,
+       .update_records = NULL,//__ctsvc_db_contact_update_records,
+       .delete_records = NULL,//__ctsvc_db_contact_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = __ctsvc_db_contact_replace_record,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_get_contact_base_info(int id, ctsvc_contact_s *contact)
+{
+       int ret;
+       int i;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       char *temp;
+       char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, addressbook_id, person_id, changed_time, changed_ver, link_mode, %s, "
+                               "display_name_source, image_thumbnail_path, "
+                               "ringtone_path, vibration, message_alert, "
+                               "uid, is_favorite, has_phonenumber, has_email, "
+                               "sort_name, reverse_sort_name "
+                               "FROM "CTS_TABLE_CONTACTS" WHERE contact_id = %d AND deleted = 0",
+                               ctsvc_get_display_column(), id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       i = 0;
+       contact->id = ctsvc_stmt_get_int(stmt, i++);
+       contact->addressbook_id = ctsvc_stmt_get_int(stmt, i++);
+       contact->person_id = ctsvc_stmt_get_int(stmt, i++);
+       contact->changed_time = ctsvc_stmt_get_int(stmt, i++);
+       contact->changed_ver = ctsvc_stmt_get_int(stmt, i++);
+       contact->link_mode = ctsvc_stmt_get_int(stmt, i++);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       contact->display_name = SAFE_STRDUP(temp);
+       contact->display_source_type = ctsvc_stmt_get_int(stmt, i++);
+
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       if (temp) {
+               snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
+               contact->image_thumbnail_path = strdup(full_path);
+       }
+
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       contact->ringtone_path = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       contact->vibration = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       contact->message_alert = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       contact->uid = SAFE_STRDUP(temp);
+       contact->is_favorite = ctsvc_stmt_get_int(stmt, i++);
+       contact->has_phonenumber = ctsvc_stmt_get_int(stmt, i++);
+       contact->has_email = ctsvc_stmt_get_int(stmt, i++);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       contact->sort_name = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       contact->reverse_sort_name = SAFE_STRDUP(temp);
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_get_data(int id, ctsvc_contact_s *contact)
+{
+       int ret;
+       int datatype;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                               "SELECT datatype, id, data.contact_id, is_default, data1, data2, "
+                                       "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
+                                       "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                                       "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                                       "WHERE data.contact_id = %d  AND is_my_profile = 0 "
+                                       "ORDER BY is_default DESC", id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE */!= ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+
+       do {
+               datatype = ctsvc_stmt_get_int(stmt, 0);
+               switch (datatype) {
+               case CTSVC_DATA_NAME:
+                       ctsvc_get_data_info_name(stmt, (contacts_list_h)contact->name);
+                       break;
+               case CTSVC_DATA_EVENT:
+                       ctsvc_get_data_info_event(stmt, (contacts_list_h)contact->events);
+                       break;
+               case CTSVC_DATA_MESSENGER:
+                       ctsvc_get_data_info_messenger(stmt, (contacts_list_h)contact->messengers);
+                       break;
+               case CTSVC_DATA_POSTAL:
+                       ctsvc_get_data_info_address(stmt, (contacts_list_h)contact->postal_addrs);
+                       break;
+               case CTSVC_DATA_URL:
+                       ctsvc_get_data_info_url(stmt, (contacts_list_h)contact->urls);
+                       break;
+               case CTSVC_DATA_NICKNAME:
+                       ctsvc_get_data_info_nickname(stmt, (contacts_list_h)contact->nicknames);
+                       break;
+               case CTSVC_DATA_NUMBER:
+                       ctsvc_get_data_info_number(stmt, (contacts_list_h)contact->numbers);
+                       break;
+               case CTSVC_DATA_EMAIL:
+                       ctsvc_get_data_info_email(stmt, (contacts_list_h)contact->emails);
+                       break;
+               case CTSVC_DATA_PROFILE:
+                       ctsvc_get_data_info_profile(stmt, (contacts_list_h)contact->profiles);
+                       break;
+               case CTSVC_DATA_RELATIONSHIP:
+                       ctsvc_get_data_info_relationship(stmt, (contacts_list_h)contact->relationships);
+                       break;
+               case CTSVC_DATA_IMAGE:
+                       ctsvc_get_data_info_image(stmt, (contacts_list_h)contact->images);
+                       break;
+               case CTSVC_DATA_COMPANY:
+                       ctsvc_get_data_info_company(stmt, (contacts_list_h)contact->company);
+                       break;
+               case CTSVC_DATA_NOTE:
+                       ctsvc_get_data_info_note(stmt, (contacts_list_h)contact->note);
+                       break;
+               case CTSVC_DATA_EXTENSION:
+                       ctsvc_get_data_info_extension(stmt, (contacts_list_h)contact->extensions);
+                       break;
+               default:
+                       CTS_ERR("Intenal : Not supported data type (%d)", datatype);
+                       break;
+               }
+
+       }while(1 == ctsvc_stmt_step(stmt));
+
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+
+}
+
+static inline int __ctsvc_get_contact_grouprel(int contact_id, ctsvc_contact_s *contact)
+{
+       CTS_FN_CALL;
+       int ret;
+       ctsvc_group_relation_s *grouprel;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       char *temp;
+
+       snprintf(query, sizeof(query),
+               "SELECT group_id, contact_id, group_name "
+                       " FROM "CTSVC_DB_VIEW_GROUP_RELATION" WHERE contact_id = %d", contact_id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       while (1 /*CTS_TRUE */ == ctsvc_stmt_step(stmt)) {
+               contacts_record_create(_contacts_group_relation._uri, (contacts_record_h*)&grouprel);
+
+               if (grouprel) {
+                       grouprel->group_id = ctsvc_stmt_get_int(stmt, 0);
+                       grouprel->id = grouprel->group_id;
+                       grouprel->contact_id = ctsvc_stmt_get_int(stmt, 1);
+                       temp = ctsvc_stmt_get_text(stmt, 2);
+                       grouprel->group_name = SAFE_STRDUP(temp);
+
+                       ctsvc_list_prepend((contacts_list_h)contact->grouprelations, (contacts_record_h)grouprel);
+               }
+       }
+
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse((contacts_list_h)contact->grouprelations);
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_contact_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       contacts_record_h record;
+       ctsvc_contact_s *contact;
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       contacts_record_create(_contacts_contact._uri, &record);
+       contact = (ctsvc_contact_s *)record;
+       ret = __ctsvc_db_get_contact_base_info(id, contact);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_db_get_contact_base_info(ALL) Failed(%d)", ret);
+               contacts_record_destroy(record, true);
+               return ret;
+       }
+
+       ret = __ctsvc_db_get_data(id, contact);
+       if (CONTACTS_ERROR_NONE != ret && CONTACTS_ERROR_NO_DATA != ret) {
+               CTS_ERR("ctsvc_get_data_info Failed(%d)", ret);
+               contacts_record_destroy(record, true);
+               return ret;
+       }
+
+       ret = __ctsvc_get_contact_grouprel(id, contact);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_get_group_relations Failed(%d)", ret);
+               contacts_record_destroy(record, true);
+               return ret;
+       }
+
+       *out_record = record;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_contact_delete_record( int id )
+{
+       return ctsvc_db_contact_delete(id);
+}
+
+static inline int __ctsvc_contact_update_data(ctsvc_contact_s *contact)
+{
+       int ret;
+
+       if (contact->name) {
+               ret = ctsvc_contact_update_data_name((contacts_list_h)contact->name, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_name() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (contact->company) {
+               ret = ctsvc_contact_update_data_company((contacts_list_h)contact->company, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_company() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (contact->note) {
+               ret = ctsvc_contact_update_data_note((contacts_list_h)contact->note, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_note() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (contact->events) {
+               ret = ctsvc_contact_update_data_event((contacts_list_h)contact->events, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_events() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (contact->messengers) {
+               ret = ctsvc_contact_update_data_messenger((contacts_list_h)contact->messengers, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_messengers() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (contact->postal_addrs) {
+               ret = ctsvc_contact_update_data_address((contacts_list_h)contact->postal_addrs, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_address() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (contact->urls) {
+               ret = ctsvc_contact_update_data_url((contacts_list_h)contact->urls, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_url() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (contact->nicknames) {
+               ret = ctsvc_contact_update_data_nickname((contacts_list_h)contact->nicknames, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_nickname() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (contact->numbers) {
+               bool had_phonenumber;
+               ret = ctsvc_contact_update_data_number((contacts_list_h)contact->numbers, contact->id, false, &had_phonenumber);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_number() Failed(%d)", ret);
+                       return ret;
+               }
+               contact->has_phonenumber = had_phonenumber;
+       }
+
+       if (contact->emails) {
+               bool had_email;
+               ret = ctsvc_contact_update_data_email((contacts_list_h)contact->emails, contact->id, false, &had_email);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_email() Failed(%d)", ret);
+                       return ret;
+               }
+               contact->has_email = had_email;
+       }
+
+       if (contact->profiles) {
+               ret = ctsvc_contact_update_data_profile((contacts_list_h)contact->profiles, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_profile() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (contact->relationships) {
+               ret = ctsvc_contact_update_data_relationship((contacts_list_h)contact->relationships, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_relationship() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (contact->images) {
+               ret = ctsvc_contact_update_data_image((contacts_list_h)contact->images, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_image() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (contact->extensions) {
+               ret = ctsvc_contact_update_data_extension((contacts_list_h)contact->extensions, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_extension() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static void __ctsvc_contact_check_default_data(ctsvc_contact_s *contact)
+{
+       if (contact->numbers)
+               contact->has_phonenumber = ctsvc_contact_check_default_number((contacts_list_h)contact->numbers);
+       if (contact->emails)
+               contact->has_email = ctsvc_contact_check_default_email((contacts_list_h)contact->emails);
+       if (contact->images)
+               ctsvc_contact_check_default_image((contacts_list_h)contact->images);
+       if (contact->postal_addrs)
+               ctsvc_contact_check_default_address((contacts_list_h)contact->postal_addrs);
+}
+
+static inline int __ctsvc_contact_update_grouprel(int contact_id, contacts_list_h group_list)
+{
+       CTS_FN_CALL;
+       ctsvc_group_relation_s *grouprel;
+       ctsvc_list_s *list = (ctsvc_list_s*)group_list;
+       int rel_changed = 0;
+       int count;
+       int ret;
+       GList *cursor;
+
+       RETV_IF(NULL == group_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       for(cursor = list->deleted_records;cursor;cursor=cursor->next) {
+               grouprel = (ctsvc_group_relation_s *)cursor->data;
+               ret = ctsvc_group_remove_contact_in_transaction(grouprel->group_id, contact_id);
+               if (0 < ret)
+                       rel_changed += ret;
+       }
+
+       ret = contacts_list_get_count(group_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(group_list);
+       do {
+               contacts_list_get_current_record_p(group_list, (contacts_record_h*)&grouprel);
+               if (NULL == grouprel)
+                       continue;
+
+               RETVM_IF(grouprel->group_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "group_id(%d) invalid", grouprel->group_id);
+               if (grouprel->group_id) {
+                       ret = ctsvc_group_add_contact_in_transaction(grouprel->group_id, contact_id);
+                       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_db_group_set_relation() Failed(%d)", ret);
+                       if (0 < ret)
+                               rel_changed += ret;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(group_list));
+
+       if (rel_changed)
+               return rel_changed;
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static bool __ctsvc_contact_check_token(char *src, char *dest, int len)
+{
+       bool had = false;
+       int i = 0;
+
+       for (i=0;i<len;i++) {
+               if (src[i] == '@' || src[i] == '.') {
+                       dest[i] = ' ';
+                       had = true;
+               }
+               else
+                       dest[i] = src[i];
+       }
+       dest[i] = '\0';
+
+       return had;
+}
+
+// Make search data by number, email, nicknames, address, note, messenger, relationship, company
+static inline int __ctsvc_contact_make_search_data(int contact_id, ctsvc_contact_s *contact,
+               char **search_name, char **search_number, char **search_data)
+{
+       int len = 0;
+
+       char *number = NULL;
+       char *data = NULL;
+       char *temp_number=NULL;
+       char *temp_data=NULL;
+       int buf_size=0;
+
+       if (contact == NULL)
+               return CONTACTS_ERROR_NO_DATA;
+
+       RETV_IF(NULL == search_name, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == search_number, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == search_data, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       ctsvc_contact_make_search_name(contact, search_name);
+
+       if (contact->numbers) {
+               contacts_list_h number_list = (contacts_list_h)contact->numbers;
+               ctsvc_number_s *number_record;
+               contacts_list_first(number_list);
+               do {
+                       contacts_list_get_current_record_p(number_list, (contacts_record_h*)&number_record);
+                       if (NULL != number_record && number_record->cleaned) {
+                               buf_size = SAFE_STRLEN(number) + SAFE_STRLEN(number_record->cleaned) + SAFE_STRLEN(number_record->normalized) + 3;
+                               temp_number = calloc(1, buf_size);
+                               if (NULL == temp_number) {
+                                       CTS_ERR("calloc() return NULL");
+                                       free(number);
+                                       free(*search_name);
+                                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+                               }
+                               if (NULL == temp_number) {
+                                       CTS_ERR("calloc() return NULL");
+                                       break;
+                               }
+                               if (number)
+                                       snprintf(temp_number, buf_size, "%s %s %s", SAFE_STR(number), number_record->cleaned, number_record->normalized);
+                               else
+                                       snprintf(temp_number, buf_size, "%s %s", number_record->cleaned, number_record->normalized);
+                               free(number);
+                               number = temp_number;
+                       }
+               }while(CONTACTS_ERROR_NONE == contacts_list_next(number_list));
+       }
+
+       if (contact->emails) {
+               contacts_list_h email_list = (contacts_list_h)contact->emails;
+               ctsvc_email_s *email;
+               contacts_list_first(email_list);
+               do {
+                       contacts_list_get_current_record_p(email_list, (contacts_record_h*)&email);
+                       if (NULL != email && email->email_addr) {
+                               int len = strlen(email->email_addr);
+                               char temp[len+1];
+                               bool had = __ctsvc_contact_check_token(email->email_addr, temp, len);
+
+                               buf_size = SAFE_STRLEN(data) + SAFE_STRLEN(email->email_addr) * (had?2:1) + 4;
+                               temp_data = calloc(1, buf_size);
+                               if (NULL == temp_data) {
+                                       CTS_ERR("calloc() return NULL");
+                                       free(data);
+                                       free(number);
+                                       free(*search_name);
+                                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+                               }
+                               if (data)
+                                       snprintf(temp_data, buf_size, "%s %s %s",data, email->email_addr, (had?temp:""));
+                               else
+                                       snprintf(temp_data, buf_size, "%s %s",email->email_addr, (had?temp:""));
+                               free(data);
+                               data = temp_data;
+                       }
+               }while(CONTACTS_ERROR_NONE == contacts_list_next(email_list));
+       }
+
+       if (contact->nicknames) {
+               contacts_list_h nickname_list = (contacts_list_h)contact->nicknames;
+               ctsvc_nickname_s *nickname;
+               contacts_list_first(nickname_list);
+               do {
+                       contacts_list_get_current_record_p(nickname_list, (contacts_record_h*)&nickname);
+                       if (NULL != nickname && nickname->nickname) {
+                               int len = strlen(nickname->nickname);
+                               char temp[len+1];
+                               bool had = __ctsvc_contact_check_token(nickname->nickname, temp, len);
+
+                               buf_size = SAFE_STRLEN(data) + SAFE_STRLEN(nickname->nickname) * (had?2:1) + 4;
+                               temp_data = calloc(1, buf_size);
+                               if (NULL == temp_data) {
+                                       CTS_ERR("calloc() return NULL");
+                                       free(data);
+                                       free(number);
+                                       free(*search_name);
+                                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+                               }
+                               if (data)
+                                       snprintf(temp_data, buf_size, "%s %s %s", data, nickname->nickname, (had?temp:""));
+                               else
+                                       snprintf(temp_data, buf_size, "%s %s", nickname->nickname, (had?temp:""));
+                               free(data);
+                               data = temp_data;
+                       }
+               }while(CONTACTS_ERROR_NONE == contacts_list_next(nickname_list));
+       }
+
+       if (contact->postal_addrs) {
+               contacts_list_h address_list = (contacts_list_h)contact->postal_addrs;
+               ctsvc_address_s *address;
+               contacts_list_first(address_list);
+               do {
+                       contacts_list_get_current_record_p(address_list, (contacts_record_h*)&address);
+                       if (NULL != address) {
+                               bool had;
+                               int str_len = SAFE_STRLEN(address->country)
+                                                       + SAFE_STRLEN(address->pobox)
+                                                       + SAFE_STRLEN(address->postalcode)
+                                                       + SAFE_STRLEN(address->region)
+                                                       + SAFE_STRLEN(address->locality)
+                                                       + SAFE_STRLEN(address->street)
+                                                       + SAFE_STRLEN(address->extended);
+                               len = 0;
+                               buf_size = SAFE_STRLEN(data)
+                                                       + str_len * 2 + 16;
+                               temp_data = calloc(1, buf_size);
+                               if (NULL == temp_data) {
+                                       CTS_ERR("calloc() return NULL");
+                                       free(data);
+                                       free(number);
+                                       free(*search_name);
+                                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+                               }
+
+                               char temp[str_len+1];
+
+                               if(data)
+                                       len += snprintf(temp_data + len, buf_size - len, "%s ", data);
+
+                               if (address->country) {
+                                       had = __ctsvc_contact_check_token(address->country, temp, SAFE_STRLEN(address->country));
+                                       len += snprintf(temp_data + len, buf_size - len, "%s %s ", address->country, had?temp:"");
+                               }
+                               if (address->pobox) {
+                                       had = __ctsvc_contact_check_token(address->pobox, temp, SAFE_STRLEN(address->pobox));
+                                       len += snprintf(temp_data + len, buf_size - len, "%s %s ", address->pobox, had?temp:"");
+                               }
+                               if (address->postalcode) {
+                                       had = __ctsvc_contact_check_token(address->postalcode, temp, SAFE_STRLEN(address->postalcode));
+                                       len += snprintf(temp_data + len, buf_size - len, "%s %s ", address->postalcode, had?temp:"");
+                               }
+                               if (address->region) {
+                                       had = __ctsvc_contact_check_token(address->region, temp, SAFE_STRLEN(address->region));
+                                       len += snprintf(temp_data + len, buf_size - len, "%s %s ", address->region, had?temp:"");
+                               }
+                               if (address->locality) {
+                                       had = __ctsvc_contact_check_token(address->locality, temp, SAFE_STRLEN(address->locality));
+                                       len += snprintf(temp_data + len, buf_size - len, "%s %s ", address->locality, had?temp:"");
+                               }
+                               if (address->street) {
+                                       had = __ctsvc_contact_check_token(address->street, temp, SAFE_STRLEN(address->street));
+                                       len += snprintf(temp_data + len, buf_size - len, "%s %s ", address->street, had?temp:"");
+                               }
+                               if (address->extended) {
+                                       had = __ctsvc_contact_check_token(address->extended, temp, SAFE_STRLEN(address->extended));
+                                       len += snprintf(temp_data + len, buf_size - len, "%s %s ", address->extended, had?temp:"");
+                               }
+                               free(data);
+                               data = temp_data;
+                       }
+               }while(CONTACTS_ERROR_NONE == contacts_list_next(address_list));
+       }
+
+       if (contact->note) {
+               contacts_list_h note_list = (contacts_list_h)contact->note;
+               ctsvc_note_s *note;
+               contacts_list_first(note_list);
+               do {
+                       contacts_list_get_current_record_p(note_list, (contacts_record_h*)&note);
+                       if (NULL != note && note->note) {
+                               int len = strlen(note->note);
+                               char temp[len+1];
+                               bool had = __ctsvc_contact_check_token(note->note, temp, len);
+
+                               buf_size = SAFE_STRLEN(data) + SAFE_STRLEN(note->note) * (had?2:1) + 4;
+                               temp_data = calloc(1, buf_size);
+                               if (NULL == temp_data) {
+                                       CTS_ERR("calloc() return NULL");
+                                       free(data);
+                                       free(number);
+                                       free(*search_name);
+                                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+                               }
+                               if (data)
+                                       snprintf(temp_data, buf_size, "%s %s %s",data, note->note, (had?temp:""));
+                               else
+                                       snprintf(temp_data, buf_size, "%s %s",note->note, (had?temp:""));
+                               free(data);
+                               data = temp_data;
+                       }
+               }while(CONTACTS_ERROR_NONE == contacts_list_next(note_list));
+       }
+
+       if (contact->messengers) {
+               contacts_list_h messenger_list = (contacts_list_h)contact->messengers;
+               ctsvc_messenger_s *messenger;
+               contacts_list_first(messenger_list);
+               do {
+                       contacts_list_get_current_record_p(messenger_list, (contacts_record_h*)&messenger);
+                       if (NULL != messenger && messenger->im_id) {
+                               int len = strlen(messenger->im_id);
+                               char temp[len+1];
+                               bool had = __ctsvc_contact_check_token(messenger->im_id, temp, len);
+
+                               buf_size = SAFE_STRLEN(data) + SAFE_STRLEN(messenger->im_id) * (had?2:1) + 4;
+                               temp_data = calloc(1, buf_size);
+                               if (NULL == temp_data) {
+                                       CTS_ERR("calloc() return NULL");
+                                       free(data);
+                                       free(number);
+                                       free(*search_name);
+                                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+                               }
+                               if (data)
+                                       snprintf(temp_data, buf_size, "%s %s %s",data, messenger->im_id, (had?temp:""));
+                               else
+                                       snprintf(temp_data, buf_size, "%s %s",messenger->im_id, (had?temp:""));
+                               free(data);
+                               data = temp_data;
+                       }
+               }while(CONTACTS_ERROR_NONE == contacts_list_next(messenger_list));
+       }
+
+       if (contact->relationships) {
+               contacts_list_h relationship_list = (contacts_list_h)contact->relationships;
+               ctsvc_relationship_s *relationship;
+               contacts_list_first(relationship_list);
+               do {
+                       contacts_list_get_current_record_p(relationship_list, (contacts_record_h*)&relationship);
+                       if (NULL != relationship && relationship->name) {
+                               int len = strlen(relationship->name);
+                               char temp[len+1];
+                               bool had = __ctsvc_contact_check_token(relationship->name, temp, len);
+
+                               buf_size = SAFE_STRLEN(data) + SAFE_STRLEN(relationship->name) * (had?2:1) + 4;
+                               temp_data = calloc(1, buf_size);
+                               if (NULL == temp_data) {
+                                       CTS_ERR("calloc() return NULL");
+                                       free(data);
+                                       free(number);
+                                       free(*search_name);
+                                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+                               }
+
+                               if (data)
+                                       snprintf(temp_data, buf_size, "%s %s %s",data, relationship->name, (had?temp:""));
+                               else
+                                       snprintf(temp_data, buf_size, "%s %s",relationship->name, (had?temp:""));
+                               free(data);
+                               data = temp_data;
+                       }
+               }while(CONTACTS_ERROR_NONE == contacts_list_next(relationship_list));
+       }
+
+       if (contact->company) {
+               contacts_list_h company_list = (contacts_list_h)contact->company;
+               ctsvc_company_s *company;
+               contacts_list_first(company_list);
+               do {
+                       contacts_list_get_current_record_p(company_list, (contacts_record_h*)&company);
+                       if (NULL != company) {
+                               bool had;
+                               int str_len = SAFE_STRLEN(company->name)
+                                                       + SAFE_STRLEN(company->department)
+                                                       + SAFE_STRLEN(company->job_title)
+                                                       + SAFE_STRLEN(company->role)
+                                                       + SAFE_STRLEN(company->assistant_name)
+                                                       + SAFE_STRLEN(company->location)
+                                                       + SAFE_STRLEN(company->description)
+                                                       + SAFE_STRLEN(company->phonetic_name);
+                               len = 0;
+                               buf_size = SAFE_STRLEN(data) + str_len * 2 + 18;
+                               temp_data = calloc(1, buf_size);
+                               if (NULL == temp_data) {
+                                       CTS_ERR("calloc() return NULL");
+                                       free(data);
+                                       free(number);
+                                       free(*search_name);
+                                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+                               }
+
+                               char temp[str_len+1];
+
+                               if(data)
+                                       len += snprintf(temp_data + len, buf_size - len, "%s ", data);
+                               if (company->name) {
+                                       had = __ctsvc_contact_check_token(company->name, temp, SAFE_STRLEN(company->name));
+                                       len += snprintf(temp_data + len, buf_size - len, "%s %s ", company->name, had?temp:"");
+                               }
+                               if (company->department) {
+                                       had = __ctsvc_contact_check_token(company->department, temp, SAFE_STRLEN(company->department));
+                                       len += snprintf(temp_data + len, buf_size - len, "%s %s ", company->department, had?temp:"");
+                               }
+                               if (company->job_title) {
+                                       had = __ctsvc_contact_check_token(company->job_title, temp, SAFE_STRLEN(company->job_title));
+                                       len += snprintf(temp_data + len, buf_size - len, "%s %s ", company->job_title, had?temp:"");
+                               }
+                               if (company->role) {
+                                       had = __ctsvc_contact_check_token(company->role, temp, SAFE_STRLEN(company->role));
+                                       len += snprintf(temp_data + len, buf_size - len, "%s %s ", company->role, had?temp:"");
+                               }
+                               if (company->assistant_name) {
+                                       had = __ctsvc_contact_check_token(company->assistant_name, temp, SAFE_STRLEN(company->assistant_name));
+                                       len += snprintf(temp_data + len, buf_size - len, "%s %s ", company->assistant_name, had?temp:"");
+                               }
+                               if (company->location) {
+                                       had = __ctsvc_contact_check_token(company->location, temp, SAFE_STRLEN(company->location));
+                                       len += snprintf(temp_data + len, buf_size - len, "%s %s ", company->location, had?temp:"");
+                               }
+                               if (company->description) {
+                                       had = __ctsvc_contact_check_token(company->description, temp, SAFE_STRLEN(company->description));
+                                       len += snprintf(temp_data + len, buf_size - len, "%s %s ", company->description, had?temp:"");
+                               }
+                               if (company->phonetic_name) {
+                                       had = __ctsvc_contact_check_token(company->phonetic_name, temp, SAFE_STRLEN(company->phonetic_name));
+                                       len += snprintf(temp_data + len, buf_size - len, "%s %s ", company->phonetic_name, had?temp:"");
+                               }
+
+                               free(data);
+                               data = temp_data;
+                       }
+               }while(CONTACTS_ERROR_NONE == contacts_list_next(company_list));
+       }
+
+       *search_number = number;
+       if (data) {
+               *search_data = data;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_contact_refresh_lookup_data(int contact_id, ctsvc_contact_s *contact)
+{
+       int ret, len = 0, temp_len =0;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE contact_id = %d",
+                       CTS_TABLE_NAME_LOOKUP, contact_id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE contact_id = %d",
+                       CTS_TABLE_PHONE_LOOKUP, contact_id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               return ret;
+       }
+
+       if (contact == NULL)
+               return CONTACTS_ERROR_NO_DATA;
+
+       if (contact->name) {
+               contacts_list_h name_list = (contacts_list_h)contact->name;
+               ctsvc_name_s *name_record;
+               cts_stmt stmt = NULL;
+               char *temp_name = NULL;
+               contacts_list_first(name_list);
+               len = 0;
+               // name record of contact should be one
+               do {
+                       contacts_list_get_current_record_p(name_list, (contacts_record_h*)&name_record);
+                       if (NULL != name_record
+                                       && (name_record->last || name_record->first || name_record->addition || name_record->suffix)) {
+                               char *normalized_name = NULL;
+
+                               ///////////////////////////////////////////////
+                               // Make reverse display name (Last name first)
+                               // Default                       : Prefix Last, First Middle(addition), Suffix
+                               // Korean, Chinese : Prefix LastMiddleFirstSuffix
+                               // Japanese              : Prefix Last Middle First Suffix
+                               // reverse sort name does not include prefix
+                               //      But, if there is only prefix, reverse sort_name is prefix
+                               //////////////////////////////////////////////
+                               // make display name
+                               temp_len = SAFE_STRLEN(name_record->first) + SAFE_STRLEN(name_record->addition)
+                                                                       + SAFE_STRLEN(name_record->last)+ SAFE_STRLEN(name_record->suffix) + 1;
+                               int reverse_lang_type = ctsvc_contact_get_name_language(name_record);
+                               temp_name = calloc(1, temp_len);
+                               if (NULL == temp_name) {
+                                       CTS_ERR("calloc() return NULL");
+                                       break;
+                               }
+                               if (reverse_lang_type == CTSVC_LANG_KOREAN ||
+                                       reverse_lang_type == CTSVC_LANG_CHINESE ||
+                                       reverse_lang_type == CTSVC_LANG_JAPANESE) {
+                                       if(name_record->last)
+                                               len += snprintf(temp_name + len, temp_len - len, "%s", name_record->last);
+                                       if(name_record->addition)
+                                               len += snprintf(temp_name + len, temp_len - len, "%s", name_record->addition);
+                                       if(name_record->first)
+                                               len += snprintf(temp_name + len, temp_len - len, "%s", name_record->first);
+                                       if(name_record->suffix)
+                                               len += snprintf(temp_name + len, temp_len - len, "%s", name_record->suffix);
+                               }
+                               else {
+                                       if(name_record->last)
+                                               len += snprintf(temp_name + len, temp_len - len, "%s", name_record->last);
+                                       if(name_record->first)
+                                               len += snprintf(temp_name + len, temp_len - len, "%s", name_record->first);
+                                       if(name_record->addition)
+                                               len += snprintf(temp_name + len, temp_len - len, "%s", name_record->addition);
+                                       if(name_record->suffix)
+                                               len += snprintf(temp_name + len, temp_len - len, "%s", name_record->suffix);
+                               }
+
+                               ctsvc_normalize_str(temp_name, &normalized_name);
+                               snprintf(query, sizeof(query), "INSERT INTO %s(data_id, contact_id, name, type) "
+                                                               "VALUES(%d, %d, ?, %d)",        CTS_TABLE_NAME_LOOKUP, name_record->id,
+                                                               contact_id, 0);
+
+                               ret = ctsvc_query_prepare(query, &stmt);
+                               if (NULL == stmt) {
+                                       CTS_ERR("ctsvc_query_prepare() Failed(%d)", ret);
+                                       free(temp_name);
+                                       free(normalized_name);
+                                       return ret;
+                               }
+
+                               if (normalized_name)
+                                       ctsvc_stmt_bind_text(stmt, 1, normalized_name);
+
+                               ret = ctsvc_stmt_step(stmt);
+
+                               free(temp_name);
+                               free(normalized_name);
+
+                               ctsvc_stmt_finalize(stmt);
+
+                               if (CONTACTS_ERROR_NONE != ret) {
+                                       CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+                                       return ret;
+                               }
+                               break;
+                       }
+               }while(CONTACTS_ERROR_NONE == contacts_list_next(name_list));
+       }
+
+       if (contact->numbers) {
+               contacts_list_h number_list = (contacts_list_h)contact->numbers;
+               cts_stmt stmt = NULL;
+               ctsvc_number_s *number_record;
+               contacts_list_first(number_list);
+               len = 0;
+               do {
+                       contacts_list_get_current_record_p(number_list, (contacts_record_h*)&number_record);
+                       if (NULL != number_record && number_record->number) {
+                               if (NULL == number_record->cleaned)
+                                       continue;
+
+                               // actually phone_lookup minmatch is not used
+                               snprintf(query, sizeof(query), "INSERT INTO %s(data_id, contact_id, number, min_match) "
+                                                               "VALUES(%d, %d, ?, ?)", CTS_TABLE_PHONE_LOOKUP, number_record->id,
+                                                               contact_id);
+
+                               ret = ctsvc_query_prepare(query, &stmt);
+                               RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+                               if (*number_record->cleaned)
+                                       ctsvc_stmt_bind_text(stmt, 1, number_record->cleaned);
+                               ret = ctsvc_stmt_step(stmt);
+                               if (CONTACTS_ERROR_NONE != ret) {
+                                       CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+                                       ctsvc_stmt_finalize(stmt);
+                                       return ret;
+                               }
+                               if (number_record->normalized && strcmp(number_record->cleaned, number_record->normalized) != 0) {
+                                       ctsvc_stmt_reset(stmt);
+                                       if (*number_record->normalized)
+                                               ctsvc_stmt_bind_text(stmt, 1, number_record->normalized);
+                                       ret = ctsvc_stmt_step(stmt);
+                                       if (CONTACTS_ERROR_NONE != ret) {
+                                               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+                                               ctsvc_stmt_finalize(stmt);
+                                               return ret;
+                                       }
+                               }
+                               ctsvc_stmt_finalize(stmt);
+                       }
+               }while(CONTACTS_ERROR_NONE == contacts_list_next(number_list));
+       }
+
+       if (contact->nicknames) {
+               contacts_list_h nickname_list = (contacts_list_h)contact->nicknames;
+               cts_stmt stmt = NULL;
+               ctsvc_nickname_s *nickname;
+               contacts_list_first(nickname_list);
+               do {
+                       contacts_list_get_current_record_p(nickname_list, (contacts_record_h*)&nickname);
+                       if (NULL != nickname && NULL != nickname->nickname) {
+                               char *normalized_nickname = NULL;
+                               ctsvc_normalize_str(nickname->nickname, &normalized_nickname);
+                               snprintf(query, sizeof(query), "INSERT INTO %s(data_id, contact_id, name, type) "
+                                                               "VALUES(%d, %d, ?, %d)",        CTS_TABLE_NAME_LOOKUP, nickname->id,
+                                                               contact_id,  0);
+
+                               ret = ctsvc_query_prepare(query, &stmt);
+                               if (NULL == stmt) {
+                                       CTS_ERR("ctsvc_query_prepare() Failed(%d)", ret);
+                                       free(normalized_nickname);
+                                       return ret;
+                               }
+
+                               if (normalized_nickname && *normalized_nickname)
+                                       ctsvc_stmt_bind_text(stmt, 1, normalized_nickname);
+
+                               ret = ctsvc_stmt_step(stmt);
+
+                               free(normalized_nickname);
+
+                               ctsvc_stmt_finalize(stmt);
+
+                               if (CONTACTS_ERROR_NONE != ret) {
+                                       CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+                                       return ret;
+                               }
+                       }
+               }while(CONTACTS_ERROR_NONE == contacts_list_next(nickname_list));
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_contact_update_search_data(int contact_id)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       char *search_name = NULL;
+       char *search_number = NULL;
+       char *search_data = NULL;
+       ctsvc_contact_s *contact = NULL;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       ret = ctsvc_db_contact_get(contact_id, (contacts_record_h*)&contact);
+       if (CONTACTS_ERROR_NO_DATA == ret) {
+               int r;
+               snprintf(query, sizeof(query), "DELETE FROM %s WHERE contact_id = %d",
+                               CTS_TABLE_SEARCH_INDEX, contact_id);
+               r = ctsvc_query_exec(query);
+               if (CONTACTS_ERROR_NONE != r) {
+                       CTS_ERR("ctsvc_query_exec() Failed(%d)", r);
+                       return r;
+               }
+               return ret;
+       }
+       else if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_db_contact_get() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = __ctsvc_contact_make_search_data(contact_id, contact, &search_name, &search_number, &search_data);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_contact_make_search_data() Failed(%d)", ret);
+               contacts_record_destroy((contacts_record_h)contact, true);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET name=?, number=?, data=? "
+                       "WHERE contact_id = %d",
+                       CTS_TABLE_SEARCH_INDEX, contact_id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("ctsvc_query_prepare() Failed(%d)", ret);
+               contacts_record_destroy((contacts_record_h)contact, true);
+               ctsvc_end_trans(false);
+               free(search_name);
+               free(search_number);
+               free(search_data);
+               return ret;
+       }
+
+       if (search_name)
+               ctsvc_stmt_bind_text(stmt, 1, search_name);
+       if (search_number)
+               ctsvc_stmt_bind_text(stmt, 2, search_number);
+       if (search_data)
+               ctsvc_stmt_bind_text(stmt, 3, search_data);
+
+       ret = ctsvc_stmt_step(stmt);
+
+       free(search_name);
+       free(search_number);
+       free(search_data);
+
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               contacts_record_destroy((contacts_record_h)contact, true);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       // update phone_lookup, name_lookup
+       ret = __ctsvc_contact_refresh_lookup_data(contact_id, contact);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_contact_refresh_lookup_data() Failed(%d)", ret);
+               contacts_record_destroy((contacts_record_h)contact, true);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       contacts_record_destroy((contacts_record_h)contact, true);
+
+       ret = ctsvc_end_trans(true);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_end_trans() Failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_contact_update_record( contacts_record_h record )
+{
+       int ret, len = 0;
+       int rel_changed = 0;
+       int version;
+       char *set = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
+       bool is_invalid = false;
+       int current_version = 0;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+               "SELECT changed_ver FROM "CTS_TABLE_CONTACTS" "
+               "WHERE contact_id = %d AND deleted = 0", contact->id);
+       ret = ctsvc_query_get_first_int_result(query, &current_version);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("The index(%d) is Invalid. %d Record(s) is(are) found", contact->id, ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(contact->addressbook_id)) {
+               CTS_ERR("Does not have permission to update this contact");
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       if (current_version != contact->changed_ver)
+               is_invalid = true;
+       __ctsvc_contact_check_default_data(contact);
+
+       //update data
+       ret = __ctsvc_contact_update_data(contact);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_contact_update_data() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (contact->grouprelations) {
+               rel_changed = __ctsvc_contact_update_grouprel(contact->id, (contacts_list_h)contact->grouprelations);
+               if (rel_changed < CONTACTS_ERROR_NONE) {
+                       CTS_ERR("cts_update_contact_grouprel() Failed(%d)", rel_changed);
+                       ctsvc_end_trans(false);
+                       return rel_changed;
+               }
+       }
+
+       //////////////////////////////////////////////////////////////////////
+       // this code will be removed.
+       if (contact->images) {
+               int ret = CONTACTS_ERROR_NONE;
+               contacts_record_h record_image = NULL;
+               int count = 0;
+               ctsvc_image_s *image;
+
+               contacts_list_get_count((contacts_list_h)contact->images, &count);
+               if (count) {
+                       contacts_list_first((contacts_list_h)contact->images);
+                       ret = contacts_list_get_current_record_p((contacts_list_h)contact->images, &record_image);
+
+                       if (CONTACTS_ERROR_NONE != ret) {
+                               CTS_ERR("contacts_list_get_current_record_p() Failed(%d)", ret);
+                               ctsvc_end_trans(false);
+                               return CONTACTS_ERROR_DB;
+                       }
+
+                       image = (ctsvc_image_s*)record_image;
+
+                       if ((NULL == contact->image_thumbnail_path && NULL != image->path) ||
+                                       (NULL != contact->image_thumbnail_path && NULL == image->path) ||
+                                       (contact->image_thumbnail_path && image->path && 0 != strcmp(contact->image_thumbnail_path, image->path))) {
+                               ctsvc_record_set_property_flag((ctsvc_record_s *)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY);
+
+                               if (ctsvc_contact_check_image_location(image->path))
+                                       contact->image_thumbnail_path = SAFE_STRDUP(image->path + strlen(CTSVC_CONTACT_IMG_FULL_LOCATION) + 1);
+                               else
+                                       contact->image_thumbnail_path = SAFE_STRDUP(image->path);
+                       }
+               }
+               else if (contact->image_thumbnail_path) {
+                       free(contact->image_thumbnail_path);
+                       contact->image_thumbnail_path = NULL;
+                       bool is_changed = ctsvc_record_check_property_flag((ctsvc_record_s *)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY);
+                       if ((!is_changed && !is_invalid) || (is_changed && !is_invalid)) {
+                               ctsvc_record_set_property_flag((ctsvc_record_s *)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY);
+                       }
+                       else {
+                               if (((ctsvc_record_s *)record)->properties_flags) {
+                                       int index = _contacts_contact.image_thumbnail_path & 0x000000FF;
+                                       ((ctsvc_record_s *)record)->properties_flags[index] = 0;
+                               }
+                       }
+               }
+       }
+       // this code will be removed.
+       //////////////////////////////////////////////////////////////////////
+
+       if (is_invalid) {
+               ctsvc_contact_s* temp_contact;
+               contacts_record_create(_contacts_contact._uri, (contacts_record_h*)&temp_contact);
+               ret = __ctsvc_db_get_data(contact->id, temp_contact);
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "__ctsvc_db_get_data() Fail(%d)", ret);
+               ctsvc_contact_make_display_name(temp_contact);
+
+               FREEandSTRDUP(contact->display_name, temp_contact->display_name);
+               FREEandSTRDUP(contact->reverse_display_name, temp_contact->reverse_display_name);
+               FREEandSTRDUP(contact->sort_name, temp_contact->sort_name);
+               FREEandSTRDUP(contact->reverse_sort_name, temp_contact->reverse_sort_name);
+               FREEandSTRDUP(contact->sortkey, temp_contact->sortkey);
+               FREEandSTRDUP(contact->reverse_sortkey, temp_contact->reverse_sortkey);
+
+               contact->display_name_language = temp_contact->display_name_language;
+               contact->reverse_display_name_language = temp_contact->reverse_display_name_language;
+               contact->display_source_type = temp_contact->display_source_type;
+
+               if (ctsvc_record_check_property_flag((ctsvc_record_s *)temp_contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY))
+                       ctsvc_record_set_property_flag((ctsvc_record_s *)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY);
+
+               contacts_record_destroy((contacts_record_h)temp_contact, true);
+       }
+       else
+               ctsvc_contact_make_display_name(contact);
+
+       do {
+               char query[CTS_SQL_MAX_LEN] = {0};
+               char query_set[CTS_SQL_MIN_LEN] = {0, };
+               cts_stmt stmt = NULL;
+
+               version = ctsvc_get_next_ver();
+
+               ret = ctsvc_db_create_set_query(record, &set, &bind_text);
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_db_create_set_query() Failed(%d)", ret);
+
+               if (set && *set)
+                       len = snprintf(query_set, sizeof(query_set), "%s, ", set);
+               len += snprintf(query_set+len, sizeof(query_set)-len, " changed_ver=%d, changed_time=%d, has_phonenumber=%d, has_email=%d",
+                               version, (int)time(NULL), contact->has_phonenumber, contact->has_email);
+               if (ctsvc_record_check_property_flag((ctsvc_record_s *)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY)) {
+                       len += snprintf(query_set+len, sizeof(query_set)-len,
+                                       ", display_name=?, reverse_display_name=?, display_name_source=%d, "
+                                       "display_name_language=%d, reverse_display_name_language=%d, "
+                                       "sort_name=?, reverse_sort_name=?, sortkey=?, reverse_sortkey=?",
+                                       contact->display_source_type, contact->display_name_language, contact->reverse_display_name_language);
+                       bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->display_name)));
+                       bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->reverse_display_name)));
+                       bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->sort_name)));
+                       bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->reverse_sort_name)));
+                       bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->sortkey)));
+                       bind_text = g_slist_append(bind_text, strdup(SAFE_STR(contact->reverse_sortkey)));
+               }
+
+               if (ctsvc_record_check_property_flag((ctsvc_record_s *)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY))
+                       len += snprintf(query_set+len, sizeof(query_set)-len, ", image_changed_ver=%d", version);
+
+               snprintf(query, sizeof(query), "UPDATE %s SET %s WHERE contact_id = %d", CTS_TABLE_CONTACTS, query_set, contact->id);
+
+               ret = ctsvc_query_prepare(query, &stmt);
+               if (NULL == stmt) {
+                       CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+                       break;
+               }
+
+               if (bind_text) {
+                       int i = 0;
+                       for (cursor=bind_text,i=1;cursor;cursor=cursor->next,i++) {
+                               const char *text = cursor->data;
+                               if (*text)
+                                       ctsvc_stmt_bind_text(stmt, i, text);
+                       }
+               }
+               ret = ctsvc_stmt_step(stmt);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       break;
+               }
+               ctsvc_stmt_finalize(stmt);
+       } while (0);
+
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+               CONTACTS_FREE(set);
+               if (bind_text) {
+                       for (cursor=bind_text;cursor;cursor=cursor->next)
+                               CONTACTS_FREE(cursor->data);
+                       g_slist_free(bind_text);
+               }
+               return ret;
+       }
+
+       ctsvc_set_contact_noti();
+       if (0 < rel_changed)
+               ctsvc_set_group_rel_noti();
+
+       __ctsvc_contact_update_search_data(contact->id);
+       ctsvc_db_update_person((contacts_record_h)contact);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       ret = ctsvc_end_trans(true);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "DB error : ctsvc_end_trans() Failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_contact_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int len;
+       int contact_id;
+       cts_stmt stmt;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_list_h list;
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT contact_id FROM "CTS_TABLE_CONTACTS" WHERE deleted = 0");
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               contact_id = ctsvc_stmt_get_int(stmt, 0);
+               ret = ctsvc_db_contact_get(contact_id, &record);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : ctsvc_db_contact_get() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_contact_get_changed_ver(int contact_id, ctsvc_contact_s *contact)
+{
+       int ret;
+       int version;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "SELECT changed_ver FROM "CTS_TABLE_CONTACTS
+                               " WHERE contact_id = %d AND deleted = 0", contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &version);
+       if (CONTACTS_ERROR_NONE == ret)
+               contact->changed_ver = version;
+       return ret;
+}
+
+static int __ctsvc_db_contact_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_contact_s *contact;
+       char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+       bool had_contact_id = false;
+       int contact_id = 0;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       if (s_query->projection) {
+               for (i=0;i<s_query->projection_count;i++) {
+                       if (s_query->projection[i] == CTSVC_PROPERTY_CONTACT_ID) {
+                               had_contact_id = true;
+                               break;
+                       }
+               }
+       }
+       else
+               had_contact_id = true;
+
+       if (!had_contact_id) {
+               unsigned int *temp = realloc(s_query->projection, s_query->projection_count+1);
+               RETVM_IF(NULL == temp, CONTACTS_ERROR_OUT_OF_MEMORY, "realloc() return NULL");
+               s_query->projection = temp;
+               s_query->projection[s_query->projection_count] = CTSVC_PROPERTY_CONTACT_ID;
+               s_query->projection_count++;
+       }
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_contact._uri, &record);
+               contact = (ctsvc_contact_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if (CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_CONTACT_ID:
+                               contact_id = ctsvc_stmt_get_int(stmt, i);
+                               if (had_contact_id)
+                                       contact->id = contact_id;
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_DISPLAY_NAME:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               contact->display_name = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID:
+                               contact->display_source_type = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID:
+                               contact->addressbook_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_RINGTONE:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               contact->ringtone_path = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               if (temp && *temp) {
+                                       snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
+                                       contact->image_thumbnail_path = strdup(full_path);
+                               }
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_IS_FAVORITE:
+                               contact->is_favorite = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_HAS_PHONENUMBER:
+                               contact->has_phonenumber = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_HAS_EMAIL:
+                               contact->has_email = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_PERSON_ID:
+                               contact->person_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_UID:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               contact->uid = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_VIBRATION:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               contact->vibration = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_MESSAGE_ALERT:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               contact->message_alert = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_CHANGED_TIME:
+                               contact->changed_time = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_LINK_MODE:
+                               contact->link_mode = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               // get changed_ver
+               ret = __ctsvc_db_contact_get_changed_ver(contact_id, contact);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("__ctsvc_db_contact_get_changed_ver Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               ret = __ctsvc_db_get_data(contact_id, contact);
+               if (CONTACTS_ERROR_NONE != ret && CONTACTS_ERROR_NO_DATA != ret) {
+                       CTS_ERR("ctsvc_get_data_info Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               ret = __ctsvc_get_contact_grouprel(contact_id, contact);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_get_group_relations Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_contact_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_contact_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_contact_delete_records(int ids[], int count) { return CONTACTS_ERROR_NONE; }
+
+static int __ctsvc_contact_insert_data(ctsvc_contact_s *contact)
+{
+       int ret;
+
+       //Insert the name
+       if (contact->name) {
+               ret = ctsvc_contact_insert_data_name((contacts_list_h)contact->name, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_insert_data_name() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the company
+       if (contact->company) {
+               ret = ctsvc_contact_insert_data_company((contacts_list_h)contact->company, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_insert_contact_data_company() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the events
+       if (contact->events) {
+               ret = ctsvc_contact_insert_data_event((contacts_list_h)contact->events, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_insert_contact_data_event() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the messengers
+       if (contact->messengers) {
+               ret = ctsvc_contact_insert_data_messenger((contacts_list_h)contact->messengers, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_insert_contact_data_messenger() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the postals
+       if (contact->postal_addrs) {
+               ret = ctsvc_contact_insert_data_address((contacts_list_h)contact->postal_addrs, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_insert_contact_data_postal() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the Web addrs
+       if (contact->urls) {
+               ret = ctsvc_contact_insert_data_url((contacts_list_h)contact->urls, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_insert_contact_data_web() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the Nick names
+       if (contact->nicknames) {
+               ret = ctsvc_contact_insert_data_nickname((contacts_list_h)contact->nicknames, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_insert_contact_data_nickname() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the numbers
+       if (contact->numbers) {
+               ret = ctsvc_contact_insert_data_number((contacts_list_h)contact->numbers, contact->id, false);
+               if (ret < CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_contact_insert_data_number() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the emails
+       if (contact->emails) {
+               ret = ctsvc_contact_insert_data_email((contacts_list_h)contact->emails, contact->id, false);
+               if (ret < CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_insert_contact_data_email() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the profile values
+       if (contact->profiles) {
+               ret = ctsvc_contact_insert_data_profile((contacts_list_h)contact->profiles, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_insert_contact_data_profile() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the relationship values
+       if (contact->relationships) {
+               ret = ctsvc_contact_insert_data_relationship((contacts_list_h)contact->relationships, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_insert_data_relationship() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the image values
+       if (contact->images) {
+               ret = ctsvc_contact_insert_data_image((contacts_list_h)contact->images, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_insert_data_image() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the note values
+       if (contact->note) {
+               ret = ctsvc_contact_insert_data_note((contacts_list_h)contact->note, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_insert_data_note() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the extensions values
+       if (contact->extensions) {
+               ret = ctsvc_contact_insert_data_extension((contacts_list_h)contact->extensions, contact->id, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_insert_data_extension() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_contact_insert_search_data(int contact_id)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       char *search_name = NULL;
+       char *search_number = NULL;
+       char *search_data = NULL;
+       ctsvc_contact_s *contact = NULL;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "contacts_begin_trans() Failed(%d)", ret);
+
+       ret = ctsvc_db_contact_get(contact_id, (contacts_record_h*)&contact);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_db_contact_get() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = __ctsvc_contact_make_search_data(contact_id, contact, &search_name, &search_number, &search_data);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_contact_make_search_data() Failed(%d)", ret);
+               contacts_record_destroy((contacts_record_h)contact, true);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "INSERT INTO %s(contact_id, name, number, data) "
+                       "VALUES(%d, ?, ?, ?)",
+                       CTS_TABLE_SEARCH_INDEX, contact_id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("ctsvc_query_prepare() Failed(%d)", ret);
+               contacts_record_destroy((contacts_record_h)contact, true);
+               ctsvc_end_trans(false);
+               free(search_name);
+               free(search_number);
+               free(search_data);
+               return ret;
+       }
+
+       if(search_name)
+               ctsvc_stmt_bind_text(stmt, 1, search_name);
+       if(search_number)
+               ctsvc_stmt_bind_text(stmt, 2, search_number);
+       if(search_data)
+               ctsvc_stmt_bind_text(stmt, 3, search_data);
+
+       ret = ctsvc_stmt_step(stmt);
+
+       free(search_name);
+       free(search_number);
+       free(search_data);
+
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               contacts_record_destroy((contacts_record_h)contact, true);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       // update phone_lookup, name_lookup
+       ret = __ctsvc_contact_refresh_lookup_data(contact_id, contact);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_contact_refresh_lookup_data() Failed(%d)", ret);
+               contacts_record_destroy((contacts_record_h)contact, true);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       contacts_record_destroy((contacts_record_h)contact, true);
+
+       ret = ctsvc_end_trans(true);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_end_trans() Failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_contact_insert_grouprel(int contact_id, contacts_list_h group_list)
+{
+       CTS_FN_CALL;
+       ctsvc_group_relation_s *grouprel;
+       int rel_changed = 0;
+       int count;
+       int ret;
+
+       RETV_IF(NULL == group_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       ret = contacts_list_get_count(group_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(group_list);
+       do {
+               contacts_list_get_current_record_p(group_list, (contacts_record_h*)&grouprel);
+               if (NULL == grouprel)
+                       continue;
+
+               RETVM_IF(grouprel->group_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "group_id(%d) invalid", grouprel->group_id);
+               if (grouprel->group_id) {
+                       ret = ctsvc_group_add_contact_in_transaction(grouprel->group_id, contact_id);
+                       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_db_group_set_relation() Failed(%d)", ret);
+                       if (0 < ret)
+                               rel_changed += ret;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(group_list));
+
+       if (rel_changed)
+               return rel_changed;
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+inline static int __ctsvc_find_person_to_link_with_number(const char *number, int addressbook_id, int *person_id)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+       int number_len = SAFE_STRLEN(number);
+       char clean_num[number_len+1];
+
+       ret = ctsvc_clean_number(number, clean_num, sizeof(clean_num), true);
+       if (0 < ret) {
+               char normal_num[sizeof(clean_num)+20];
+               ret = ctsvc_normalize_number(clean_num, normal_num, sizeof(normal_num), true);
+               char minmatch[sizeof(normal_num)+1];
+               if (0 < ret) {
+                       ret = ctsvc_get_minmatch_number(normal_num, minmatch, sizeof(minmatch), ctsvc_get_phonenumber_min_match_digit());
+                       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_get_minmatch_number() Fail(%d)", ret);
+               }
+
+               snprintf(query, sizeof(query),
+                               "SELECT C.person_id FROM "CTS_TABLE_CONTACTS" C, "CTS_TABLE_DATA" D "
+                               "ON C.contact_id=D.contact_id AND D.datatype=%d AND C.deleted = 0 "
+                               "AND C.addressbook_id <> %d AND D.is_my_profile = 0 "
+                               "WHERE D.data4 = ?",
+                               // Below condition takes long time, so omit the condition
+                               // AND _NUMBER_COMPARE_(D.data5, ?, NULL, NULL)
+                               CTSVC_DATA_NUMBER, addressbook_id);
+
+               ret = ctsvc_query_prepare(query, &stmt);
+               RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare fail(%d)", ret);
+               ctsvc_stmt_bind_text(stmt, 1, minmatch);
+//             ctsvc_stmt_bind_text(stmt, 2, normal_num);
+               ret = ctsvc_stmt_step(stmt);
+               if (1 == ret) {
+                       *person_id = ctsvc_stmt_get_int(stmt, 0);
+                       ret = CONTACTS_ERROR_NONE;
+               }
+               else if (CONTACTS_ERROR_NONE == ret) {
+                       ret = CONTACTS_ERROR_NO_DATA;
+               }
+               ctsvc_stmt_finalize(stmt);
+               CTS_DBG("result ret(%d) person_id(%d)", ret, *person_id);
+               return ret;
+       }
+
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+inline static int __ctsvc_find_person_to_link_with_email(const char *email_addr, int addressbook_id, int *person_id)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "SELECT C.person_id FROM "CTS_TABLE_CONTACTS" C, "CTS_TABLE_DATA" D "
+                       "ON C.contact_id=D.contact_id AND D.datatype=%d AND C.deleted = 0 AND D.is_my_profile = 0 "
+                       "AND C.addressbook_id <> %d "
+                       "WHERE D.data3 = ?",
+                       CTSVC_DATA_EMAIL, addressbook_id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare fail(%d)", ret);
+
+       ctsvc_stmt_bind_text(stmt, 1, email_addr);
+       ret = ctsvc_stmt_step(stmt);
+       if (1 == ret) {
+               *person_id = ctsvc_stmt_get_int(stmt, 0);
+               ret = CONTACTS_ERROR_NONE;
+       }
+       else if (CONTACTS_ERROR_NONE == ret) {
+               ret = CONTACTS_ERROR_NO_DATA;
+       }
+
+       ctsvc_stmt_finalize(stmt);
+       CTS_DBG("result ret(%d) person_id(%d)", ret, *person_id);
+
+       return ret;
+}
+
+inline static int __ctsvc_find_person_to_link(contacts_record_h record, int addressbook_id, int *person_id)
+{
+       int ret;
+       ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
+       ctsvc_number_s *number_data;
+       ctsvc_email_s *email_data;
+       GList *cursor;
+
+       for(cursor = contact->numbers->records;cursor;cursor=cursor->next) {
+               number_data = (ctsvc_number_s *)cursor->data;
+               if (number_data && number_data->number && number_data->number[0]){
+                       ret = __ctsvc_find_person_to_link_with_number(number_data->number, addressbook_id, person_id);
+
+                       if (ret == CONTACTS_ERROR_NONE && *person_id > 0)
+                               return ret;
+               }
+       }
+
+       for(cursor = contact->emails->records;cursor;cursor=cursor->next) {
+               email_data = (ctsvc_email_s *)cursor->data;
+               if (email_data && email_data->email_addr && email_data->email_addr[0]){
+                       ret = __ctsvc_find_person_to_link_with_email(email_data->email_addr, addressbook_id, person_id);
+
+                       if (ret == CONTACTS_ERROR_NONE && *person_id > 0)
+                               return ret;
+               }
+       }
+
+       return CONTACTS_ERROR_NO_DATA;
+}
+
+static int __ctsvc_db_contact_insert_record( contacts_record_h record, int *id)
+{
+       int version;
+       int ret, person_id = 0;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       bool auto_link_enabled = true;
+       bool auto_linked = false;
+
+       ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
+       int rel_changed = 0;
+       cts_stmt stmt = NULL;
+
+       // These check should be done in client side
+       RETVM_IF(NULL == contact, CONTACTS_ERROR_INVALID_PARAMETER,
+                                       "Invalid parameter : contact is NULL");
+       RETVM_IF(contact->addressbook_id < 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : addressbook_id(%d) is mandatory field to insert contact record ", contact->addressbook_id);
+       RETVM_IF(0 < contact->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", contact->id);
+
+       if (contact->link_mode == CONTACTS_CONTACT_LINK_MODE_IGNORE_ONCE)
+               auto_link_enabled = false;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       if (false == ctsvc_have_ab_write_permission(contact->addressbook_id)) {
+               CTS_ERR("ctsvc_have_ab_write_permission fail : does not have permission(addressbook_id : %d)",
+                                       contact->addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_get_next_id(CTS_TABLE_CONTACTS);
+       if (ret < CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_db_get_next_id() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       contact->id = ret;
+       if (id)
+               *id = ret;
+
+       ctsvc_contact_make_display_name(contact);
+       __ctsvc_contact_check_default_data(contact);
+
+       //Insert Data
+       ret = __ctsvc_contact_insert_data(contact);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("cts_insert_contact_data() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       //////////////////////////////////////////////////////////////////////
+       // this code will be removed.
+       free(contact->image_thumbnail_path);
+       contact->image_thumbnail_path = NULL;
+
+       if (contact->images) {
+               ctsvc_image_s *image;
+               int count = 0;
+
+               contacts_list_get_count((contacts_list_h)contact->images, &count);
+
+               while (count) {
+                       contacts_list_first((contacts_list_h)contact->images);
+                       ret = contacts_list_get_current_record_p((contacts_list_h)contact->images, (contacts_record_h*)&image);
+                       if (CONTACTS_ERROR_NONE != ret) {
+                               CTS_ERR("contacts_list_get_current_record_p() Failed(%d)", ret);
+                               ctsvc_end_trans(false);
+                               return CONTACTS_ERROR_DB;
+                       }
+
+                       if (image->path && image->is_default) {
+                               contact->image_thumbnail_path = strdup(image->path);
+                               break;
+                       }
+                       count--;
+               }
+       }
+       // this code will be removed.
+       //////////////////////////////////////////////////////////////////////
+
+       version = ctsvc_get_next_ver();
+
+       if (contact->person_id) {
+               int id;
+
+               snprintf(query,sizeof(query),
+                                       "SELECT contact_id FROM "CTSVC_DB_VIEW_CONTACT" "
+                                               "WHERE person_id = %d", contact->person_id);
+               ret = ctsvc_query_get_first_int_result(query, &id);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("Invalid person_id(%d)", contact->person_id);
+                       ctsvc_end_trans(false);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+
+               auto_linked = true;
+       }
+       else if (auto_link_enabled) {
+               ret = __ctsvc_find_person_to_link((contacts_record_h)contact, contact->addressbook_id, &person_id);
+               CTS_DBG("__ctsvc_find_person_to_link return %d , person_id(%d)", ret, person_id);
+               if (ret == CONTACTS_ERROR_NONE && person_id > 0) {
+                       contact->person_id = person_id;
+                       auto_linked = true;
+               }
+               else {
+                       ret = ctsvc_db_insert_person((contacts_record_h)contact);
+                       CTS_DBG("ctsvc_db_insert_person return %d, person_id(%d)", ret, ret);
+                       if (ret < CONTACTS_ERROR_NONE) {
+                               CTS_ERR("ctsvc_db_insert_person() Failed(%d)", ret);
+                               ctsvc_end_trans(false);
+                               return ret;
+                       }
+                       contact->person_id = ret;
+               }
+       }
+       else {
+               ret = ctsvc_db_insert_person((contacts_record_h)contact);
+               CTS_DBG("ctsvc_db_insert_person return %d, person_id(%d)", ret, ret);
+               if (ret < CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_db_insert_person() Failed(%d)", ret);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+               contact->person_id = ret;
+       }
+
+       snprintf(query, sizeof(query),
+               "INSERT INTO "CTS_TABLE_CONTACTS"(contact_id, person_id, addressbook_id, is_favorite, "
+                       "created_ver, changed_ver, changed_time, link_mode, "
+                       "image_changed_ver, has_phonenumber, has_email, "
+                       "display_name, reverse_display_name, display_name_source, "
+                       "display_name_language, reverse_display_name_language, "
+                       "sort_name, reverse_sort_name, "
+                       "sortkey, reverse_sortkey, "
+                       "uid, ringtone_path, vibration, message_alert, image_thumbnail_path) "
+                       "VALUES(%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, ?, ?, %d, %d, %d, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+                       contact->id, contact->person_id, contact->addressbook_id, contact->is_favorite,
+                       version, version, (int)time(NULL), contact->link_mode,
+                       (NULL !=contact->image_thumbnail_path)?version:0, contact->has_phonenumber, contact->has_email,
+                       contact->display_source_type, contact->display_name_language, contact->reverse_display_name_language);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (contact->display_name)
+               ctsvc_stmt_bind_text(stmt, 1, contact->display_name);
+       if (contact->reverse_display_name)
+               ctsvc_stmt_bind_text(stmt, 2, contact->reverse_display_name);
+       if (contact->sort_name)
+               ctsvc_stmt_bind_text(stmt, 3, contact->sort_name);
+       if (contact->reverse_sort_name)
+               ctsvc_stmt_bind_text(stmt, 4, contact->reverse_sort_name);
+       if (contact->sortkey)
+               ctsvc_stmt_bind_text(stmt, 5, contact->sortkey);
+       if (contact->reverse_sortkey)
+               ctsvc_stmt_bind_text(stmt, 6, contact->reverse_sortkey);
+       if (contact->uid)
+               ctsvc_stmt_bind_text(stmt, 7, contact->uid);
+       if (contact->ringtone_path)
+               ctsvc_stmt_bind_text(stmt, 8, contact->ringtone_path);
+       if (contact->vibration)
+               ctsvc_stmt_bind_text(stmt, 9, contact->vibration);
+       if (contact->message_alert)
+               ctsvc_stmt_bind_text(stmt, 10, contact->message_alert);
+       if (contact->image_thumbnail_path)
+               ctsvc_stmt_bind_text(stmt, 11, contact->image_thumbnail_path);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       //Insert group Info
+       if (contact->grouprelations) {
+               rel_changed = __ctsvc_contact_insert_grouprel(contact->id, (contacts_list_h)contact->grouprelations);
+               if (rel_changed < CONTACTS_ERROR_NONE) {
+                       CTS_ERR("__ctsvc_contact_insert_grouprel() Failed(%d)", rel_changed);
+                       ctsvc_end_trans(false);
+                       return rel_changed;
+               }
+       }
+
+       ret = __ctsvc_contact_insert_search_data(contact->id);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("__ctsvc_contact_insert_search_data() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       // person aggregation when auto_linked
+       if (auto_linked)
+               ctsvc_person_aggregate(contact->person_id);
+
+#ifdef ENABLE_LOG_FEATURE
+       // update phonelog
+       if (contact->numbers) {
+               int count;
+               ret = contacts_list_get_count((contacts_list_h)contact->numbers, &count);
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "contacts_list_get_count() Fail(%d)", ret);
+               contacts_list_first((contacts_list_h)contact->numbers);
+               if (count > 0) {
+                       ctsvc_number_s *number_record;
+                       do {
+                               contacts_list_get_current_record_p((contacts_list_h)contact->numbers, (contacts_record_h*)&number_record);
+                               if (number_record->number)
+                                       ctsvc_db_phone_log_update_person_id(number_record->number, -1, contact->person_id, false);
+                       } while(CONTACTS_ERROR_NONE == contacts_list_next((contacts_list_h)contact->numbers));
+               }
+       }
+#endif // ENABLE_LOG_FEATURE
+       if (rel_changed)
+               ctsvc_set_group_rel_noti();
+       ctsvc_set_contact_noti();
+
+       ret = ctsvc_end_trans(true);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_svc_end_trans() Failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_contact_replace_record( contacts_record_h record, int contact_id )
+{
+       CTS_FN_CALL;
+       int ret, len;
+       int rel_changed = 0;
+       int person_id;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
+       cts_stmt stmt = NULL;
+       int version;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+               "SELECT addressbook_id, person_id FROM "CTS_TABLE_CONTACTS" "
+               "WHERE contact_id = %d AND deleted = 0", contact_id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB errror : ctsvc_query_prepare fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("The contact_id(%d) is Invalid(%d)", contact_id, ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       addressbook_id = ctsvc_stmt_get_int(stmt, 0);
+       person_id = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to replace this contact (addressbook_id : %d, contact_id : %d", addressbook_id, contact_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       contact->id = contact_id;
+       contact->person_id = person_id;
+       ctsvc_contact_make_display_name(contact);
+       __ctsvc_contact_check_default_data(contact);
+
+       //remove current child data
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE contact_id = %d", contact_id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = __ctsvc_contact_insert_data(contact);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_contact_insert_data() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       //remove current child data
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_GROUP_RELATIONS" WHERE contact_id = %d", contact_id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (contact->grouprelations) {
+               rel_changed = __ctsvc_contact_insert_grouprel(contact_id, (contacts_list_h)contact->grouprelations);
+               if (rel_changed < CONTACTS_ERROR_NONE) {
+                       CTS_ERR("__ctsvc_contact_insert_grouprel() Failed(%d)", rel_changed);
+                       ctsvc_end_trans(false);
+                       return rel_changed;
+               }
+       }
+
+       //////////////////////////////////////////////////////////////////////
+       // this code will be removed.
+       if (contact->images) {
+               int ret = CONTACTS_ERROR_NONE;
+               contacts_record_h record_image = NULL;
+               int count = 0;
+               ctsvc_image_s *image;
+
+               contacts_list_get_count((contacts_list_h)contact->images, &count);
+               if (count) {
+                       contacts_list_first((contacts_list_h)contact->images);
+                       ret = contacts_list_get_current_record_p((contacts_list_h)contact->images, &record_image);
+
+                       if (CONTACTS_ERROR_NONE != ret) {
+                               CTS_ERR("contacts_list_get_current_record_p() Failed(%d)", ret);
+                               ctsvc_end_trans(false);
+                               return CONTACTS_ERROR_DB;
+                       }
+
+                       image = (ctsvc_image_s*)record_image;
+                       if ((NULL == contact->image_thumbnail_path && NULL != image->path) ||
+                                       (NULL != contact->image_thumbnail_path && NULL == image->path) ||
+                                       (contact->image_thumbnail_path && image->path && 0 != strcmp(contact->image_thumbnail_path, image->path))) {
+                               ctsvc_record_set_property_flag((ctsvc_record_s *)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY);
+
+                               if (ctsvc_contact_check_image_location(image->path))
+                                       contact->image_thumbnail_path = SAFE_STRDUP(image->path + strlen(CTSVC_CONTACT_IMG_FULL_LOCATION) + 1);
+                               else
+                                       contact->image_thumbnail_path = SAFE_STRDUP(image->path);
+                       }
+               }
+               else if (contact->image_thumbnail_path) {
+                       free(contact->image_thumbnail_path);
+                       contact->image_thumbnail_path = NULL;
+                       if (!ctsvc_record_check_property_flag((ctsvc_record_s *)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY)) {
+                               ctsvc_record_set_property_flag((ctsvc_record_s *)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY);
+                       }
+                       else {
+                               if (((ctsvc_record_s *)record)->properties_flags) {
+                                       int index = _contacts_contact.image_thumbnail_path & 0x000000FF;
+                                       ((ctsvc_record_s *)record)->properties_flags[index] = 0;
+                               }
+                       }
+               }
+       }
+       // this code will be removed.
+       //////////////////////////////////////////////////////////////////////
+       version = ctsvc_get_next_ver();
+
+       len = snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_CONTACTS" SET changed_ver=%d, changed_time=%d, "
+                                       "has_phonenumber=%d, has_email=%d , display_name=?, "
+                                       "reverse_display_name=?, display_name_source=%d, "
+                                       "display_name_language=%d, reverse_display_name_language=%d, "
+                                       "sort_name=?, reverse_sort_name=?, "
+                                       "sortkey=?, reverse_sortkey=?, uid=?, ringtone_path=?, vibration=?, "
+                                       "message_alert =?, image_thumbnail_path=?",
+                                       version, (int)time(NULL),
+                                       contact->has_phonenumber, contact->has_email,
+                                       contact->display_source_type,
+                                       contact->display_name_language, contact->reverse_display_name_language);
+
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)contact, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY))
+               len += snprintf(query+len, sizeof(query)-len, ", image_changed_ver = %d", version);
+
+       len += snprintf(query+len, sizeof(query)-len, " WHERE contact_id=%d", contact->id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (contact->display_name)
+               ctsvc_stmt_bind_text(stmt, 1, contact->display_name);
+       if (contact->reverse_display_name)
+               ctsvc_stmt_bind_text(stmt, 2, contact->reverse_display_name);
+       if (contact->sort_name)
+               ctsvc_stmt_bind_text(stmt, 3, contact->sort_name);
+       if (contact->reverse_sort_name)
+               ctsvc_stmt_bind_text(stmt, 4, contact->reverse_sort_name);
+       if (contact->sortkey)
+               ctsvc_stmt_bind_text(stmt, 5, contact->sortkey);
+       if (contact->reverse_sortkey)
+               ctsvc_stmt_bind_text(stmt, 6, contact->reverse_sortkey);
+       if (contact->uid)
+               ctsvc_stmt_bind_text(stmt, 7, contact->uid);
+       if (contact->ringtone_path)
+               ctsvc_stmt_bind_text(stmt, 8, contact->ringtone_path);
+       if (contact->vibration)
+               ctsvc_stmt_bind_text(stmt, 9, contact->vibration);
+       if (contact->message_alert)
+               ctsvc_stmt_bind_text(stmt, 10, contact->message_alert);
+       if (contact->image_thumbnail_path)
+               ctsvc_stmt_bind_text(stmt, 11, contact->image_thumbnail_path);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       ctsvc_set_contact_noti();
+       if (0 < rel_changed)
+               ctsvc_set_group_rel_noti();
+
+       __ctsvc_contact_update_search_data(contact->id);
+       ctsvc_db_update_person((contacts_record_h)contact);
+
+       ret = ctsvc_end_trans(true);
+
+       if (ret < CONTACTS_ERROR_NONE)
+               return ret;
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
diff --git a/native/ctsvc_db_plugin_contact_helper.c b/native/ctsvc_db_plugin_contact_helper.c
new file mode 100644 (file)
index 0000000..fed3aa0
--- /dev/null
@@ -0,0 +1,2641 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <ctype.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_record.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_setting.h"
+#include "ctsvc_localize.h"
+#include "ctsvc_localize_utils.h"
+#include "ctsvc_localize_ch.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_access_control.h"
+
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_db_plugin_company_helper.h"
+#include "ctsvc_db_plugin_name_helper.h"
+#include "ctsvc_db_plugin_number_helper.h"
+#include "ctsvc_db_plugin_email_helper.h"
+#include "ctsvc_db_plugin_event_helper.h"
+#include "ctsvc_db_plugin_url_helper.h"
+#include "ctsvc_db_plugin_note_helper.h"
+#include "ctsvc_db_plugin_profile_helper.h"
+#include "ctsvc_db_plugin_address_helper.h"
+#include "ctsvc_db_plugin_nickname_helper.h"
+#include "ctsvc_db_plugin_messenger_helper.h"
+#include "ctsvc_db_plugin_relationship_helper.h"
+#include "ctsvc_db_plugin_image_helper.h"
+#include "ctsvc_db_plugin_extension_helper.h"
+
+#include "ctsvc_person.h"
+#include "ctsvc_group.h"
+
+#ifdef ENABLE_LOG_FEATURE
+#include "ctsvc_phonelog.h"
+#endif // ENABLE_LOG_FEATURE
+
+#define CTSVC_CONTACT_INITIAL_DATA_MAX_LEN 128
+
+int ctsvc_contact_add_image_file(int parent_id, int img_id,
+               char *src_img, char *dest, int dest_size)
+{
+       int ret;
+       int version;
+       char *ext;
+       char *temp;
+       char *lower_ext;
+
+       RETVM_IF(NULL == src_img, CONTACTS_ERROR_INVALID_PARAMETER, "image_thumbnail_path is NULL");
+
+       ext = strrchr(src_img, '.');
+       if (NULL == ext || strchr(ext, '/'))
+               ext = "";
+
+       lower_ext = strdup(ext);
+       RETVM_IF(NULL == lower_ext, CONTACTS_ERROR_OUT_OF_MEMORY, "strdup() return NULL");
+
+       temp = lower_ext;
+       while (*temp) {
+               *temp = tolower(*temp);
+               temp++;
+       }
+
+       version = ctsvc_get_next_ver();
+       snprintf(dest, dest_size, "%d_%d-%d%s", parent_id, img_id, version, lower_ext);
+       free(lower_ext);
+
+       ret = ctsvc_utils_copy_image(CTSVC_CONTACT_IMG_FULL_LOCATION, src_img, dest);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_utils_copy_image() Failed(%d)", ret);
+               dest[0] = '\0';
+               return ret;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_contact_get_current_image_file(int image_id, char *dest, int dest_size)
+{
+       int ret;
+       cts_stmt stmt;
+       char *tmp_path;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query), "SELECT data3 FROM %s WHERE id = %d", CTS_TABLE_DATA, image_id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("DB error: ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       tmp_path = ctsvc_stmt_get_text(stmt, 0);
+       if (tmp_path) {
+               snprintf(dest, dest_size, "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, tmp_path);
+       }
+       ctsvc_stmt_finalize(stmt);
+       return CONTACTS_ERROR_NONE;
+}
+
+// check that the image file under location or not
+// we should check CTSVC_CONTACT_IMG_FULL_LOCATION, CTSVC_VCARD_IMAGE_LOCATION, CTS_GROUP_IMAGE_LOCATION, CTS_LOGO_IMAGE_LOCATION
+bool ctsvc_contact_check_image_location(const char *path)
+{
+       int len;
+       char *slash;
+
+       if (path == NULL || *path == '\0')
+               return false;
+
+       slash = strrchr(path, '/');
+       if (slash == NULL || slash == path)
+               return false;
+
+       len = (int)(slash-path);
+       if (len != strlen(CTSVC_CONTACT_IMG_FULL_LOCATION))
+               return false;
+
+       if (strncmp(path, CTSVC_CONTACT_IMG_FULL_LOCATION, len) == 0)
+               return true;
+
+       return false;
+}
+
+int ctsvc_contact_update_image_file(int parent_id, int img_id,
+               char *src_img, char *dest_name, int dest_size)
+{
+       int ret;
+       char dest[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+
+       ret = __ctsvc_contact_get_current_image_file(img_id, dest, sizeof(dest));
+
+       WARN_IF(CONTACTS_ERROR_NONE != ret && CONTACTS_ERROR_NO_DATA != ret,
+                       "__ctsvc_contact_get_current_image_file() Failed(%d)", ret);
+       if (*dest) {
+               if (src_img && strcmp(dest, src_img) == 0) {
+                       snprintf(dest_name, dest_size, "%s", src_img + strlen(CTSVC_CONTACT_IMG_FULL_LOCATION) + 1);
+                       return CONTACTS_ERROR_NONE;
+               }
+
+               ret = unlink(dest);
+               if (ret < 0) {
+                       CTS_WARN("unlink Failed(%d)", errno);
+               }
+       }
+
+       if (src_img) {
+               ret = ctsvc_contact_add_image_file(parent_id, img_id, src_img, dest_name, dest_size);
+               RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_contact_add_image_file() Failed(%d)", ret);
+       }
+
+       return ret;
+}
+
+int ctsvc_db_contact_update_changed_time(int contact_id)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET changed_ver=%d, changed_time=%d WHERE contact_id=%d AND deleted = 0",
+                       CTS_TABLE_CONTACTS, ctsvc_get_next_ver(), (int)time(NULL), contact_id);
+
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_exec() Failed(%d)", ret);
+
+       ctsvc_set_contact_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_contact_delete_image_file_with_path(const unsigned char* image_path)
+{
+       int ret;
+
+       if (image_path) {
+               char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+               snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, image_path);
+               ret = unlink(full_path);
+               if (ret < 0) {
+                       CTS_WARN("unlink Failed(%d)", errno);
+               }
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_contact_delete(int contact_id)
+{
+       CTS_FN_CALL;
+       int ret, rel_changed;
+       int addressbook_id;
+       int person_id;
+       int link_count = 0;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt = NULL;
+       int version;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+               "SELECT addressbook_id, person_id "
+               "FROM "CTS_TABLE_CONTACTS" WHERE contact_id = %d AND deleted = 0", contact_id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       addressbook_id = ctsvc_stmt_get_int(stmt, 0);
+       person_id = ctsvc_stmt_get_int(stmt, 1);
+       CTS_DBG("addressbook_id : %d, person_id : %d", addressbook_id, person_id);
+       ctsvc_stmt_finalize(stmt);
+       stmt = NULL;
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this contact");
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       version = ctsvc_get_next_ver();
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET member_changed_ver=%d "
+                               "WHERE group_id IN (SELECT group_id FROM %s WHERE contact_id = %d AND deleted = 0) ",
+                               CTS_TABLE_GROUPS, version, CTS_TABLE_GROUP_RELATIONS, contact_id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       rel_changed = ctsvc_db_change();
+
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET deleted = 1, person_id = 0, changed_ver=%d WHERE contact_id = %d",
+                       CTS_TABLE_CONTACTS, version, contact_id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query), "SELECT link_count FROM "CTS_TABLE_PERSONS" WHERE person_id = %d", person_id);
+       ret = ctsvc_query_get_first_int_result(query, &link_count);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_get_first_int_result() Failed(%d)", ret);
+       // set dirty bit to person by trigger : person will be aggregated in ctsvc_person_aggregate
+
+       if (1 < link_count) {
+               ctsvc_person_aggregate(person_id);
+
+#ifdef ENABLE_LOG_FEATURE
+               // update phonelog
+               ctsvc_db_phone_log_update_person_id(NULL, person_id, -1, false);
+#endif // ENABLE_LOG_FEATURE
+       }
+       else
+               ctsvc_set_person_noti();
+
+       ctsvc_set_contact_noti();
+       if (rel_changed > 0)
+               ctsvc_set_group_rel_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static inline void __ctsvc_contact_get_initial(char *src, char *dest, int dest_size, bool pinyin )
+{
+       int i, j=0;
+       bool bFirst = true;
+       int len = strlen(src);
+       for(i = 0; i < len && j < (dest_size-1);)
+       {
+               if (src[i] == ' ') {
+                       bFirst=true;
+                       i++;
+               } else if (bFirst) {
+                       int char_len = ctsvc_check_utf8(src[i]);
+                       int k;
+                       for (k=0;k<char_len && j < (dest_size-1) ;k++)
+                               dest[j++] = src[i++];
+                       if (!pinyin && j < (dest_size-1))
+                               dest[j++] = ' ';
+                       bFirst = false;
+               }
+               else
+                       i++;
+       }
+}
+
+static inline void __ctsvc_remove_space(char *src, char *dest, int dest_size)
+{
+       int len = strlen(src);
+       int i, j=0;
+
+       for(i=0; i < len && i < dest_size; i++) {
+               if (src[i] && src[i] != ' ') {
+                       dest[j] = src[i];
+                       j++;
+               }
+       }
+       dest[j] = '\0';
+}
+
+/* make search name to insert search_index table name column
+ * korean : display_name, chosung, phonetic
+ * japanese : dislay_name(hiragana), phonetic
+ *                             if display_name is chinese and sort_name(phonetic) is japanese,
+ *                                     then search_name is normalized_name and sort_name (phonetic)
+ * chinese : display_name, pinyin name, pinyin initial, phonetic
+ * others : display_name, phonetic
+ */
+int ctsvc_contact_make_search_name(ctsvc_contact_s *contact, char **search_name) {
+       char *name = NULL;
+       char *temp_name = NULL;
+       int buf_size, ret;
+       RETV_IF(NULL == search_name, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       if (contact->display_name) {
+               if (ctsvc_has_chinese(contact->display_name)) {
+                       if (CTSVC_LANG_JAPANESE == ctsvc_check_language_type(contact->sort_name)) {
+                               char *normalized_display_name=NULL;
+
+                               ctsvc_normalize_str(contact->display_name, &normalized_display_name);
+                               if (normalized_display_name) {
+                                       buf_size = SAFE_STRLEN(normalized_display_name) + strlen(contact->sort_name) + 2;
+                                       name = calloc(1, buf_size);
+                                       RETVM_IF(NULL == name, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+                                       snprintf(name, buf_size, "%s %s", normalized_display_name, contact->sort_name);
+                                       free(normalized_display_name);
+                               }
+                       }
+                       else {
+                               char *langset = ctsvc_get_langset();
+                               if (strncmp(langset, "zh_CN", strlen("zh_CN")) == 0) {
+                                       pinyin_name_s *pinyinname;
+                                       int size, i, len;
+
+                                       ret = ctsvc_convert_chinese_to_pinyin(contact->display_name, &pinyinname, &size);
+                                       if (CONTACTS_ERROR_NONE == ret) {
+                                               int name_len = (CHINESE_PINYIN_SPELL_MAX_LEN*strlen(contact->display_name)+1) * sizeof(char);
+                                               char *name_nospace = calloc(1, name_len);
+                                               if (NULL == name_nospace) {
+                                                       CTS_ERR("calloc() return NULL");
+                                                       ctsvc_pinyin_free(pinyinname, size);
+                                                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+                                               }
+                                               char *temp_name = NULL;
+
+                                               ctsvc_normalize_str(contact->display_name, &name);
+                                               if (name) {
+                                                       for(i=0; i<size; i++) {
+                                                               __ctsvc_remove_space(pinyinname[i].pinyin_name, name_nospace, name_len);
+
+                                                               buf_size = SAFE_STRLEN(name)
+                                                                                                       + SAFE_STRLEN(pinyinname[i].pinyin_name)
+                                                                                                       + SAFE_STRLEN(name_nospace)
+                                                                                                       + SAFE_STRLEN(pinyinname[i].pinyin_initial)
+                                                                                                       + 4;
+                                                               temp_name = calloc(1, buf_size);
+                                                               if (NULL == temp_name) {
+                                                                       CTS_ERR("calloc() return NULL");
+                                                                       free(name_nospace);
+                                                                       ctsvc_pinyin_free(pinyinname, size);
+                                                                       free(name);
+                                                                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+                                                               }
+
+                                                               snprintf(temp_name, buf_size, "%s %s %s %s",
+                                                                               name, pinyinname[i].pinyin_name, name_nospace, pinyinname[i].pinyin_initial);
+                                                               free(name);
+                                                               name = temp_name;
+                                                       }
+                                               }
+
+                                               len = ctsvc_check_utf8(contact->display_name[0]);
+                                               for(i=len; i < strlen(contact->display_name); i+=len) {
+                                                       len = ctsvc_check_utf8(contact->display_name[i]);
+
+                                                       buf_size = SAFE_STRLEN(name) + SAFE_STRLEN(&contact->display_name[i]) + 2;
+                                                       temp_name = calloc(1, buf_size);
+                                                       if (NULL == temp_name) {
+                                                               CTS_ERR("calloc() return NULL");
+                                                               free(name_nospace);
+                                                               ctsvc_pinyin_free(pinyinname, size);
+                                                               free(name);
+                                                               return CONTACTS_ERROR_OUT_OF_MEMORY;
+                                                       }
+
+                                                       snprintf(temp_name, buf_size, "%s %s", name, &contact->display_name[i]);
+
+                                                       free(name);
+                                                       name = temp_name;
+                                               }
+
+                                               free(name_nospace);
+                                               ctsvc_pinyin_free(pinyinname, size);
+                                       }
+                                       else {
+                                               char initial[CTSVC_CONTACT_INITIAL_DATA_MAX_LEN] = {0,};
+                                               char *normalized_display_name = NULL;
+
+                                               ctsvc_normalize_str(contact->display_name, &normalized_display_name);
+                                               if (normalized_display_name) {
+                                                       __ctsvc_contact_get_initial(contact->display_name, initial, sizeof(initial), false);
+                                                       buf_size = SAFE_STRLEN(normalized_display_name) + strlen(initial) + 2;
+                                                       name = calloc(1, buf_size);
+                                                       if (NULL == name) {
+                                                               CTS_ERR("calloc() return NULL");
+                                                               free(normalized_display_name);
+                                                               return CONTACTS_ERROR_OUT_OF_MEMORY;
+                                                       }
+                                                       snprintf(name, buf_size, "%s %s", normalized_display_name, initial);
+
+                                                       free(normalized_display_name);
+                                               }
+                                       }
+                               }
+                               else {
+                                       char initial[CTSVC_CONTACT_INITIAL_DATA_MAX_LEN] = {0,};
+                                       char *normalized_display_name = NULL;
+
+                                       ctsvc_normalize_str(contact->display_name, &normalized_display_name);
+                                       if (normalized_display_name) {
+                                               __ctsvc_contact_get_initial(contact->display_name, initial, sizeof(initial), false);
+                                               buf_size = SAFE_STRLEN(normalized_display_name) + strlen(initial) + 2;
+                                               name = calloc(1, buf_size);
+                                               if (NULL == name) {
+                                                       CTS_ERR("calloc() return NULL");
+                                                       free(normalized_display_name);
+                                                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+                                               }
+
+                                               snprintf(name, buf_size, "%s %s", normalized_display_name, initial);
+
+                                               free(normalized_display_name);
+                                       }
+                               }
+                       }
+               }
+               else if (ctsvc_has_korean(contact->display_name)) {
+                       // 'a가' should be searched by 'ㄱ'
+                       int count, i, j;
+                       int full_len, chosung_len;
+                       char *chosung = calloc(1, strlen(contact->display_name) * 5);
+                       if (NULL == chosung) {
+                               CTS_ERR("calloc() return NULL");
+                               return CONTACTS_ERROR_OUT_OF_MEMORY;
+                       }
+                       int total_len = strlen(contact->display_name);
+
+                       count = ctsvc_get_chosung(contact->display_name, chosung, strlen(contact->display_name) * 5 );
+
+                       ctsvc_normalize_str(contact->display_name, &name);
+
+                       if (count > 0) {
+                               for(i=0, j=0; i < total_len; i+=full_len, j+=chosung_len) {
+                                       full_len = ctsvc_check_utf8(contact->display_name[i]);
+                                       chosung_len = ctsvc_check_utf8(chosung[j]);
+
+                                       buf_size = SAFE_STRLEN(name) + SAFE_STRLEN(&contact->display_name[i]) + SAFE_STRLEN(&chosung[j]) + 3;
+                                       temp_name = calloc(1, buf_size);
+                                       if (NULL == temp_name) {
+                                               CTS_ERR("calloc() return NULL");
+                                               free(name);
+                                               free(chosung);
+                                               return CONTACTS_ERROR_OUT_OF_MEMORY;
+                                       }
+
+                                       snprintf(temp_name, buf_size, "%s %s %s", name, &contact->display_name[i], &chosung[j]);
+
+                                       free(name);
+                                       name = temp_name;
+                               }
+                       }
+                       free(chosung);
+               }
+               else if (CTSVC_LANG_JAPANESE == ctsvc_check_language_type(contact->display_name)) {
+                       ctsvc_convert_japanese_to_hiragana(contact->display_name, &name);
+               }
+               else {
+                       // Insert 'ABO Â' for 'ÂBC'
+                       char initial[CTSVC_CONTACT_INITIAL_DATA_MAX_LEN] = {0,};
+                       char *normalized_display_name=NULL;
+
+                       ctsvc_normalize_str(contact->display_name, &normalized_display_name);
+                       if (normalized_display_name) {
+                               __ctsvc_contact_get_initial(contact->display_name, initial, sizeof(initial), false);
+                               buf_size = SAFE_STRLEN(normalized_display_name) + strlen(initial) + 2;
+                               name = calloc(1, buf_size);
+                               if (NULL == name) {
+                                       CTS_ERR("calloc() return NULL");
+                                       free(normalized_display_name);
+                                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+                               }
+                               snprintf(name, buf_size, "%s %s", normalized_display_name, initial);
+
+                               free(normalized_display_name);
+                       }
+               }
+       }
+
+       // append phonetic name
+       if (contact->name) {
+               contacts_list_h name_list = (contacts_list_h)contact->name;
+               ctsvc_name_s *name_record;
+               contacts_list_first(name_list);
+               char *phonetic = NULL;
+               int temp_len = 0;
+
+               contacts_list_get_current_record_p(name_list, (contacts_record_h*)&name_record);
+               if (NULL != name_record) {
+                       buf_size = SAFE_STRLEN(name_record->phonetic_first) + SAFE_STRLEN(name_record->phonetic_last) + SAFE_STRLEN(name_record->phonetic_middle);
+                       if (buf_size > 0) {
+                               buf_size += 3; // for space and null string
+                               phonetic = calloc(1, buf_size);
+                               if (NULL == phonetic) {
+                                       CTS_ERR("calloc() return NULL");
+                                       free(name);
+                                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+                               }
+
+                               if (name_record->phonetic_first)
+                                       temp_len += snprintf(phonetic, buf_size, "%s", name_record->phonetic_first);
+                               if (name_record->phonetic_middle) {
+                                       if (temp_len)
+                                               temp_len += snprintf(phonetic + temp_len, buf_size - temp_len, " ");
+                                       temp_len += snprintf(phonetic + temp_len, buf_size - temp_len, "%s", name_record->phonetic_middle);
+                               }
+                               if (name_record->phonetic_last) {
+                                       if (temp_len)
+                                               temp_len += snprintf(phonetic + temp_len, buf_size - temp_len, " ");
+                                       temp_len += snprintf(phonetic + temp_len, buf_size - temp_len, "%s", name_record->phonetic_last);
+                               }
+
+                               if (name) {
+                                       buf_size = SAFE_STRLEN(name) + SAFE_STRLEN(phonetic) + 2;
+                                       temp_name = calloc(1, buf_size);
+                                       if (NULL == temp_name) {
+                                               CTS_ERR("calloc() return NULL");
+                                               free(phonetic);
+                                               free(name);
+                                               return CONTACTS_ERROR_OUT_OF_MEMORY;
+                                       }
+                                       snprintf(temp_name, buf_size, "%s %s", name, phonetic);
+                                       free(name);
+                                       name = temp_name;
+                                       free(phonetic);
+                               }
+                               else
+                                       name = phonetic;
+                       }
+               }
+       }
+
+       *search_name = name;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_make_phonetic_name(ctsvc_name_s* name, char** phonetic, contacts_name_display_order_e order)
+{
+       int len = SAFE_STRLEN(name->phonetic_first) + SAFE_STRLEN(name->phonetic_last) + SAFE_STRLEN(name->phonetic_middle);
+       if( len > 0 )
+       {
+               len += 3; // for space and null string
+               *phonetic = calloc(1, len);
+               RETVM_IF(NULL == *phonetic, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+
+               int temp_len = 0;
+               if ( order == CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST ) {
+                       if (name->phonetic_first)
+                               temp_len += snprintf(*phonetic, len, "%s", name->phonetic_first);
+                       if (name->phonetic_middle) {
+                               if (temp_len)
+                                       temp_len += snprintf(*phonetic + temp_len, len - temp_len, " ");
+                               temp_len += snprintf(*phonetic + temp_len, len - temp_len, "%s", name->phonetic_middle);
+                       }
+                       if (name->phonetic_last) {
+                               if (temp_len)
+                                       temp_len += snprintf(*phonetic + temp_len, len - temp_len, " ");
+                               temp_len += snprintf(*phonetic + temp_len, len - temp_len, "%s", name->phonetic_last);
+                       }
+               }
+               else {
+                       if (name->phonetic_last)
+                               temp_len += snprintf(*phonetic, len, "%s", name->phonetic_last);
+                       if (name->phonetic_middle) {
+                               if (temp_len)
+                                       temp_len += snprintf(*phonetic + temp_len, len - temp_len, " ");
+                               temp_len += snprintf(*phonetic + temp_len, len - temp_len, "%s", name->phonetic_middle);
+                       }
+                       if (name->phonetic_first) {
+                               if (temp_len)
+                                       temp_len += snprintf(*phonetic + temp_len, len - temp_len, " ");
+                               temp_len += snprintf(*phonetic + temp_len, len - temp_len, "%s", name->phonetic_first);
+                       }
+               }
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_get_sort_name_to_pinyin(const char *display_name, char **sort_name) {
+       int ret;
+       int size;
+       pinyin_name_s *pinyinname = NULL;
+       *sort_name = NULL;
+
+       if (false == ctsvc_has_chinese(display_name))
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+
+       ret = ctsvc_convert_chinese_to_pinyin(display_name, &pinyinname, &size);
+
+       if (ret == CONTACTS_ERROR_NONE) {
+               char temp[strlen(display_name) * 2 + strlen(pinyinname[0].pinyin_name)];
+               int pinyin_index = 0;
+               int name_index = 0;
+               int temp_index = 0;
+
+               while(1) {
+                       int pinyin_len = 0;
+                       int name_len = 0;
+
+                       if (pinyinname[0].pinyin_name[pinyin_index] == '\0') {
+                               if (display_name[name_index] != '\0') {
+                                       temp[temp_index] = ' ';
+                                       temp_index++;
+                                       name_len = ctsvc_check_utf8(display_name[name_index]);
+                                       if (name_len > 0) {
+                                               memcpy(&(temp[temp_index]), &(display_name[name_index]), name_len);
+                                               temp_index += name_len;
+                                               name_index += name_len;
+                                       }
+                               }
+                               break;
+                       }
+                       pinyin_len = ctsvc_check_utf8(pinyinname[0].pinyin_name[pinyin_index]);
+                       if (pinyin_len <= 0)
+                               break;
+                       memcpy(&(temp[temp_index]), &(pinyinname[0].pinyin_name[pinyin_index]), pinyin_len);
+                       temp_index += pinyin_len;
+
+                       if (pinyinname[0].pinyin_name[pinyin_index] == ' ') {
+                               name_len = ctsvc_check_utf8(display_name[name_index]);
+                               if (name_len <= 0)
+                                       break;
+
+                               if (name_len == 1 && display_name[name_index] == ' ') {
+                                       temp[temp_index] = ' ';
+                                       temp_index++;
+                                       pinyin_index++;
+                               }
+                               memcpy(&(temp[temp_index]), &(display_name[name_index]), name_len);
+                               temp_index += name_len;
+                               name_index += name_len;
+                               temp[temp_index] = ' ';
+                               temp_index++;
+                       }
+
+                       pinyin_index += pinyin_len;
+               }
+               temp[temp_index] = '\0';
+               *sort_name = strdup(temp);
+               ctsvc_pinyin_free(pinyinname, size);
+       }
+       return ret;
+}
+
+void ctsvc_contact_make_sortkey(ctsvc_contact_s *contact)
+{
+       int ret;
+       char *sortkey = NULL;
+       char *phonetic = NULL;
+       int sort_type = -1;
+
+       if (contact->display_source_type == CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME) {
+               if ( contact->name->count > 0 && contact->name->records != NULL
+                               && contact->name->records->data != NULL ) {
+                       ctsvc_name_s *name = (ctsvc_name_s *)contact->name->records->data;
+                       ret = __ctsvc_make_phonetic_name(name, &phonetic, CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST);
+                       RETM_IF(CONTACTS_ERROR_NONE != ret, "__ctsvc_make_phonetic_name() Fail(%d)", ret);
+               }
+       }
+
+       if (phonetic)
+               sort_type = ctsvc_get_name_sort_type(phonetic);
+       else if (contact->sort_name)
+               sort_type = ctsvc_get_name_sort_type(contact->sort_name);
+       else
+               sort_type = CTSVC_SORT_OTHERS;
+
+       WARN_IF(sort_type < 0, "ctsvc_get_name_sort_type Failed(%d)", sort_type);
+       char *langset = ctsvc_get_langset();
+
+       switch (sort_type) {
+       case CTSVC_SORT_CJK:
+               {
+                       if (strncmp(langset, "zh_CN", strlen("zh_CN")) == 0) { // chinese to pinyin
+                               char *pinyin = NULL;
+                               if (phonetic)
+                                       __ctsvc_get_sort_name_to_pinyin(phonetic, &pinyin);
+                               else
+                                       __ctsvc_get_sort_name_to_pinyin(contact->sort_name, &pinyin);
+
+                               if (pinyin) {
+                                       free(contact->sort_name);
+                                       contact->sort_name = pinyin;
+                                       sort_type = CTSVC_SORT_WESTERN;
+                               }
+                       }
+                       else if (strncmp(langset, "ko_KR", strlen("ko_KR")) == 0) {
+                                       sort_type = CTSVC_SORT_KOREAN;
+                       }
+               }
+               break;
+       case CTSVC_SORT_JAPANESE:
+               {
+                       char *hiragana = NULL;
+                       ctsvc_convert_japanese_to_hiragana(contact->sort_name, &hiragana);
+
+                       if (hiragana) {
+                               free(contact->sort_name);
+                               contact->sort_name = hiragana;
+                       }
+                       break;
+               }
+       default:
+               {
+                       if( phonetic )
+                               FREEandSTRDUP(contact->sort_name, phonetic);
+               }
+               break;
+       }
+
+       free(phonetic);
+       phonetic = NULL;
+
+       if (ctsvc_get_primary_sort() == sort_type)
+               contact->display_name_language = CTSVC_SORT_PRIMARY;
+       else if (ctsvc_get_secondary_sort() == sort_type)
+               contact->display_name_language = CTSVC_SORT_SECONDARY;
+       else if (sort_type < 0)
+               contact->display_name_language = CTSVC_SORT_OTHERS;
+       else
+               contact->display_name_language = sort_type;
+
+       // check reverse sort_name, reverser_display_name_language
+       // make reverse phonetic name
+       if (contact->display_source_type == CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME) {
+               if ( contact->name->count > 0 && contact->name->records != NULL
+                               && contact->name->records->data != NULL ) {
+                       ctsvc_name_s *name = (ctsvc_name_s *)contact->name->records->data;
+                       ret = __ctsvc_make_phonetic_name(name, &phonetic, CONTACTS_NAME_DISPLAY_ORDER_LASTFIRST);
+                       RETM_IF(CONTACTS_ERROR_NONE != ret, "__ctsvc_make_phonetic_name() Fail(%d)", ret);
+               }
+       }
+
+       if (phonetic)
+               sort_type = ctsvc_get_name_sort_type(phonetic);
+       else if (contact->reverse_sort_name)
+               sort_type = ctsvc_get_name_sort_type(contact->reverse_sort_name);
+       else
+               sort_type = CTSVC_SORT_OTHERS;
+
+       WARN_IF( sort_type < 0, "ctsvc_get_name_sort_type Failed(%d)", sort_type);
+
+       switch (sort_type)
+       {
+       case CTSVC_SORT_CJK:
+               {
+                       if (strncmp(langset, "zh_CN", strlen("zh_CN")) == 0) {
+                               char *pinyin = NULL;
+                               if (phonetic)
+                                       __ctsvc_get_sort_name_to_pinyin(phonetic, &pinyin);
+                               else
+                                       __ctsvc_get_sort_name_to_pinyin(contact->reverse_sort_name, &pinyin);
+
+                               if (pinyin) {
+                                       free(contact->reverse_sort_name);
+                                       contact->reverse_sort_name = pinyin;
+                                       sort_type = CTSVC_SORT_WESTERN;
+                               }
+                       }
+                       else if (strncmp(langset, "ko_KR", strlen("ko_KR")) == 0) {
+                                       sort_type = CTSVC_SORT_KOREAN;
+                       }
+               }
+               break;
+       case CTSVC_SORT_JAPANESE:
+               {
+                       char *hiragana = NULL;
+                       ctsvc_convert_japanese_to_hiragana(contact->reverse_sort_name, &hiragana);
+
+                       if (hiragana) {
+                               free(contact->reverse_sort_name);
+                               contact->reverse_sort_name = hiragana;
+                       }
+               }
+               break;
+       default:
+               {
+                       if( phonetic )
+                               FREEandSTRDUP(contact->reverse_sort_name, phonetic);
+               }
+               break;
+       }
+
+       free(phonetic);
+       phonetic = NULL;
+
+       if (ctsvc_get_primary_sort() == sort_type)
+               contact->reverse_display_name_language = CTSVC_SORT_PRIMARY;
+       else if (ctsvc_get_secondary_sort() == sort_type)
+               contact->reverse_display_name_language = CTSVC_SORT_SECONDARY;
+       else if (sort_type < 0)
+               contact->reverse_display_name_language = CTSVC_SORT_OTHERS;
+       else
+               contact->reverse_display_name_language = sort_type;
+
+       if (contact->sort_name) {
+               sort_type = ctsvc_collation_str(contact->sort_name, &sortkey);
+               if (CONTACTS_ERROR_NONE == sort_type)
+                       contact->sortkey = sortkey;
+               else
+                       free(sortkey);
+       }
+
+       sortkey = NULL;
+
+       if (contact->reverse_sort_name) {
+               sort_type = ctsvc_collation_str(contact->reverse_sort_name, &sortkey);
+               if (CONTACTS_ERROR_NONE == sort_type)
+                       contact->reverse_sortkey = sortkey;
+               else
+                       free(sortkey);
+       }
+}
+
+static bool __ctsvc_contact_check_name_has_korean(const ctsvc_name_s *name)
+{
+       if (name->first && ctsvc_has_korean(name->first))
+               return true;
+       else if (name->last && ctsvc_has_korean(name->last))
+               return true;
+       else if (name->addition && ctsvc_has_korean(name->addition))
+               return true;
+       else if (name->prefix && ctsvc_has_korean(name->prefix))
+               return true;
+       else if (name->suffix && ctsvc_has_korean(name->suffix))
+               return true;
+
+       return false;
+}
+
+static bool __ctsvc_contact_check_name_has_japanese(const ctsvc_name_s *name)
+{
+       if (name->first && ctsvc_check_language_type(name->first) == CTSVC_LANG_JAPANESE)
+               return true;
+       else if (name->addition && ctsvc_check_language_type(name->addition) == CTSVC_LANG_JAPANESE)
+               return true;
+       else if (name->last && ctsvc_check_language_type(name->last) == CTSVC_LANG_JAPANESE)
+               return true;
+
+       return false;
+}
+
+static bool __ctsvc_contact_check_name_has_chinese(const ctsvc_name_s *name)
+{
+       if (name->first && ctsvc_check_language_type(name->first) == CTSVC_LANG_CHINESE)
+               return true;
+       else if (name->addition && ctsvc_check_language_type(name->addition) == CTSVC_LANG_CHINESE)
+               return true;
+       else if (name->last && ctsvc_check_language_type(name->last) == CTSVC_LANG_CHINESE)
+               return true;
+
+       return false;
+}
+
+int ctsvc_contact_get_name_language(const ctsvc_name_s *name)
+{
+       int lang = -1;
+       if (__ctsvc_contact_check_name_has_korean(name))
+               lang = CTSVC_LANG_KOREAN;
+       else if (__ctsvc_contact_check_name_has_japanese(name))
+               lang = CTSVC_LANG_JAPANESE;
+       else if (__ctsvc_contact_check_name_has_chinese(name))
+               lang = CTSVC_LANG_CHINESE;
+       else {
+               if (name->last)
+                       lang =  ctsvc_check_language_type(name->last);
+               else if (name->first)
+                       lang =  ctsvc_check_language_type(name->first);
+               else if (name->addition)
+                       lang =  ctsvc_check_language_type(name->addition);
+       }
+
+       return lang;
+}
+
+char * __ctsvc_remove_first_space(char *src)
+{
+       if(src == NULL ||SAFE_STRLEN(src) == 0)
+               return NULL;
+
+       int name_len = (SAFE_STRLEN(src)+1)*sizeof(char);
+       char *name_nospace = NULL;
+       name_nospace = calloc(1, name_len);
+       RETVM_IF(NULL == name_nospace, NULL, "calloc() return NULL");
+
+       int len = strlen(src);
+       int i =0;
+
+       for(i=0; i < len && i < name_len; i++) {
+               if (src[i] && src[i] != ' ') {
+                       strncpy(name_nospace, src+i, name_len);
+                       break;
+               }
+       }
+       return name_nospace;
+}
+// Make display_name, sort_name, sortkey of the contact by name record
+// If the contact record does not have name record,
+// we use company, nickname, number, email record in order
+void ctsvc_contact_make_display_name(ctsvc_contact_s *contact)
+{
+       int len;
+       ctsvc_name_s *name = NULL;
+
+       free(contact->display_name);
+       contact->display_name = NULL;
+
+       free(contact->reverse_display_name);
+       contact->reverse_display_name = NULL;
+
+       free(contact->sort_name);
+       contact->sort_name = NULL;
+
+       free(contact->reverse_sort_name);
+       contact->reverse_sort_name = NULL;
+
+       free(contact->sortkey);
+       contact->sortkey = NULL;
+
+       free(contact->reverse_sortkey);
+       contact->reverse_sortkey = NULL;
+
+       contact->display_name_language = CTSVC_SORT_OTHERS;
+       contact->reverse_display_name_language = CTSVC_SORT_OTHERS;
+
+       contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_INVALID;
+
+       if ( contact->name->count > 0 && contact->name->records != NULL && contact->name->records->data != NULL )
+       {
+               name = (ctsvc_name_s *)contact->name->records->data;
+       }
+
+       if ( name && ( name->first || name->last || name->prefix || name->addition || name->suffix) ) {
+               int reverse_lang_type = -1;
+               int display_len;
+               int temp_display_len;
+               char *display = NULL;
+               char *temp_display = NULL;
+
+               ///////////////////////////////////////////////
+               // Make reverse display name (Last name first)
+               // Default         : Prefix Last, First Middle(addition), Suffix
+               // Korean, Chinese : Prefix LastMiddleFirstSuffix
+               // Japanese        : Prefix Last Middle First Suffix
+               // reverse sort name does not include prefix
+               //    But, if there is only prefix, reverse sort_name is prefix
+               //////////////////////////////////////////////
+               temp_display_len = SAFE_STRLEN(name->first)
+                                               + SAFE_STRLEN(name->addition)
+                                               + SAFE_STRLEN(name->last)
+                                               + SAFE_STRLEN(name->suffix);
+               if (0 < temp_display_len) {
+                       temp_display_len += 7;
+                       temp_display = calloc(1, temp_display_len);
+                       RETM_IF(NULL == temp_display, "calloc() return NULL");
+                       len=0;
+
+                       // get language type
+                       reverse_lang_type = ctsvc_contact_get_name_language(name);
+                       if(name->last) {
+                               char * temp = __ctsvc_remove_first_space(name->last);
+                               len += snprintf(temp_display + len, temp_display_len - len, "%s", temp);
+                               free(temp);
+                               if (reverse_lang_type != CTSVC_LANG_KOREAN &&
+                                               reverse_lang_type != CTSVC_LANG_CHINESE &&
+                                               reverse_lang_type != CTSVC_LANG_JAPANESE) {
+                                       if(name->first || name->addition)
+                                               len += snprintf(temp_display + len, temp_display_len - len, ",");
+                               }
+                       }
+
+                       if(reverse_lang_type == CTSVC_LANG_JAPANESE) {
+                               // make temp_display name Prefix - Last - Middle - First - Suffix
+                               if(name->addition) {
+                                       char * temp = __ctsvc_remove_first_space(name->addition);
+                                       if (*temp_display)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", temp);
+                                       free(temp);
+                               }
+
+                               if(name->first) {
+                                       char * temp = __ctsvc_remove_first_space(name->first);
+                                       if (*temp_display)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", temp);
+                                       free(temp);
+                               }
+                       }
+                       else if (reverse_lang_type == CTSVC_LANG_CHINESE || reverse_lang_type == CTSVC_LANG_KOREAN) {
+                               if(name->addition) {
+                                       char * temp = __ctsvc_remove_first_space(name->addition);
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", temp);
+                                       free(temp);
+                               }
+
+                               if(name->first) {
+                                       char * temp = __ctsvc_remove_first_space(name->first);
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", temp);
+                                       free(temp);
+                               }
+                       }
+                       else {
+                               // make temp_display name Prefix - Last - First - Middle - Suffix
+                               if(name->first) {
+                                       if (*temp_display) {
+                                               if (reverse_lang_type < 0) {
+                                                       reverse_lang_type = ctsvc_check_language_type(temp_display);
+                                               }
+
+                                               if (reverse_lang_type != CTSVC_LANG_KOREAN &&
+                                                               reverse_lang_type != CTSVC_LANG_CHINESE)
+                                                       len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       }
+                                       char * temp = __ctsvc_remove_first_space(name->first);
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", temp);
+                                       free(temp);
+                               }
+
+                               if(name->addition) {
+                                       if (*temp_display) {
+                                               if (reverse_lang_type < 0) {
+                                                       reverse_lang_type = ctsvc_check_language_type(temp_display);
+                                               }
+
+                                               if (reverse_lang_type != CTSVC_LANG_KOREAN &&
+                                                               reverse_lang_type != CTSVC_LANG_CHINESE)
+                                                       len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       }
+                                       char * temp = __ctsvc_remove_first_space(name->addition);
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", temp);
+                                       free(temp);
+                               }
+                       }
+
+                       if(name->suffix) {
+                               if (*temp_display) {
+                                       if (reverse_lang_type < 0) {
+                                               reverse_lang_type = ctsvc_check_language_type(temp_display);
+                                       }
+
+                                       if (reverse_lang_type == CTSVC_LANG_JAPANESE)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       else if (reverse_lang_type != CTSVC_LANG_KOREAN &&
+                                                               reverse_lang_type != CTSVC_LANG_CHINESE)
+                                               len += snprintf(temp_display + len, temp_display_len - len, ", ");
+                               }
+                               char * temp = __ctsvc_remove_first_space(name->suffix);
+                               len += snprintf(temp_display + len, temp_display_len - len, "%s", temp);
+                               free(temp);
+                       }
+               }
+
+               if(name->prefix && temp_display) {
+                       display_len = SAFE_STRLEN(name->prefix) + temp_display_len + 2;
+                       display = calloc(1, display_len);
+                       if (NULL == display) {
+                               CTS_ERR("calloc() return NULL");
+                               free(temp_display);
+                               return;
+                       }
+                       char * temp = __ctsvc_remove_first_space(name->prefix);
+                       snprintf(display, display_len , "%s %s", temp, temp_display);
+                       free(temp);
+                       contact->reverse_display_name = display;
+                       contact->reverse_sort_name = temp_display;
+               }
+               else if (temp_display) {
+                       contact->reverse_display_name = temp_display;
+                       contact->reverse_sort_name = strdup(temp_display);
+                       RETM_IF(NULL == contact->reverse_sort_name, "strdup() return NULL");
+               }
+               else if (name->prefix) {
+                       contact->reverse_display_name = strdup(name->prefix);
+                       RETM_IF(NULL == contact->reverse_display_name, "strdup() return NULL");
+                       contact->reverse_sort_name = strdup(name->prefix);
+                       RETM_IF(NULL == contact->reverse_sort_name, "strdup() return NULL");
+               }
+
+               ///////////////////////////////////////////////
+               // Make display name (First name first)
+               // Default         : Prefix First Middle Last, Suffix
+               // Korean, Chinese : Prefix LastFirstMiddleSuffix (Same as reverse display name)
+               // Japanese        : Prefix First Middle Last Suffix
+               // sort name does not include prefix
+               //    But, if there is only prefix, sort_name is prefix
+               //////////////////////////////////////////////
+               if (reverse_lang_type == CTSVC_LANG_KOREAN ||
+                       reverse_lang_type == CTSVC_LANG_CHINESE ||
+                       reverse_lang_type == CTSVC_LANG_JAPANESE) {
+                       contact->display_name = strdup(contact->reverse_display_name);
+                       RETM_IF(NULL == contact->display_name, "strdup() return NULL");
+                       contact->sort_name = SAFE_STRDUP(contact->reverse_sort_name);
+               }
+               else {
+                       int lang_type = -1;
+                       temp_display = NULL;
+                       temp_display_len = SAFE_STRLEN(name->first)
+                                                               + SAFE_STRLEN(name->addition)
+                                                               + SAFE_STRLEN(name->last)
+                                                               + SAFE_STRLEN(name->suffix);
+                       if (0 < temp_display_len) {
+                               temp_display_len += 6;
+                               // make reverse_temp_display_name
+                               temp_display = calloc(1, temp_display_len);
+                               RETM_IF(NULL == temp_display, "calloc() return NULL");
+                               len = 0;
+
+                               if(name->first) {
+                                       char * temp = __ctsvc_remove_first_space(name->first);
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", temp);
+                                       free(temp);
+                               }
+
+                               if(name->addition) {
+                                       char * temp = __ctsvc_remove_first_space(name->addition);
+                                       if (*temp_display)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", temp);
+                                       free(temp);
+                               }
+
+                               if(name->last) {
+                                       char * temp = __ctsvc_remove_first_space(name->last);
+                                       if (*temp_display)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", temp);
+                                       free(temp);
+                               }
+
+                               if(name->suffix) {
+                                       if (*temp_display) {
+                                               lang_type = ctsvc_check_language_type(temp_display);
+                                               if (lang_type == CTSVC_LANG_JAPANESE)
+                                                       len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                               else
+                                                       len += snprintf(temp_display + len, temp_display_len - len, ", ");
+                                       }
+                                       char * temp = __ctsvc_remove_first_space(name->suffix);
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", temp);
+                                       free(temp);
+                               }
+                       }
+
+                       if(name->prefix && temp_display) {
+                               display_len = SAFE_STRLEN(name->prefix) + temp_display_len + 2;
+                               display = calloc(1, display_len);
+                               if (NULL == display) {
+                                       CTS_ERR("calloc() return NULL");
+                                       free(temp_display);
+                                       return;
+                               }
+                               snprintf(display, display_len , "%s %s", name->prefix, temp_display);
+                               contact->display_name = display;
+                               contact->sort_name = temp_display;
+                       }
+                       else if (temp_display) {
+                               contact->display_name = temp_display;
+                               contact->sort_name = strdup(temp_display);
+                               RETM_IF(NULL == contact->sort_name, "strdup() return NULL");
+                       }
+                       else if (name->prefix) {
+                               contact->display_name = strdup(name->prefix);
+                               RETM_IF(NULL == contact->display_name, "strdup() return NULL");
+                               contact->sort_name = strdup(name->prefix);
+                               RETM_IF(NULL == contact->sort_name, "strdup() return NULL");
+                       }
+               }
+
+               ctsvc_record_set_property_flag((ctsvc_record_s *)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY);
+               contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME;
+       }
+       else {
+               GList *cur;
+               if (contact->company && contact->company->records) {
+                       for (cur=contact->company->records;cur;cur=cur->next) {
+                               ctsvc_company_s *company = (ctsvc_company_s *)cur->data;
+                               if (company && company->name) {
+                                       ctsvc_record_set_property_flag((ctsvc_record_s *)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY);
+                                       FREEandSTRDUP(contact->display_name, company->name);
+                                       contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_COMPANY;
+                                       break;
+                               }
+                       }
+               }
+
+               if (!ctsvc_record_check_property_flag((ctsvc_record_s *)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY) &&
+                               contact->nicknames && contact->nicknames->records) {
+                       for (cur=contact->nicknames->records;cur;cur=cur->next) {
+                               ctsvc_nickname_s *nickname = (ctsvc_nickname_s *)cur->data;
+                               if (nickname && nickname->nickname) {
+                                       ctsvc_record_set_property_flag((ctsvc_record_s *)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY);
+                                       FREEandSTRDUP(contact->display_name, nickname->nickname);
+                                       contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NICKNAME;
+                                       break;
+                               }
+                       }
+               }
+
+               if (!ctsvc_record_check_property_flag((ctsvc_record_s *)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY) &&
+                               contact->numbers && contact->numbers->records) {
+                       for (cur=contact->numbers->records;cur;cur=cur->next) {
+                               ctsvc_number_s *number = (ctsvc_number_s *)cur->data;
+                               if (number && number->number) {
+                                       ctsvc_record_set_property_flag((ctsvc_record_s *)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY);
+                                       FREEandSTRDUP(contact->display_name, number->number);
+                                       contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NUMBER;
+                                       break;
+                               }
+                       }
+               }
+
+               if (!ctsvc_record_check_property_flag((ctsvc_record_s *)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY) &&
+                               contact->emails && contact->emails->records) {
+                       for (cur=contact->emails->records;cur;cur=cur->next) {
+                               ctsvc_email_s *email = (ctsvc_email_s *)cur->data;
+                               if (email && email->email_addr) {
+                                       ctsvc_record_set_property_flag((ctsvc_record_s *)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY);
+                                       FREEandSTRDUP(contact->display_name, email->email_addr);
+                                       contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL;
+                                       break;
+                               }
+                       }
+               }
+
+               if (ctsvc_record_check_property_flag((ctsvc_record_s *)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY)) {
+                       FREEandSTRDUP(contact->reverse_display_name, contact->display_name);
+                       FREEandSTRDUP(contact->sort_name, contact->display_name);
+                       FREEandSTRDUP(contact->reverse_sort_name, contact->display_name);
+               }
+               else {
+                       // Update as NULL
+                       ctsvc_record_set_property_flag((ctsvc_record_s *)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY);
+               }
+       }
+
+       // make sortkey
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)contact, _contacts_contact.display_name, CTSVC_PROPERTY_FLAG_DIRTY))
+               ctsvc_contact_make_sortkey(contact);
+
+       return;
+}
+
+int ctsvc_get_data_info_name(cts_stmt stmt, contacts_list_h name_list)
+{
+       int ret;
+       int count;
+       contacts_record_h record;
+
+       ret = contacts_list_get_count(name_list, &count);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_list_get_count is failed(%d)", ret);
+       RETVM_IF (1 < count, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : already had name");
+
+       ctsvc_db_name_get_value_from_stmt(stmt, &record, 1);
+       contacts_list_add(name_list, record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_get_data_info_event(cts_stmt stmt, contacts_list_h list)
+{
+       contacts_record_h record;
+
+       ctsvc_db_event_get_value_from_stmt(stmt, &record, 1);
+       contacts_list_add(list, record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_get_data_info_number(cts_stmt stmt, contacts_list_h number_list)
+{
+       contacts_record_h record;
+
+       ctsvc_db_number_get_value_from_stmt(stmt, &record, 1);
+       contacts_list_add(number_list, record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_get_data_info_email(cts_stmt stmt, contacts_list_h list)
+{
+       contacts_record_h record;
+
+       ctsvc_db_email_get_value_from_stmt(stmt, &record, 1);
+       contacts_list_add(list, record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_get_data_info_address(cts_stmt stmt, contacts_list_h list)
+{
+       contacts_record_h record;
+
+       ctsvc_db_address_get_value_from_stmt(stmt, &record, 1);
+       contacts_list_add(list, record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_get_data_info_messenger(cts_stmt stmt, contacts_list_h list)
+{
+       contacts_record_h record;
+
+       ctsvc_db_messenger_get_value_from_stmt(stmt, &record, 1);
+       contacts_list_add(list, record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_get_data_info_note(cts_stmt stmt, contacts_list_h list)
+{
+       contacts_record_h record;
+
+       ctsvc_db_note_get_value_from_stmt(stmt, &record, 1);
+       contacts_list_add(list, record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_get_data_info_company(cts_stmt stmt, contacts_list_h list)
+{
+       contacts_record_h record;
+
+       ctsvc_db_company_get_value_from_stmt(stmt, &record, 1);
+       contacts_list_add(list, record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_get_data_info_profile(cts_stmt stmt, contacts_list_h list)
+{
+       contacts_record_h record;
+
+       ctsvc_db_profile_get_value_from_stmt(stmt, &record, 1);
+       contacts_list_add(list, record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_get_data_info_relationship(cts_stmt stmt, contacts_list_h list)
+{
+       contacts_record_h record;
+
+       ctsvc_db_relationship_get_value_from_stmt(stmt, &record, 1);
+       contacts_list_add(list, record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_get_data_info_image(cts_stmt stmt, contacts_list_h list)
+{
+       contacts_record_h record;
+
+       ctsvc_db_image_get_value_from_stmt(stmt, &record, 1);
+       contacts_list_add(list, record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_get_data_info_url(cts_stmt stmt, contacts_list_h list)
+{
+       contacts_record_h record;
+
+       ctsvc_db_url_get_value_from_stmt(stmt, &record, 1);
+       contacts_list_add(list, record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_get_data_info_nickname(cts_stmt stmt, contacts_list_h list)
+{
+       contacts_record_h record;
+
+       ctsvc_db_nickname_get_value_from_stmt(stmt, &record, 1);
+       contacts_list_add(list, record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_get_data_info_extension(cts_stmt stmt, contacts_list_h list)
+{
+       contacts_record_h record;
+
+       ctsvc_db_extension_get_value_from_stmt(stmt, &record, 1);
+       contacts_list_add(list, record);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+bool ctsvc_contact_check_default_number(contacts_list_h number_list)
+{
+       bool has_default = false;
+       ctsvc_number_s* number;
+       int count;
+       int ret;
+
+       RETV_IF(NULL == number_list, false);
+
+       ret = contacts_list_get_count(number_list, &count);
+       if(CONTACTS_ERROR_NONE !=ret || 0 == count)
+               return false;
+
+       contacts_list_first(number_list);
+       do {
+               contacts_list_get_current_record_p(number_list, (contacts_record_h*)&number);
+               if (NULL != number && number->number && *number->number) {
+                       if (number->is_default && false == has_default)
+                               has_default = true;
+                       else if (has_default)
+                               number->is_default = false;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(number_list));
+
+       if (false == has_default) {
+               contacts_list_first(number_list);
+               do {
+                       contacts_list_get_current_record_p(number_list, (contacts_record_h*)&number);
+                       if (NULL != number && number->number && *number->number) {
+                               number->is_default = true;
+                               ctsvc_record_set_property_flag((ctsvc_record_s *)number, _contacts_number.is_default, CTSVC_PROPERTY_FLAG_DIRTY);
+                               has_default = true;
+                               break;
+                       }
+               }while(CONTACTS_ERROR_NONE == contacts_list_next(number_list));
+       }
+       return has_default;
+}
+
+bool ctsvc_contact_check_default_email(contacts_list_h email_list)
+{
+       bool has_default = false;
+       ctsvc_email_s* email;
+       int count;
+       int ret;
+
+       RETV_IF(NULL == email_list, false);
+
+       ret = contacts_list_get_count(email_list, &count);
+       if(CONTACTS_ERROR_NONE !=ret || 0 == count)
+               return false;
+
+       contacts_list_first(email_list);
+       do {
+               contacts_list_get_current_record_p(email_list, (contacts_record_h*)&email);
+               if (NULL != email && email->email_addr && *email->email_addr) {
+                       if (email->is_default && false == has_default)
+                               has_default = true;
+                       else if (has_default)
+                               email->is_default = false;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(email_list));
+
+       if (false == has_default) {
+               contacts_list_first(email_list);
+               do {
+                       contacts_list_get_current_record_p(email_list, (contacts_record_h*)&email);
+                       if (NULL != email && email->email_addr && *email->email_addr) {
+                               email->is_default = true;
+                               ctsvc_record_set_property_flag((ctsvc_record_s *)email, _contacts_email.is_default, CTSVC_PROPERTY_FLAG_DIRTY);
+                               has_default = true;
+                               break;
+                       }
+               }while(CONTACTS_ERROR_NONE == contacts_list_next(email_list));
+       }
+       return has_default;
+}
+
+bool ctsvc_contact_check_default_image(contacts_list_h image_list)
+{
+       bool has_default = false;
+       ctsvc_image_s* image;
+       int count;
+       int ret;
+
+       RETV_IF(NULL == image_list, false);
+
+       ret = contacts_list_get_count(image_list, &count);
+       if (CONTACTS_ERROR_NONE !=ret || 0 == count) {
+               CTS_DBG("list get count failed (%d)", count);
+               return false;
+       }
+
+       contacts_list_first(image_list);
+       do {
+               contacts_list_get_current_record_p(image_list, (contacts_record_h*)&image);
+               if (NULL != image && image->path && *image->path) {
+                       if (image->is_default && false == has_default)
+                               has_default = true;
+                       else if (has_default)
+                               image->is_default = false;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(image_list));
+
+       if (false == has_default) {
+               contacts_list_first(image_list);
+               do {
+                       contacts_list_get_current_record_p(image_list, (contacts_record_h*)&image);
+                       if (NULL != image && image->path && *image->path) {
+                               image->is_default = true;
+                               ctsvc_record_set_property_flag((ctsvc_record_s *)image, _contacts_image.is_default, CTSVC_PROPERTY_FLAG_DIRTY);
+                               has_default = true;
+                               break;
+                       }
+               }while(CONTACTS_ERROR_NONE == contacts_list_next(image_list));
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+bool ctsvc_contact_check_default_address(contacts_list_h address_list)
+{
+       bool has_default = false;
+       ctsvc_address_s* address;
+       int count;
+       int ret;
+
+       RETV_IF(NULL == address_list, false);
+
+       ret = contacts_list_get_count(address_list, &count);
+       if (CONTACTS_ERROR_NONE !=ret || 0 == count) {
+               CTS_DBG("list get count failed (%d)", count);
+               return false;
+       }
+
+       contacts_list_first(address_list);
+       do {
+               contacts_list_get_current_record_p(address_list, (contacts_record_h*)&address);
+               if (NULL != address &&
+                                               (address->pobox || address->postalcode || address->region || address->locality
+                                                       || address->street || address->extended || address->country)) {
+                       if (address->is_default && false == has_default)
+                               has_default = true;
+                       else if (has_default)
+                               address->is_default = false;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(address_list));
+
+       if (false == has_default) {
+               contacts_list_first(address_list);
+               do {
+                       contacts_list_get_current_record_p(address_list, (contacts_record_h*)&address);
+                       if (NULL != address &&
+                                               (address->pobox || address->postalcode || address->region || address->locality
+                                                       || address->street || address->extended || address->country)) {
+                               address->is_default = true;
+                               ctsvc_record_set_property_flag((ctsvc_record_s *)address, _contacts_address.is_default, CTSVC_PROPERTY_FLAG_DIRTY);
+                               has_default = true;
+                               break;
+                       }
+               }while(CONTACTS_ERROR_NONE == contacts_list_next(address_list));
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_contact_update_data_name(contacts_list_h name_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record;
+       ctsvc_name_s *name;
+       ctsvc_list_s *list = (ctsvc_list_s*)name_list;
+       GList *cursor;
+       RETV_IF(NULL == name_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       for(cursor = list->deleted_records;cursor;cursor=cursor->next) {
+               name = (ctsvc_name_s *)cursor->data;
+               ctsvc_db_name_delete(name->id, is_my_profile);
+       }
+
+       contacts_list_first(name_list);
+       contacts_list_get_current_record_p(name_list, &record);
+       if (record) {
+               name = (ctsvc_name_s*)record;
+               if (0 < name->id) {
+                       if (name->first || name->last || name->addition || name->prefix || name->suffix
+                                       || name->phonetic_first || name->phonetic_middle || name->phonetic_last)
+                               ret = ctsvc_db_name_update(record, is_my_profile);
+                       else
+                               ret = ctsvc_db_name_delete(name->id, is_my_profile);
+               }
+               else
+                       ret = ctsvc_db_name_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret)
+                       CTS_ERR("DB error : return(%d)", ret);
+       }
+
+       return ret;
+}
+
+int ctsvc_contact_update_data_company(contacts_list_h company_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int count = 0;
+       ctsvc_list_s *list = (ctsvc_list_s*)company_list;
+       ctsvc_company_s *company;
+       GList *cursor;
+
+       RETV_IF(NULL == company_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       for(cursor = list->deleted_records;cursor;cursor=cursor->next) {
+               company = (ctsvc_company_s *)cursor->data;
+               ctsvc_db_company_delete(company->id, is_my_profile);
+       }
+
+       ret = contacts_list_get_count(company_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(company_list);
+       do {
+               contacts_list_get_current_record_p(company_list, &record);
+               company = (ctsvc_company_s*)record;
+               if (0 < company->id) {
+                       if (company->name || company->department || company->job_title || company->role
+                               || company->assistant_name || company->logo || company->location || company->description
+                               || company->phonetic_name)
+                               ret = ctsvc_db_company_update(record, contact_id, is_my_profile);
+                       else
+                               ret = ctsvc_db_company_delete(company->id, is_my_profile);
+               }
+               else
+                       ret = ctsvc_db_company_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : return (%d)", ret);
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(company_list));
+
+       return ret;
+}
+
+int ctsvc_contact_update_data_note(contacts_list_h note_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int count = 0;
+       ctsvc_list_s *list = (ctsvc_list_s*)note_list;
+       ctsvc_note_s *note;
+       GList *cursor;
+
+       RETV_IF(NULL == note_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       for(cursor = list->deleted_records;cursor;cursor=cursor->next) {
+               note = (ctsvc_note_s *)cursor->data;
+               ctsvc_db_note_delete(note->id, is_my_profile);
+       }
+
+       ret = contacts_list_get_count(note_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(note_list);
+       do {
+               contacts_list_get_current_record_p(note_list, &record);
+               note = (ctsvc_note_s*)record;
+               if (0 < note->id) {
+                       if (note->note)
+                               ret = ctsvc_db_note_update(record, is_my_profile);
+                       else
+                               ret = ctsvc_db_note_delete(note->id, is_my_profile);
+               }
+               else
+                       ret = ctsvc_db_note_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : return (%d)", ret);
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(note_list));
+
+       return ret;
+}
+
+int ctsvc_contact_update_data_event(contacts_list_h event_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int count = 0;
+       ctsvc_list_s *list = (ctsvc_list_s*)event_list;
+       ctsvc_event_s *event;
+       GList *cursor;
+
+       RETV_IF(NULL == event_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       for(cursor = list->deleted_records;cursor;cursor=cursor->next) {
+               event = (ctsvc_event_s *)cursor->data;
+               ctsvc_db_event_delete(event->id, is_my_profile);
+       }
+
+       ret = contacts_list_get_count(event_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(event_list);
+       do {
+               contacts_list_get_current_record_p(event_list, &record);
+               event = (ctsvc_event_s*)record;
+               if (0 < event->id) {
+                       if (event->date > 0)
+                               ret = ctsvc_db_event_update(record, is_my_profile);
+                       else
+                               ret = ctsvc_db_event_delete(event->id, is_my_profile);
+               }
+               else
+                       ret = ctsvc_db_event_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : return (%d)", ret);
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(event_list));
+
+       return ret;
+}
+
+int ctsvc_contact_update_data_messenger(contacts_list_h messenger_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int count = 0;
+       ctsvc_list_s *list = (ctsvc_list_s*)messenger_list;
+       ctsvc_messenger_s *messenger;
+       GList *cursor;
+
+       RETV_IF(NULL == messenger_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       for(cursor = list->deleted_records;cursor;cursor=cursor->next) {
+               messenger = (ctsvc_messenger_s *)cursor->data;
+               ctsvc_db_messenger_delete(messenger->id, is_my_profile);
+       }
+
+       ret = contacts_list_get_count(messenger_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(messenger_list);
+       do {
+               contacts_list_get_current_record_p(messenger_list, &record);
+               messenger = (ctsvc_messenger_s*)record;
+               if (0 < messenger->id) {
+                       if (messenger->im_id)
+                               ret = ctsvc_db_messenger_update(record, is_my_profile);
+                       else
+                               ret = ctsvc_db_messenger_delete(messenger->id, is_my_profile);
+               }
+               else
+                       ret = ctsvc_db_messenger_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : return (%d)", ret);
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(messenger_list));
+
+       return ret;
+}
+
+int ctsvc_contact_update_data_address(contacts_list_h address_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int count = 0;
+       ctsvc_list_s *list = (ctsvc_list_s*)address_list;
+       ctsvc_address_s *address;
+       GList *cursor;
+
+       RETV_IF(NULL == address_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       for(cursor = list->deleted_records;cursor;cursor=cursor->next) {
+               address = (ctsvc_address_s *)cursor->data;
+               ctsvc_db_address_delete(address->id, is_my_profile);
+       }
+
+       ret = contacts_list_get_count(address_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(address_list);
+       do {
+               contacts_list_get_current_record_p(address_list, &record);
+               address = (ctsvc_address_s*)record;
+               if (0 < address->id) {
+                       if (address->pobox || address->postalcode || address->region || address->locality
+                               || address->street || address->extended || address->country)
+                               ret = ctsvc_db_address_update(record, is_my_profile);
+                       else
+                               ret = ctsvc_db_address_delete(address->id, is_my_profile);
+               }
+               else
+                       ret = ctsvc_db_address_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : return (%d)", ret);
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(address_list));
+
+       return ret;
+}
+
+int ctsvc_contact_update_data_url(contacts_list_h url_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int count = 0;
+       ctsvc_list_s *list = (ctsvc_list_s*)url_list;
+       ctsvc_url_s *url;
+       GList *cursor;
+
+       RETV_IF(NULL == url_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       for(cursor = list->deleted_records;cursor;cursor=cursor->next) {
+               url = (ctsvc_url_s *)cursor->data;
+               ctsvc_db_url_delete(url->id, is_my_profile);
+       }
+
+       ret = contacts_list_get_count(url_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(url_list);
+       do {
+               contacts_list_get_current_record_p(url_list, &record);
+               url = (ctsvc_url_s*)record;
+               if (0 < url->id) {
+                       if (url->url)
+                               ret = ctsvc_db_url_update(record, is_my_profile);
+                       else
+                               ret = ctsvc_db_url_delete(url->id, is_my_profile);
+               }
+               else
+                       ret = ctsvc_db_url_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : return (%d)", ret);
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(url_list));
+
+       return ret;
+}
+
+int ctsvc_contact_update_data_profile(contacts_list_h profile_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int count = 0;
+       ctsvc_list_s *list = (ctsvc_list_s*)profile_list;
+       ctsvc_profile_s *profile;
+       GList *cursor;
+
+       RETV_IF(NULL == profile_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       for(cursor = list->deleted_records;cursor;cursor=cursor->next) {
+               profile = (ctsvc_profile_s *)cursor->data;
+               ctsvc_db_profile_delete(profile->id, is_my_profile);
+       }
+       ret = contacts_list_get_count(profile_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(profile_list);
+       do {
+               contacts_list_get_current_record_p(profile_list, &record);
+               profile = (ctsvc_profile_s*)record;
+               if (0 < profile->id) {
+                       if (profile->text)
+                               ret = ctsvc_db_profile_update(record, is_my_profile);
+                       else
+                               ret = ctsvc_db_profile_delete(profile->id, is_my_profile);
+               }
+               else
+                       ret = ctsvc_db_profile_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : return (%d)", ret);
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(profile_list));
+
+       return ret;
+}
+
+int ctsvc_contact_update_data_relationship(contacts_list_h relationship_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int count = 0;
+       ctsvc_list_s *list = (ctsvc_list_s*)relationship_list;
+       ctsvc_relationship_s *relationship;
+       GList *cursor;
+
+       RETV_IF(NULL == relationship_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       for(cursor = list->deleted_records;cursor;cursor=cursor->next) {
+               relationship = (ctsvc_relationship_s *)cursor->data;
+               ctsvc_db_relationship_delete(relationship->id, is_my_profile);
+       }
+
+       ret = contacts_list_get_count(relationship_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(relationship_list);
+       do {
+               contacts_list_get_current_record_p(relationship_list, &record);
+               relationship = (ctsvc_relationship_s*)record;
+               if (0 < relationship->id) {
+                       if (relationship->name)
+                               ret = ctsvc_db_relationship_update(record, is_my_profile);
+                       else
+                               ret = ctsvc_db_relationship_delete(relationship->id, is_my_profile);
+               }
+               else
+                       ret = ctsvc_db_relationship_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : return (%d)", ret);
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(relationship_list));
+
+       return ret;
+}
+
+int ctsvc_contact_update_data_image(contacts_list_h image_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int count = 0;
+       ctsvc_list_s *list = (ctsvc_list_s*)image_list;
+       ctsvc_image_s *image;
+       GList *cursor;
+
+       RETV_IF(NULL == image_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       for(cursor = list->deleted_records;cursor;cursor=cursor->next) {
+               image = (ctsvc_image_s *)cursor->data;
+               ctsvc_db_image_delete(image->id, is_my_profile);
+       }
+
+       ret = contacts_list_get_count(image_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(image_list);
+       do {
+               contacts_list_get_current_record_p(image_list, &record);
+               image = (ctsvc_image_s*)record;
+               if (CTSVC_PROPERTY_FLAG_DIRTY & image->base.property_flag) {
+                       if (0 < image->id) {
+                               if (image->path)
+                                       ret = ctsvc_db_image_update(record, contact_id, is_my_profile);
+                               else
+                                       ret = ctsvc_db_image_delete(image->id, is_my_profile);
+                       }
+                       else
+                               ret = ctsvc_db_image_insert(record, contact_id, is_my_profile, NULL);
+               }
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : return (%d)", ret);
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(image_list));
+
+       return ret;
+}
+
+int ctsvc_contact_update_data_nickname(contacts_list_h nickname_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int count = 0;
+       ctsvc_list_s *list = (ctsvc_list_s*)nickname_list;
+       ctsvc_nickname_s *nickname;
+       GList *cursor;
+
+       RETV_IF(NULL == nickname_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       for(cursor = list->deleted_records;cursor;cursor=cursor->next) {
+               nickname = (ctsvc_nickname_s *)cursor->data;
+               ctsvc_db_nickname_delete(nickname->id, is_my_profile);
+       }
+
+       ret = contacts_list_get_count(nickname_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(nickname_list);
+       do {
+               contacts_list_get_current_record_p(nickname_list, &record);
+               nickname = (ctsvc_nickname_s*)record;
+               if (0 < nickname->id) {
+                       if (nickname->nickname)
+                               ret = ctsvc_db_nickname_update(record, is_my_profile);
+                       else
+                               ret = ctsvc_db_nickname_delete(nickname->id, is_my_profile);
+               }
+               else
+                       ret = ctsvc_db_nickname_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : return (%d)", ret);
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(nickname_list));
+
+       return ret;
+}
+
+int ctsvc_contact_update_data_extension(contacts_list_h extension_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int count = 0;
+       ctsvc_list_s *list = (ctsvc_list_s*)extension_list;
+       ctsvc_extension_s *extension;
+       GList *cursor;
+
+       RETV_IF(NULL == extension_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       for(cursor = list->deleted_records;cursor;cursor=cursor->next) {
+               extension = (ctsvc_extension_s *)cursor->data;
+               ctsvc_db_extension_delete(extension->id, is_my_profile);
+       }
+
+       ret = contacts_list_get_count(extension_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(extension_list);
+       do {
+               contacts_list_get_current_record_p(extension_list, &record);
+               extension = (ctsvc_extension_s*)record;
+               if (0 < extension->id) {
+                       if (extension->data2 || extension->data3 || extension->data4 || extension->data5
+                               || extension->data6 || extension->data7 || extension->data8 || extension->data9
+                               || extension->data10 || extension->data11 || extension->data12)
+                               ret = ctsvc_db_extension_update(record);
+                       else
+                               ret = ctsvc_db_extension_delete(extension->id, is_my_profile);
+               }
+               else
+                       ret = ctsvc_db_extension_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : return (%d)", ret);
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(extension_list));
+
+       return ret;
+}
+
+int ctsvc_contact_update_data_number(contacts_list_h number_list,
+       int contact_id, bool is_my_profile, bool *had_phonenumber)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int count = 0;
+       ctsvc_list_s *list = (ctsvc_list_s*)number_list;
+       ctsvc_number_s *number;
+       GList *cursor;
+       bool had = false;
+       *had_phonenumber = false;
+
+       RETV_IF(NULL == number_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       for(cursor = list->deleted_records;cursor;cursor=cursor->next) {
+               number = (ctsvc_number_s *)cursor->data;
+               ctsvc_db_number_delete(number->id, is_my_profile);
+       }
+
+       ret = contacts_list_get_count(number_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(number_list);
+       do {
+               contacts_list_get_current_record_p(number_list, &record);
+               number = (ctsvc_number_s*)record;
+               if (0 < number->id) {
+                       if (number->number) {
+                               ret = ctsvc_db_number_update(record, is_my_profile);
+                               had = true;
+                       }
+                       else
+                               ret = ctsvc_db_number_delete(number->id, is_my_profile);
+               }
+               else if (number->number) {
+                       ret = ctsvc_db_number_insert(record, contact_id, is_my_profile, NULL);
+                       had = true;
+               }
+               if (CONTACTS_ERROR_DB == ret) {
+                       CTS_ERR("DB error : return (%d)", ret);
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(number_list));
+
+       *had_phonenumber = had;
+       return ret;
+}
+
+int ctsvc_contact_update_data_email(contacts_list_h email_list,
+       int contact_id, bool is_my_profile, bool *had_email)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int count = 0;
+       ctsvc_list_s *list = (ctsvc_list_s*)email_list;
+       ctsvc_email_s *email;
+       GList *cursor;
+       bool had = false;
+       *had_email = false;
+
+       RETV_IF(NULL == email_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       for(cursor = list->deleted_records;cursor;cursor=cursor->next) {
+               email = (ctsvc_email_s *)cursor->data;
+               ctsvc_db_email_delete(email->id, is_my_profile);
+       }
+
+       ret = contacts_list_get_count(email_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(email_list);
+       do {
+               contacts_list_get_current_record_p(email_list, &record);
+               email = (ctsvc_email_s*)record;
+
+               if (0 < email->id) {
+                       if (email->email_addr) {
+                               ret = ctsvc_db_email_update(record, is_my_profile);
+                               had = true;
+                       }
+                       else
+                               ret = ctsvc_db_email_delete(email->id, is_my_profile);
+               }
+               else if (email->email_addr) {
+                       ret = ctsvc_db_email_insert(record, contact_id, is_my_profile, NULL);
+                       had = true;
+               }
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : return (%d)", ret);
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(email_list));
+
+       *had_email = had;
+       return ret;
+}
+
+int ctsvc_contact_insert_data_name(contacts_list_h name_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record;
+       RETV_IF(NULL == name_list, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       contacts_list_first(name_list);
+       contacts_list_get_current_record_p(name_list, &record);
+       if (record) {
+               ret = ctsvc_db_name_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : ctsvc_db_name_insert");
+               }
+       }
+       return ret;
+}
+
+int ctsvc_contact_insert_data_number(contacts_list_h number_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record;
+       int count = 0;
+
+       RETV_IF(NULL == number_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       ret = contacts_list_get_count(number_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(number_list);
+       do {
+               contacts_list_get_current_record_p(number_list, &record);
+               ret = ctsvc_db_number_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : ctsvc_db_number_insert");
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(number_list));
+
+       return ret;
+}
+
+int ctsvc_contact_insert_data_email(contacts_list_h email_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record;
+       int count = 0;
+
+       RETV_IF(NULL == email_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       ret = contacts_list_get_count(email_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(email_list);
+       do {
+               contacts_list_get_current_record_p(email_list, &record);
+               ret = ctsvc_db_email_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : ctsvc_db_email_insert");
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(email_list));
+
+       return ret;
+}
+
+int ctsvc_contact_insert_data_profile(contacts_list_h profile_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record;
+       int count = 0;
+
+       RETV_IF(NULL == profile_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       ret = contacts_list_get_count(profile_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(profile_list);
+       do {
+               contacts_list_get_current_record_p(profile_list, &record);
+               ret = ctsvc_db_profile_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : ctsvc_db_profile_insert");
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(profile_list));
+
+       return ret;
+}
+
+int ctsvc_contact_insert_data_company(contacts_list_h company_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int count = 0;
+
+       RETV_IF(NULL == company_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       ret = contacts_list_get_count(company_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(company_list);
+       do {
+               contacts_list_get_current_record_p(company_list, &record);
+               ret = ctsvc_db_company_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : ctsvc_db_company_insert");
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(company_list));
+
+       return ret;
+}
+
+int ctsvc_contact_insert_data_note(contacts_list_h note_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int count = 0;
+
+       RETV_IF(NULL == note_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       ret = contacts_list_get_count(note_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(note_list);
+       do {
+               contacts_list_get_current_record_p(note_list, &record);
+               if (record) {
+                       ret = ctsvc_db_note_insert(record, contact_id, is_my_profile, NULL);
+                       if (CONTACTS_ERROR_DB == ret){
+                               CTS_ERR("DB error : ctsvc_db_note_insert");
+                               break;
+                       }
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(note_list));
+       return ret;
+}
+
+int ctsvc_contact_insert_data_event(contacts_list_h event_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record;
+       int count = 0;
+
+       RETV_IF(NULL == event_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       ret = contacts_list_get_count(event_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(event_list);
+       do {
+               contacts_list_get_current_record_p(event_list, &record);
+               ret = ctsvc_db_event_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : ctsvc_db_event_insert");
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(event_list));
+
+       return ret;
+}
+
+int ctsvc_contact_insert_data_messenger(contacts_list_h messenger_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record;
+       int count = 0;
+
+       RETV_IF(NULL == messenger_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       ret = contacts_list_get_count(messenger_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(messenger_list);
+       do {
+               contacts_list_get_current_record_p(messenger_list, &record);
+               ret = ctsvc_db_messenger_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : ctsvc_db_messenger_insert");
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(messenger_list));
+
+       return ret;
+}
+
+int ctsvc_contact_insert_data_address(contacts_list_h address_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record;
+       int count = 0;
+
+       RETV_IF(NULL == address_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       ret = contacts_list_get_count(address_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(address_list);
+       do {
+               contacts_list_get_current_record_p(address_list, &record);
+               ret = ctsvc_db_address_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : ctsvc_db_address_insert");
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(address_list));
+
+       return ret;
+}
+
+int ctsvc_contact_insert_data_url(contacts_list_h url_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record;
+       int count = 0;
+
+       RETV_IF(NULL == url_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       ret = contacts_list_get_count(url_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(url_list);
+       do {
+               contacts_list_get_current_record_p(url_list, &record);
+               ret = ctsvc_db_url_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : ctsvc_db_url_insert");
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(url_list));
+
+       return ret;
+}
+
+int ctsvc_contact_insert_data_nickname(contacts_list_h nickname_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record;
+       int count = 0;
+
+       RETV_IF(NULL == nickname_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       ret = contacts_list_get_count(nickname_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(nickname_list);
+       do {
+               contacts_list_get_current_record_p(nickname_list, &record);
+               ret = ctsvc_db_nickname_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : ctsvc_db_nickname_insert");
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(nickname_list));
+
+       return ret;
+}
+
+int ctsvc_contact_insert_data_relationship(contacts_list_h relationship_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record;
+       int count = 0;
+
+       RETV_IF(NULL == relationship_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       ret = contacts_list_get_count(relationship_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(relationship_list);
+       do {
+               contacts_list_get_current_record_p(relationship_list, &record);
+               ret = ctsvc_db_relationship_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : ctsvc_db_relationship_insert");
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(relationship_list));
+
+       return ret;
+}
+
+int ctsvc_contact_insert_data_image(contacts_list_h image_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record;
+       int count = 0;
+
+       RETV_IF(NULL == image_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       ret = contacts_list_get_count(image_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(image_list);
+       do {
+               contacts_list_get_current_record_p(image_list, &record);
+               ret = ctsvc_db_image_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : ctsvc_db_image_insert");
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(image_list));
+
+       return ret;
+}
+
+int ctsvc_contact_insert_data_extension(contacts_list_h extension_list, int contact_id, bool is_my_profile)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record;
+       int count = 0;
+
+       RETV_IF(NULL == extension_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       ret = contacts_list_get_count(extension_list, &count);
+       if(0 == count)
+               return CONTACTS_ERROR_NONE;
+
+       contacts_list_first(extension_list);
+       do {
+               contacts_list_get_current_record_p(extension_list, &record);
+               ret = ctsvc_db_extension_insert(record, contact_id, is_my_profile, NULL);
+               if (CONTACTS_ERROR_DB == ret){
+                       CTS_ERR("DB error : ctsvc_db_extension_insert");
+                       break;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(extension_list));
+
+       return ret;
+}
+
+int ctsvc_contact_update_display_name(int contact_id, contacts_display_name_source_type_e changed_record_type)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int display_name_type;
+       contacts_record_h record;
+       ret = ctsvc_db_contact_get(contact_id, (contacts_record_h*)&record);
+       RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "ctsvc_db_contact_get Fail(%d)", ret);
+       contacts_record_get_int(record, _contacts_contact.display_source_type, &display_name_type);
+
+       if (display_name_type <= changed_record_type) {
+
+               cts_stmt stmt = NULL;
+               char query[CTS_SQL_MAX_LEN] = {0};
+               ctsvc_contact_s *contact = (ctsvc_contact_s *)record;
+               ctsvc_contact_make_display_name(contact);
+
+               snprintf(query, sizeof(query), "UPDATE "CTS_TABLE_CONTACTS" SET "
+                               "display_name=?, reverse_display_name=?, display_name_source=%d, "
+                               "display_name_language=%d, reverse_display_name_language=%d, "
+                               "sort_name=?, reverse_sort_name=?, sortkey=?, reverse_sortkey=?, "
+                               "changed_ver=%d, changed_time=%d  WHERE contact_id=%d",
+                               contact->display_source_type,
+                               contact->display_name_language, contact->reverse_display_name_language,
+                               ctsvc_get_next_ver(), (int)time(NULL), contact_id);
+
+               ret = ctsvc_query_prepare(query, &stmt);
+               if (NULL == stmt) {
+                       CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+                       contacts_record_destroy(record, true);
+                       return ret;
+               }
+
+               if (contact->display_name)
+                       ctsvc_stmt_bind_text(stmt, 1, contact->display_name);
+               if (contact->reverse_display_name)
+                       ctsvc_stmt_bind_text(stmt, 2, contact->reverse_display_name);
+               if (contact->sort_name)
+                       ctsvc_stmt_bind_text(stmt, 3, contact->sort_name);
+               if (contact->reverse_sort_name)
+                       ctsvc_stmt_bind_text(stmt, 4, contact->reverse_sort_name);
+               if (contact->sortkey)
+                       ctsvc_stmt_bind_text(stmt, 5, contact->sortkey);
+               if (contact->reverse_sortkey)
+                       ctsvc_stmt_bind_text(stmt, 6, contact->reverse_sortkey);
+
+               ret = ctsvc_stmt_step(stmt);
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_stmt_step() Failed(%d)", ret);
+
+               ctsvc_stmt_finalize(stmt);
+       }
+
+       contacts_record_destroy(record, true);
+       return ret;
+}
+
+extern ctsvc_db_plugin_info_s ctsvc_db_plugin_contact;
+int ctsvc_db_contact_get( int id, contacts_record_h* out_record )
+{
+       return ctsvc_db_plugin_contact.get_record(id, out_record);
+}
+
diff --git a/native/ctsvc_db_plugin_contact_helper.h b/native/ctsvc_db_plugin_contact_helper.h
new file mode 100644 (file)
index 0000000..a96049b
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_CONTACT_HELPER_H__
+#define __CTSVC_DB_PLUGIN_CONTACT_HELPER_H__
+
+#include "ctsvc_struct.h"
+#include "ctsvc_sqlite.h"
+
+int ctsvc_contact_add_image_file(int parent_id, int img_id,
+               char *src_img, char *dest_name, int dest_size);
+int ctsvc_contact_update_image_file(int parent_id, int img_id,
+               char *src_img, char *dest_name, int dest_size);
+int ctsvc_contact_delete_image_file_with_path(const unsigned char* image_path);
+
+void ctsvc_contact_make_display_name(ctsvc_contact_s *contact);
+int ctsvc_contact_make_search_name(ctsvc_contact_s *contact, char **search_name);
+int ctsvc_contact_get_name_language(const ctsvc_name_s *name);
+
+int ctsvc_db_contact_update_changed_time(int contact_id);
+int ctsvc_contact_update_display_name(int contact_id, contacts_display_name_source_type_e changed_record_type);
+
+int ctsvc_db_contact_delete(int contact_id);
+int ctsvc_db_contact_get( int id, contacts_record_h* out_record );
+
+int ctsvc_get_data_info_name(cts_stmt stmt, contacts_list_h name_list);
+int ctsvc_get_data_info_event(cts_stmt stmt, contacts_list_h list);
+int ctsvc_get_data_info_number(cts_stmt stmt, contacts_list_h number_list);
+int ctsvc_get_data_info_email(cts_stmt stmt, contacts_list_h list);
+int ctsvc_get_data_info_address(cts_stmt stmt, contacts_list_h list);
+int ctsvc_get_data_info_messenger(cts_stmt stmt, contacts_list_h list);
+int ctsvc_get_data_info_note(cts_stmt stmt, contacts_list_h list);
+int ctsvc_get_data_info_company(cts_stmt stmt, contacts_list_h list);
+int ctsvc_get_data_info_profile(cts_stmt stmt, contacts_list_h list);
+int ctsvc_get_data_info_relationship(cts_stmt stmt, contacts_list_h list);
+int ctsvc_get_data_info_image(cts_stmt stmt, contacts_list_h list);
+int ctsvc_get_data_info_url(cts_stmt stmt, contacts_list_h list);
+int ctsvc_get_data_info_nickname(cts_stmt stmt, contacts_list_h list);
+int ctsvc_get_data_info_extension(cts_stmt stmt, contacts_list_h list);
+
+bool ctsvc_contact_check_default_number(contacts_list_h number_list);
+bool ctsvc_contact_check_default_email(contacts_list_h email_list);
+bool ctsvc_contact_check_default_address(contacts_list_h address_list);
+bool ctsvc_contact_check_default_image(contacts_list_h image_list);
+bool ctsvc_contact_check_image_location(const char *path);
+
+int ctsvc_contact_update_data_name(contacts_list_h name_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_update_data_company(contacts_list_h company_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_update_data_note(contacts_list_h note_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_update_data_event(contacts_list_h event_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_update_data_messenger(contacts_list_h messenger_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_update_data_address(contacts_list_h address_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_update_data_url(contacts_list_h url_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_update_data_profile(contacts_list_h profile_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_update_data_relationship(contacts_list_h relationship_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_update_data_image(contacts_list_h image_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_update_data_nickname(contacts_list_h nickname_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_update_data_extension(contacts_list_h extension_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_update_data_number(contacts_list_h number_list, int contact_id, bool is_my_profile, bool *had_phonenumber);
+int ctsvc_contact_update_data_email(contacts_list_h email_list, int contact_id, bool is_my_profile, bool *had_email);
+
+int ctsvc_contact_insert_data_name(contacts_list_h name_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_insert_data_number(contacts_list_h number_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_insert_data_email(contacts_list_h email_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_insert_data_profile(contacts_list_h profile_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_insert_data_company(contacts_list_h company_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_insert_data_note(contacts_list_h note_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_insert_data_event(contacts_list_h event_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_insert_data_messenger(contacts_list_h messenger_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_insert_data_address(contacts_list_h address_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_insert_data_url(contacts_list_h url_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_insert_data_nickname(contacts_list_h nickname_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_insert_data_relationship(contacts_list_h relationship_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_insert_data_image(contacts_list_h image_list, int contact_id, bool is_my_profile);
+int ctsvc_contact_insert_data_extension(contacts_list_h extension_list, int contact_id, bool is_my_profile);
+
+#endif // __CTSVC_DB_PLUGIN_CONTACT_HELPER_H__
diff --git a/native/ctsvc_db_plugin_email.c b/native/ctsvc_db_plugin_email.c
new file mode 100644 (file)
index 0000000..b27e594
--- /dev/null
@@ -0,0 +1,603 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_db_plugin_email_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_list.h"
+
+static int __ctsvc_db_email_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_email_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_email_update_record( contacts_record_h record );
+static int __ctsvc_db_email_delete_record( int id );
+static int __ctsvc_db_email_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_email_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_email_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_email_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_email_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_email = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_email_insert_record,
+       .get_record = __ctsvc_db_email_get_record,
+       .update_record = __ctsvc_db_email_update_record,
+       .delete_record = __ctsvc_db_email_delete_record,
+       .get_all_records = __ctsvc_db_email_get_all_records,
+       .get_records_with_query = __ctsvc_db_email_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_email_insert_records,
+       .update_records = NULL,//__ctsvc_db_email_update_records,
+       .delete_records = NULL,//__ctsvc_db_email_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_email_get_person_default_email(int person_id)
+{
+       int ret;
+       int default_email_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+               "SELECT id FROM "CTSVC_DB_VIEW_CONTACT" c, "CTS_TABLE_DATA" d "
+               "WHERE c.person_id = %d AND d.datatype = %d AND c.contact_id = d.contact_id AND d.is_default = 1",
+               person_id, CTSVC_DATA_EMAIL);
+       ret = ctsvc_query_get_first_int_result(query, &default_email_id);
+       if (CONTACTS_ERROR_NONE != ret)
+               return 0;
+       return default_email_id;
+}
+
+static int __ctsvc_db_email_update_person_has_email(int person_id, bool has_email)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_PERSONS" SET has_email = %d WHERE person_id = %d",
+                       has_email, person_id);
+
+       ret = ctsvc_query_exec(query);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Failed(%d)", ret);
+       return ret;
+}
+
+static int __ctsvc_db_email_update_default(int email_id, int contact_id, bool is_default, bool is_primary_default)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_DATA" SET is_default = %d, is_primary_default = %d WHERE id = %d",
+                       is_default, is_primary_default, email_id);
+       ret = ctsvc_query_exec(query);
+
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Failed(%d)", ret);
+       return ret;
+}
+
+static int __ctsvc_db_email_get_default_email_id(int contact_id)
+{
+       int ret;
+       int email_id = 0;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE datatype=%d AND contact_id=%d AND is_default=1",
+                       CTSVC_DATA_EMAIL, contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &email_id);
+       if (CONTACTS_ERROR_NONE != ret)
+               return 0;
+       return email_id;
+}
+
+static int __ctsvc_db_email_get_primary_default_email_id(int contact_id)
+{
+       int ret;
+       int email_id = 0;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE datatype=%d AND contact_id=%d AND is_primary_default=1",
+                       CTSVC_DATA_EMAIL, contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &email_id);
+       if (CONTACTS_ERROR_NONE != ret)
+               return 0;
+       return email_id;
+}
+
+static int __ctsvc_db_email_get_primary_default_contact_id(int person_id)
+{
+       int ret;
+       int default_contact_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "SELECT c.contact_id FROM "CTS_TABLE_CONTACTS" c, "CTS_TABLE_DATA" d "
+                       "WHERE c.person_id = %d AND d.datatype = %d AND c.contact_id = d.contact_id AND d.is_primary_default = 1",
+                       person_id, CTSVC_DATA_EMAIL);
+       ret = ctsvc_query_get_first_int_result(query, &default_contact_id);
+       if (CONTACTS_ERROR_NONE != ret)
+               return 0;
+       return default_contact_id;
+}
+
+static int __ctsvc_db_email_set_primary_default(int email_id, bool is_primary_default)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_DATA" SET is_primary_default = %d WHERE id = %d",
+                       is_primary_default, email_id);
+       ret = ctsvc_query_exec(query);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Failed(%d)", ret);
+       return ret;
+}
+
+static int __ctsvc_db_email_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int addressbook_id = 0;
+       int person_id = 0;
+       int old_default_email_id = 0;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt = NULL;
+       ctsvc_email_s *email = (ctsvc_email_s *)record;
+       RETVM_IF(NULL == email->email_addr, CONTACTS_ERROR_INVALID_PARAMETER,
+               "Invalid parameter : email is NULL");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id, person_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", email->contact_id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               else
+                       return ret;
+       }
+       addressbook_id = ctsvc_stmt_get_int(stmt, 0);
+       person_id = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this email record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       old_default_email_id = __ctsvc_db_email_get_default_email_id(email->contact_id);
+       if (0 == old_default_email_id)
+               email->is_default = true;
+
+       ret = ctsvc_db_email_insert(record, email->contact_id, false, id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+               "UPDATE "CTS_TABLE_CONTACTS" SET has_email = %d, changed_ver = %d, changed_time = %d "
+                       "WHERE contact_id = %d",
+                       1, ctsvc_get_next_ver(), (int)time(NULL), email->contact_id);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (email->is_default) {
+               int primary_default_contact_id = 0;
+
+               __ctsvc_db_email_update_person_has_email(person_id, true);
+
+               primary_default_contact_id = __ctsvc_db_email_get_primary_default_contact_id(person_id);
+               if (0 == primary_default_contact_id || email->contact_id == primary_default_contact_id)
+                       __ctsvc_db_email_set_primary_default(*id, true);
+
+               ctsvc_contact_update_display_name(email->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL);
+       }
+
+       ctsvc_set_contact_noti();
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_email_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE id = %d AND datatype = %d ",
+                               id, CTSVC_DATA_EMAIL);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ctsvc_db_email_get_value_from_stmt(stmt, out_record, 0);
+
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_email_update_record( contacts_record_h record )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_email_s *email = (ctsvc_email_s *)record;
+       RETVM_IF(NULL == email->email_addr, CONTACTS_ERROR_INVALID_PARAMETER, "email is empty");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", email->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : contact_id (%d) is not exist", email->contact_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this email record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_email_update(record, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("update record failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (email->is_default) {
+               int old_primary_default_email_id = 0;
+               old_primary_default_email_id = __ctsvc_db_email_get_primary_default_email_id(email->contact_id);
+               if (old_primary_default_email_id)
+                       __ctsvc_db_email_set_primary_default(email->id, true);
+       }
+       ctsvc_contact_update_display_name(email->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL);
+
+       ret = ctsvc_db_contact_update_changed_time(email->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_email_delete_record( int id )
+{
+       int ret;
+       int email_id;
+       int contact_id;
+       int person_id;
+       int is_default;
+       int is_primary_default;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       bool has_email = false;
+       cts_stmt stmt = NULL;
+       int addressbook_id;
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, person_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
+                       "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+       contact_id = ctsvc_stmt_get_int(stmt, 0);
+       person_id = ctsvc_stmt_get_int(stmt, 1);
+       addressbook_id = ctsvc_stmt_get_int(stmt, 2);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this email record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT is_default, is_primary_default FROM "CTS_TABLE_DATA" WHERE id = %d", id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+       is_default = ctsvc_stmt_get_int(stmt, 0);
+       is_primary_default = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       ret = ctsvc_db_email_delete(id, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE datatype = %d AND contact_id = %d AND is_my_profile = 0 limit 1",
+                       CTSVC_DATA_EMAIL, contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &email_id);
+       if (0 < ret )
+               has_email = true;
+
+       snprintf(query, sizeof(query),
+               "UPDATE "CTS_TABLE_CONTACTS" SET has_email = %d, changed_ver = %d, changed_time = %d "
+                       "WHERE contact_id = %d",
+                       has_email, ctsvc_get_next_ver(), (int)time(NULL), contact_id);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (is_default) {
+
+               if (email_id) {
+                       __ctsvc_db_email_update_default(email_id, contact_id, is_default, is_primary_default);
+               }
+               else if (is_primary_default) {
+                       int default_email_id = 0;
+                       default_email_id = __ctsvc_db_email_get_person_default_email(person_id);
+                       if (default_email_id)
+                               __ctsvc_db_email_set_primary_default(default_email_id, true);
+                       else
+                               __ctsvc_db_email_update_person_has_email(person_id, false);
+               }
+               ctsvc_contact_update_display_name(contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL);
+       }
+
+       ctsvc_set_contact_noti();
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "DB error : ctsvc_end_trans() Failed(%d)", ret);
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_email_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int len;
+       int ret;
+       contacts_list_h list;
+       ctsvc_email_s *email;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE datatype = %d AND is_my_profile=0 ",
+                               CTSVC_DATA_EMAIL);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB : ctsvc_stmt_step fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_db_email_get_value_from_stmt(stmt, (contacts_record_h*)&email, 0);
+               ctsvc_list_prepend(list, (contacts_record_h)email);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_email_get_records_with_query( contacts_query_h query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_email_s *email;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_email._uri, &record);
+               email = (ctsvc_email_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if(CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_EMAIL_ID:
+                               email->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_EMAIL_CONTACT_ID:
+                               email->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_EMAIL_TYPE:
+                               email->type = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_EMAIL_LABEL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               email->label = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_EMAIL_EMAIL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               email->email_addr = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_EMAIL_IS_DEFAULT:
+                               email->is_default = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_email_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_email_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_email_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_email_helper.c b/native/ctsvc_db_plugin_email_helper.c
new file mode 100644 (file)
index 0000000..4f4c7e8
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_plugin_email_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+
+int ctsvc_db_email_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count)
+{
+       int ret;
+       char *temp;
+       ctsvc_email_s *email;
+
+       ret = contacts_record_create(_contacts_email._uri, (contacts_record_h *)&email);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+
+       email->id = ctsvc_stmt_get_int(stmt, start_count++);
+       email->contact_id = ctsvc_stmt_get_int(stmt, start_count++);
+       email->is_default = ctsvc_stmt_get_int(stmt, start_count++);
+       email->type = ctsvc_stmt_get_int(stmt, start_count++);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       email->label = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       email->email_addr = SAFE_STRDUP(temp);
+
+       *record = (contacts_record_h)email;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_email_reset_default(int email_id, int contact_id)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_DATA" SET is_default = 0, is_primary_default = 0 "
+                                       "WHERE id != %d AND contact_id = %d AND datatype = %d",
+                       email_id, contact_id, CTSVC_DATA_EMAIL);
+       ret = ctsvc_query_exec(query);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Failed(%d)", ret);
+       return ret;
+}
+
+int ctsvc_db_email_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id)
+{
+       int ret;
+       int email_id;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_email_s *email = (ctsvc_email_s *)record;
+
+       RETV_IF(NULL == email->email_addr, CONTACTS_ERROR_NONE);
+       RETVM_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : contact_id(%d) is mandatory field to insert email record ", email->contact_id);
+       RETVM_IF(0 < email->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", email->id);
+
+       snprintf(query, sizeof(query),
+               "INSERT INTO "CTS_TABLE_DATA"(contact_id, is_my_profile, datatype, is_default, data1, data2, data3) "
+                                                                       "VALUES(%d, %d, %d, %d, %d, ?, ?)",
+                       contact_id, is_my_profile, CTSVC_DATA_EMAIL, email->is_default, email->type);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       if (email->label)
+               ctsvc_stmt_bind_text(stmt, 1, email->label);
+       if (email->email_addr)
+               ctsvc_stmt_bind_text(stmt, 2, email->email_addr);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+
+       email_id = ctsvc_db_get_last_insert_id();
+       if (id)
+               *id = email_id;
+       ctsvc_stmt_finalize(stmt);
+
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_email.is_default, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               if (email->is_default)
+                       __ctsvc_db_email_reset_default(email_id, contact_id);
+       }
+
+       if (!is_my_profile)
+               ctsvc_set_email_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_email_update(contacts_record_h record, bool is_my_profile)
+{
+       int id;
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       ctsvc_email_s *email = (ctsvc_email_s*)record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(!email->id, CONTACTS_ERROR_INVALID_PARAMETER, "email of contact has no ID.");
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (email->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE id = %d", email->id);
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       RETV_IF(ret != CONTACTS_ERROR_NONE, ret);
+
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_email.is_default, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               if (email->is_default)
+                       __ctsvc_db_email_reset_default(email->id, email->contact_id);
+       }
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_DATA, email->id))) break;
+               if (!is_my_profile)
+                       ctsvc_set_email_noti();
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       return ret;
+}
+
+int ctsvc_db_email_delete(int id, bool is_my_profile)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE id = %d AND datatype = %d",
+                       id, CTSVC_DATA_EMAIL);
+
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_exec() Failed(%d)", ret);
+       if (!is_my_profile)
+               ctsvc_set_email_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/native/ctsvc_db_plugin_email_helper.h b/native/ctsvc_db_plugin_email_helper.h
new file mode 100644 (file)
index 0000000..298b539
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_EMAIL_HELPER_H__
+#define __CTSVC_DB_PLUGIN_EMAIL_HELPER_H__
+
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
+
+int ctsvc_db_email_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id);
+int ctsvc_db_email_update(contacts_record_h record, bool is_my_profile);
+int ctsvc_db_email_delete(int id, bool is_my_profile);
+
+int ctsvc_db_email_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count);
+
+#endif // __CTSVC_DB_PLUGIN_EMAIL_HELPER_H__
diff --git a/native/ctsvc_db_plugin_event.c b/native/ctsvc_db_plugin_event.c
new file mode 100644 (file)
index 0000000..f46d411
--- /dev/null
@@ -0,0 +1,411 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_event_helper.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_list.h"
+#include "ctsvc_notification.h"
+
+static int __ctsvc_db_event_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_event_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_event_update_record( contacts_record_h record );
+static int __ctsvc_db_event_delete_record( int id );
+static int __ctsvc_db_event_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_event_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_event_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_event_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_event_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_event = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_event_insert_record,
+       .get_record = __ctsvc_db_event_get_record,
+       .update_record = __ctsvc_db_event_update_record,
+       .delete_record = __ctsvc_db_event_delete_record,
+       .get_all_records = __ctsvc_db_event_get_all_records,
+       .get_records_with_query = __ctsvc_db_event_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_event_insert_records,
+       .update_records = NULL,//__ctsvc_db_event_update_records,
+       .delete_records = NULL,//__ctsvc_db_event_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_event_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_event_s *event = (ctsvc_event_s *)record;
+
+       RETVM_IF(event->date <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : event date(%d)", event->date);
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", event->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       CTS_ERR("No data : contact_id (%d) is not exist", event->contact_id);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               else {
+                       CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this event record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_event_insert(record, event->contact_id, false, id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(event->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_event_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3, data4, data5 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE id = %d AND datatype = %d ",
+                               id, CTSVC_DATA_EVENT);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ctsvc_db_event_get_value_from_stmt(stmt, out_record, 0);
+
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_event_update_record( contacts_record_h record )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_event_s *event = (ctsvc_event_s *)record;
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", event->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : contact_id (%d) is not exist", event->contact_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this event record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_event_update(record, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("update record failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       // TODO ; contact display event update
+       ret = ctsvc_db_contact_update_changed_time(event->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_event_delete_record( int id )
+{
+       int ret;
+       int contact_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt = NULL;
+       int addressbook_id;
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
+                               "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("The id(%d) is Invalid(%d)", id, ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       contact_id = ctsvc_stmt_get_int(stmt, 0);
+       addressbook_id = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this event record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_event_delete(id, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_event_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int len;
+       int ret;
+       contacts_list_h list;
+       ctsvc_event_s *event;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3, data4, data5 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE datatype = %d AND is_my_profile=0 ",
+                               CTSVC_DATA_EVENT);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB : ctsvc_stmt_step fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_db_event_get_value_from_stmt(stmt, (contacts_record_h*)&event, 0);
+               ctsvc_list_prepend(list, (contacts_record_h)event);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_event_get_records_with_query( contacts_query_h query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_event_s *event;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_event._uri, &record);
+               event = (ctsvc_event_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if(CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_EVENT_ID:
+                               event->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_EVENT_CONTACT_ID:
+                               event->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_EVENT_TYPE:
+                               event->type = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_EVENT_LABEL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               event->label = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_EVENT_DATE:
+                               event->date = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_EVENT_CALENDAR_TYPE:
+                               event->calendar_type = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_EVENT_IS_LEAP_MONTH:
+                               event->is_leap_month = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_event_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_event_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_event_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_event_helper.c b/native/ctsvc_db_plugin_event_helper.c
new file mode 100644 (file)
index 0000000..20572f6
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_plugin_event_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+
+int ctsvc_db_event_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_event_s *event = (ctsvc_event_s *)record;
+
+       // These check should be done in client side
+       RETV_IF(event->date <= 0, CONTACTS_ERROR_NONE);
+       RETVM_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : contact_id(%d) is mandatory field to insert event record", event->contact_id);
+       RETVM_IF(0 < event->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", event->id);
+
+       snprintf(query, sizeof(query),
+               "INSERT INTO "CTS_TABLE_DATA"(contact_id, is_my_profile, datatype, data1, data2, data3, data4, data5) "
+                                                                       "VALUES(%d, %d, %d, %d, ?, ?, ?, %d)",
+                       contact_id, is_my_profile, CTSVC_DATA_EVENT, event->type, event->is_leap_month);
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       if (event->label)
+               ctsvc_stmt_bind_text(stmt, 1, event->label);
+       ctsvc_stmt_bind_int(stmt, 2, event->date);
+       ctsvc_stmt_bind_int(stmt, 3, event->calendar_type);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+
+//     event->id = ctsvc_db_get_last_insert_id();
+       if (id)
+               *id = ctsvc_db_get_last_insert_id();
+
+       ctsvc_stmt_finalize(stmt);
+
+       if (!is_my_profile)
+               ctsvc_set_event_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
+
+int ctsvc_db_event_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count)
+{
+       int ret;
+       ctsvc_event_s *event;
+       char *temp;
+
+       ret = contacts_record_create(_contacts_event._uri, (contacts_record_h *)&event);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+
+       event->id = ctsvc_stmt_get_int(stmt, start_count++);
+       event->contact_id = ctsvc_stmt_get_int(stmt, start_count++);
+       start_count++;  // skip is default
+       event->type = ctsvc_stmt_get_int(stmt, start_count++);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       event->label = SAFE_STRDUP(temp);
+       event->date = ctsvc_stmt_get_int(stmt, start_count++);
+       event->calendar_type = ctsvc_stmt_get_int(stmt, start_count++);
+       event->is_leap_month = ctsvc_stmt_get_int(stmt, start_count++);
+
+       *record = (contacts_record_h)event;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_event_update(contacts_record_h record, bool is_my_profile)
+{
+       int id;
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       ctsvc_event_s *event = (ctsvc_event_s*)record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(!event->id, CONTACTS_ERROR_INVALID_PARAMETER, "event of contact has no ID.");
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (event->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE id = %d", event->id);
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       RETV_IF(ret != CONTACTS_ERROR_NONE, ret);
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_DATA, event->id))) break;
+               if (!is_my_profile)
+                       ctsvc_set_event_noti();
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       return ret;
+}
+
+int ctsvc_db_event_delete(int id, bool is_my_profile)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE id = %d AND datatype = %d",
+                       id, CTSVC_DATA_EVENT);
+
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_exec() Failed(%d)", ret);
+
+       if (!is_my_profile)
+               ctsvc_set_event_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/native/ctsvc_db_plugin_event_helper.h b/native/ctsvc_db_plugin_event_helper.h
new file mode 100644 (file)
index 0000000..e5bf6bd
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_EVENT_HELPER_H__
+#define __CTSVC_DB_PLUGIN_EVENT_HELPER_H__
+
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
+
+int ctsvc_db_event_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id);
+int ctsvc_db_event_update(contacts_record_h record, bool is_my_profile);
+int ctsvc_db_event_delete(int id, bool is_my_profile);
+
+int ctsvc_db_event_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count);
+
+#endif // __CTSVC_DB_PLUGIN_EVENT_HELPER_H__
diff --git a/native/ctsvc_db_plugin_extension.c b/native/ctsvc_db_plugin_extension.c
new file mode 100644 (file)
index 0000000..9006586
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_db_plugin_extension_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_list.h"
+#include "ctsvc_notification.h"
+
+static int __ctsvc_db_extension_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_extension_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_extension_update_record( contacts_record_h record );
+static int __ctsvc_db_extension_delete_record( int id );
+static int __ctsvc_db_extension_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_extension_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_extension_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_extension_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_extension_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_extension = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_extension_insert_record,
+       .get_record = __ctsvc_db_extension_get_record,
+       .update_record = __ctsvc_db_extension_update_record,
+       .delete_record = __ctsvc_db_extension_delete_record,
+       .get_all_records = __ctsvc_db_extension_get_all_records,
+       .get_records_with_query = __ctsvc_db_extension_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_extension_insert_records,
+       .update_records = NULL,//__ctsvc_db_extension_update_records,
+       .delete_records = NULL,//__ctsvc_db_extension_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_extension_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_extension_s *extension = (ctsvc_extension_s *)record;
+
+       RETVM_IF(NULL == extension->data2 && NULL == extension->data3 && NULL == extension->data4
+                       && NULL == extension->data5 && NULL == extension->data6 && NULL == extension->data7
+                       && NULL == extension->data8 && NULL == extension->data9 && NULL == extension->data10
+                       && NULL == extension->data11 && NULL == extension->data12,
+                       CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", extension->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       CTS_ERR("No data : contact_id (%d) is not exist", extension->contact_id);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               else {
+                       CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this extension record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_extension_insert(record, extension->contact_id, false, id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(extension->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_extension_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, "
+                               "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE id = %d AND datatype = %d ",
+                               id, CTSVC_DATA_EXTENSION);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ctsvc_db_extension_get_value_from_stmt(stmt, out_record, 0);
+
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_extension_update_record( contacts_record_h record )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_extension_s *extension = (ctsvc_extension_s *)record;
+
+       RETVM_IF(NULL == extension->data2 && NULL == extension->data3 && NULL == extension->data4 &&
+                       NULL == extension->data5 && NULL == extension->data6 && NULL == extension->data7 &&
+                       NULL == extension->data8 && NULL == extension->data9 && NULL == extension->data10 &&
+                       NULL == extension->data11 && NULL == extension->data12, CONTACTS_ERROR_INVALID_PARAMETER, "extension is empty");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", extension->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : contact_id (%d) is not exist", extension->contact_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this extension record : addressbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_extension_update(record);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("update record failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(extension->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_extension_delete_record( int id )
+{
+       int ret;
+       int contact_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt = NULL;
+       int addressbook_id;
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
+                               "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("The id(%d) is Invalid(%d)", id, ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       contact_id = ctsvc_stmt_get_int(stmt, 0);
+       addressbook_id = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this extension record : addressbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_extension_delete(id, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_extension_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int len;
+       int ret;
+       contacts_list_h list;
+       ctsvc_extension_s *extension;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, "
+                               "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE datatype = %d AND is_my_profile=0 ",
+                               CTSVC_DATA_EXTENSION);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB : ctsvc_stmt_step fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_db_extension_get_value_from_stmt(stmt, (contacts_record_h*)&extension, 0);
+               ctsvc_list_prepend(list, (contacts_record_h)extension);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_extension_get_records_with_query( contacts_query_h query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_extension_s *extension;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_extension._uri, &record);
+               extension = (ctsvc_extension_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if(CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_EXTENSION_ID:
+                               extension->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_EXTENSION_CONTACT_ID:
+                               extension->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_EXTENSION_DATA1:
+                               extension->data1 = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_EXTENSION_DATA2:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               extension->data2 = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_EXTENSION_DATA3:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               extension->data3 = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_EXTENSION_DATA4:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               extension->data4 = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_EXTENSION_DATA5:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               extension->data5 = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_EXTENSION_DATA6:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               extension->data6 = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_EXTENSION_DATA7:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               extension->data7 = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_EXTENSION_DATA8:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               extension->data8 = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_EXTENSION_DATA9:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               extension->data9 = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_EXTENSION_DATA10:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               extension->data10 = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_EXTENSION_DATA11:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               extension->data11 = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_EXTENSION_DATA12:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               extension->data12 = SAFE_STRDUP(temp);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_extension_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_extension_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_extension_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_extension_helper.c b/native/ctsvc_db_plugin_extension_helper.c
new file mode 100644 (file)
index 0000000..762dbb1
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_plugin_extension_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+
+
+int ctsvc_db_extension_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count)
+{
+       int ret;
+       char *temp;
+       ctsvc_extension_s *extension;
+
+       ret = contacts_record_create(_contacts_extension._uri, (contacts_record_h *)&extension);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+
+       extension->id = ctsvc_stmt_get_int(stmt, start_count++);
+       extension->contact_id = ctsvc_stmt_get_int(stmt, start_count++);
+       start_count++;
+       extension->data1 = ctsvc_stmt_get_int(stmt, start_count++);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       extension->data2= SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       extension->data3 = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       extension->data4= SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       extension->data5 = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       extension->data6 = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       extension->data7 = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       extension->data8 = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       extension->data9 = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       extension->data10 = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       extension->data11 = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       extension->data12 = SAFE_STRDUP(temp);
+
+       *record = (contacts_record_h)extension;
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_extension_bind_stmt(cts_stmt stmt, ctsvc_extension_s *extension, int start_cnt)
+{
+       if (extension->data2)
+               ctsvc_stmt_bind_text(stmt, start_cnt, extension->data2);
+       if (extension->data3)
+               ctsvc_stmt_bind_text(stmt, start_cnt+1, extension->data3);
+       if (extension->data4)
+               ctsvc_stmt_bind_text(stmt, start_cnt+2, extension->data4);
+       if (extension->data5)
+               ctsvc_stmt_bind_text(stmt, start_cnt+3, extension->data5);
+       if (extension->data6)
+               ctsvc_stmt_bind_text(stmt, start_cnt+4, extension->data6);
+       if (extension->data7)
+               ctsvc_stmt_bind_text(stmt, start_cnt+5, extension->data7);
+       if (extension->data8)
+               ctsvc_stmt_bind_text(stmt, start_cnt+6, extension->data8);
+       if (extension->data9)
+               ctsvc_stmt_bind_text(stmt, start_cnt+7, extension->data9);
+       if (extension->data10)
+               ctsvc_stmt_bind_text(stmt, start_cnt+8, extension->data10);
+       if (extension->data11)
+               ctsvc_stmt_bind_text(stmt, start_cnt+9, extension->data11);
+       if (extension->data12)
+               ctsvc_stmt_bind_text(stmt, start_cnt+10, extension->data12);
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_extension_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_extension_s *extension = (ctsvc_extension_s *)record;
+
+       RETVM_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : contact_id(%d) is mandatory field to insert extension record ", extension->contact_id);
+       RETVM_IF(0 < extension->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", extension->id);
+
+       if (extension->data2 || extension->data3 || extension->data4 || extension->data5
+                       || extension->data6 || extension->data7 || extension->data8 || extension->data9
+                       || extension->data10 || extension->data11 || extension->data12) {
+               snprintf(query, sizeof(query),
+                       "INSERT INTO "CTS_TABLE_DATA" (contact_id, is_my_profile, datatype, data1, data2, data3, data4, "
+                                                               "data5, data6, data7, data8, data9, data10, data11, data12) "
+                                                               "VALUES(%d, %d, %d, %d, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+                                               contact_id, is_my_profile, CTSVC_DATA_EXTENSION, extension->data1);
+
+               ret = ctsvc_query_prepare(query, &stmt);
+               RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+               __ctsvc_extension_bind_stmt(stmt, extension, 1);
+
+               ret = ctsvc_stmt_step(stmt);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       return ret;
+               }
+
+//             extension->id = ctsvc_db_get_last_insert_id();
+               if (id)
+                       *id = ctsvc_db_get_last_insert_id();
+               ctsvc_stmt_finalize(stmt);
+
+               if (!is_my_profile)
+                       ctsvc_set_data_noti();
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_extension_update(contacts_record_h record)
+{
+       int id;
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       ctsvc_extension_s *extension = (ctsvc_extension_s*)record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(!extension->id, CONTACTS_ERROR_INVALID_PARAMETER, "extension of contact has no ID.");
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (extension->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE id = %d", extension->id);
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       RETV_IF(ret != CONTACTS_ERROR_NONE, ret);
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_DATA, extension->id))) break;
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+       return ret;
+}
+
+int ctsvc_db_extension_delete(int id, bool is_my_profile)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE id = %d AND datatype = %d",
+                       id, CTSVC_DATA_EXTENSION);
+
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_exec() Failed(%d)", ret);
+
+       if (!is_my_profile)
+               ctsvc_set_data_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/native/ctsvc_db_plugin_extension_helper.h b/native/ctsvc_db_plugin_extension_helper.h
new file mode 100644 (file)
index 0000000..e876f1a
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_EXTENSION_HELPER_H__
+#define __CTSVC_DB_PLUGIN_EXTENSION_HELPER_H__
+
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
+
+int ctsvc_db_extension_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id);
+int ctsvc_db_extension_update(contacts_record_h record);
+int ctsvc_db_extension_delete(int id, bool is_my_profile);
+
+int ctsvc_db_extension_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count);
+
+#endif // __CTSVC_DB_PLUGIN_EXTENSION_HELPER_H__
diff --git a/native/ctsvc_db_plugin_group.c b/native/ctsvc_db_plugin_group.c
new file mode 100644 (file)
index 0000000..ba81ba4
--- /dev/null
@@ -0,0 +1,664 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <unistd.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_list.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_group_helper.h"
+
+static int __ctsvc_db_group_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_group_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_group_update_record( contacts_record_h record );
+static int __ctsvc_db_group_delete_record( int id );
+static int __ctsvc_db_group_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_group_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_group_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_group_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_group_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_group = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_group_insert_record,
+       .get_record = __ctsvc_db_group_get_record,
+       .update_record = __ctsvc_db_group_update_record,
+       .delete_record = __ctsvc_db_group_delete_record,
+       .get_all_records = __ctsvc_db_group_get_all_records,
+       .get_records_with_query = __ctsvc_db_group_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_group_insert_records,
+       .update_records = NULL,//__ctsvc_db_group_update_records,
+       .delete_records = NULL,//__ctsvc_db_group_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static double __ctsvc_db_group_get_next_group_prio(void)
+{
+       int ret;
+       double prio = 0.0;
+       cts_stmt stmt;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query), "SELECT MAX(group_prio) FROM "CTS_TABLE_GROUPS" ");
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/  == ret)
+               prio = ctsvc_stmt_get_dbl(stmt, 0);
+       ctsvc_stmt_finalize(stmt);
+
+       return prio + 1.0;
+}
+
+static int __ctsvc_db_group_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int ver;
+       cts_stmt stmt;
+       double group_prio = 0.0;
+       ctsvc_group_s *group = (ctsvc_group_s *)record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETVM_IF(CTSVC_RECORD_GROUP != group->base.r_type, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : record is invalid type(%d)", group->base.r_type);
+       RETVM_IF(NULL == group->name, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : The name of record is empty.");
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF( ret < CONTACTS_ERROR_NONE, ret,  "DB error : ctsvc_begin_trans() Failed(%d)", ret);
+
+       if (false == ctsvc_have_ab_write_permission(group->addressbook_id)) {
+               CTS_ERR("ctsvc_have_ab_write_permission fail : does not have permission(addressbook_id : %d)",
+                                       group->addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       group_prio = __ctsvc_db_group_get_next_group_prio();
+       group->id = ctsvc_db_get_next_id(CTS_TABLE_GROUPS);
+       if (id)
+               *id = group->id;
+
+       snprintf(query, sizeof(query),
+                       "INSERT INTO "CTS_TABLE_GROUPS"(group_id, addressbook_id, group_name, created_ver, changed_ver, ringtone_path, "
+                                               "vibration, message_alert, image_thumbnail_path, extra_data, is_read_only, group_prio) "
+                       "VALUES(%d, %d, ?, ?, ?, ?, ?, ?, ?, ?, %d, %lf)",
+                       group->id, group->addressbook_id, group->is_read_only, group_prio);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_stmt_bind_text(stmt, 1, group->name);
+
+       ver = ctsvc_get_next_ver();
+
+       ctsvc_stmt_bind_int(stmt, 2, ver);
+       ctsvc_stmt_bind_int(stmt, 3, ver);
+
+       if (group->ringtone_path)
+               ctsvc_stmt_bind_text(stmt, 4, group->ringtone_path);
+       if (group->vibration)
+               ctsvc_stmt_bind_text(stmt, 5, group->vibration);
+       if (group->message_alert)
+               ctsvc_stmt_bind_text(stmt, 6, group->message_alert);
+
+       if(group->image_thumbnail_path) {
+               char image[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+               ret = ctsvc_have_file_read_permission(group->image_thumbnail_path);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_have_file_read_permission Fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+
+               ctsvc_utils_make_image_file_name(0, group->id, group->image_thumbnail_path, image, sizeof(image));
+               ret = ctsvc_utils_copy_image(CTS_GROUP_IMAGE_LOCATION, group->image_thumbnail_path, image);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_utils_copy_image() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+
+               free(group->image_thumbnail_path);
+               group->image_thumbnail_path = strdup(image);
+               ctsvc_stmt_bind_text(stmt, 7, group->image_thumbnail_path);
+       }
+
+       if (group->extra_data)
+               ctsvc_stmt_bind_text(stmt, 8, group->extra_data);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_set_group_noti();
+
+       ctsvc_stmt_finalize(stmt);
+
+       ret = ctsvc_end_trans(true);
+       if(ret < CONTACTS_ERROR_NONE ) {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_group_update_record( contacts_record_h record )
+{
+       int addressbook_id = 0;
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       ctsvc_group_s *group = (ctsvc_group_s*)record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt = NULL;
+       bool is_read_only = false;
+       char *image = NULL;
+       char *temp = NULL;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETVM_IF(CTSVC_RECORD_GROUP != group->base.r_type, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : group is invalid type(%d)", group->base.r_type);
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (group->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+       RETVM_IF(NULL == group->name, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : The name of group is empty.");
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id, is_read_only, image_thumbnail_path FROM %s WHERE group_id = %d",
+                       CTS_TABLE_GROUPS, group->id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       CTS_ERR("DB error : The group record(%d) is Invalid(%d)", group->id, ret);
+                       return CONTACTS_ERROR_NO_DATA;
+               }
+               else
+                       return ret;
+       }
+
+       addressbook_id = ctsvc_stmt_get_int(stmt, 0);
+       is_read_only = ctsvc_stmt_get_int(stmt, 1);
+       temp = ctsvc_stmt_get_text(stmt, 2);
+       image = SAFE_STRDUP(temp);
+       ctsvc_stmt_finalize(stmt);
+
+       if (is_read_only && ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_group.name, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               CTS_ERR("Can not change the group name. It is a read-only group (group_id : %d)", group->id);
+               ctsvc_end_trans(false);
+               free(image);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("ctsvc_have_ab_write_permission fail : does not have permission(addressbook_id : %d, group_id : %d)",
+                                       addressbook_id, group->id);
+               ctsvc_end_trans(false);
+               free(image);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)group, _contacts_group.image_path, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               bool same = false;
+               bool check_permission = 0;
+               // delete current image
+               if (image) {
+                       char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+                       snprintf(full_path, sizeof(full_path), "%s/%s", CTS_GROUP_IMAGE_LOCATION, image);
+
+                       if (group->image_thumbnail_path && strcmp(group->image_thumbnail_path, full_path) == 0) {
+                               int index = _contacts_group.image_path & 0x000000FF;
+                               ((ctsvc_record_s *)record)->properties_flags[index] = 0;
+                               same = true;
+                       }
+                       else {
+                               if (group->image_thumbnail_path) {
+                                       ret = ctsvc_have_file_read_permission(group->image_thumbnail_path);
+                                       if (ret != CONTACTS_ERROR_NONE) {
+                                               CTS_ERR("Your module does not have read permission of the image file()");
+                                               ctsvc_end_trans(false);
+                                               free(image);
+                                               return ret;
+                                       }
+                                       check_permission = true;
+                               }
+                               ret = unlink(full_path);
+                               if (ret < 0) {
+                                       CTS_WARN("unlink Failed(%d)", errno);
+                               }
+                       }
+               }
+
+               // add new image file
+               if (!same && group->image_thumbnail_path) {
+                       char dest[CTS_SQL_MAX_LEN] = {0};
+                       if (false == check_permission) {
+                               ret = ctsvc_have_file_read_permission(group->image_thumbnail_path);
+                               if (ret != CONTACTS_ERROR_NONE) {
+                                       CTS_ERR("ctsvc_have_file_read_permission Fail(%d)", ret);
+                                       ctsvc_end_trans(false);
+                                       free(image);
+                                       return ret;
+                               }
+                       }
+                       ctsvc_utils_make_image_file_name(0, group->id, group->image_thumbnail_path, dest, sizeof(dest));
+                       ret = ctsvc_utils_copy_image(CTS_GROUP_IMAGE_LOCATION, group->image_thumbnail_path, dest);
+                       if (CONTACTS_ERROR_NONE != ret) {
+                               CTS_ERR("cts_copy_file() Failed(%d)", ret);
+                               ctsvc_end_trans(false);
+                               free(image);
+                               return ret;
+                       }
+
+                       free(group->image_thumbnail_path);
+                       group->image_thumbnail_path = strdup(dest);
+               }
+       }
+       free(image);
+
+       do {
+               char query[CTS_SQL_MAX_LEN] = {0};
+               char query_set[CTS_SQL_MAX_LEN] = {0};
+               cts_stmt stmt = NULL;
+
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (NULL == set || '\0' == *set)
+                       break;
+               snprintf(query_set, sizeof(query_set), "%s, changed_ver=%d ", set, ctsvc_get_next_ver());
+
+               snprintf(query, sizeof(query), "UPDATE %s SET %s WHERE group_id = %d", CTS_TABLE_GROUPS, query_set, group->id);
+               ret = ctsvc_query_prepare(query, &stmt);
+               if (NULL == stmt) {
+                       CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+                       break;
+               }
+               if (bind_text) {
+                       int i = 0;
+                       for (cursor=bind_text,i=1;cursor;cursor=cursor->next,i++) {
+                               const char *text = cursor->data;
+                               if (text && *text)
+                                       ctsvc_stmt_bind_text(stmt, i, text);
+                       }
+               }
+               ret = ctsvc_stmt_step(stmt);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       break;
+               }
+               ctsvc_stmt_finalize(stmt);
+
+               ctsvc_set_group_noti();
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_end_trans(true);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "DB error : ctsvc_end_trans() Failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_group_delete_record( int id )
+{
+       int ret;
+       int count = 0;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE > ret, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM %s WHERE group_id = %d",
+                       CTS_TABLE_GROUPS, id);
+
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if ( ret < CONTACTS_ERROR_NONE) {
+               CTS_ERR("DB error : The id(%d) is Invalid(%d)", id, addressbook_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("ctsvc_have_ab_write_permission fail : does not have permission(addressbook_id : %d, group_id : %d)",
+                                       addressbook_id, id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       snprintf(query, sizeof(query),
+                               "SELECT COUNT(contact_id) FROM "CTS_TABLE_GROUP_RELATIONS" WHERE group_id = %d", id);
+       ret = ctsvc_query_get_first_int_result(query, &count);
+       if ( ret < CONTACTS_ERROR_NONE) {
+               CTS_ERR("DB error : ctsvc_query_get_first_int_result Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE group_id=%d AND is_read_only=0",
+                       CTS_TABLE_GROUPS, id);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_change();
+       if (ret <= 0) {
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_NO_DATA;
+       }
+
+       ctsvc_get_next_ver();
+
+       ctsvc_set_group_noti();
+       if (count > 0) {
+               ctsvc_set_group_rel_noti();
+               ctsvc_set_contact_noti();
+               ctsvc_set_person_noti();
+       }
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE) {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_group_value_set(cts_stmt stmt, contacts_record_h *record)
+{
+       int i;
+       int ret;
+       char *temp;
+       ctsvc_group_s *group;
+       char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+
+       ret = contacts_record_create(_contacts_group._uri, record);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+       group = (ctsvc_group_s*)*record;
+
+       i = 0;
+       group->id = ctsvc_stmt_get_int(stmt, i++);
+       group->addressbook_id = ctsvc_stmt_get_int(stmt, i++);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       group->name = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       group->extra_data = SAFE_STRDUP(temp);
+       group->is_read_only = ctsvc_stmt_get_int(stmt, i++);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       group->ringtone_path = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       group->vibration = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       group->message_alert = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       if (temp) {
+               snprintf(full_path, sizeof(full_path), "%s/%s", CTS_GROUP_IMAGE_LOCATION, temp);
+               group->image_thumbnail_path = strdup(full_path);
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_group_get_record( int id, contacts_record_h *out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_record_h record;
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT group_id, addressbook_id, group_name, extra_data, is_read_only, "
+                               "ringtone_path, vibration, message_alert, image_thumbnail_path "
+                               "FROM "CTS_TABLE_GROUPS" WHERE group_id = %d", id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ret = __ctsvc_db_group_value_set(stmt, &record);
+
+       ctsvc_stmt_finalize(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_db_group_value_set(ALL) Failed(%d)", ret);
+               return ret;
+       }
+       *out_record = record;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_group_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int len;
+       cts_stmt stmt;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_list_h list;
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT group_id, addressbook_id, group_name, extra_data, is_read_only, "
+                               "ringtone_path, vibration, message_alert, image_thumbnail_path "
+                               "FROM "CTS_TABLE_GROUPS);
+
+
+       len += snprintf(query+len, sizeof(query)-len, " ORDER BY addressbook_id, group_prio");
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               __ctsvc_db_group_value_set(stmt, &record);
+
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_group_get_records_with_query( contacts_query_h query,
+       int offset, int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_group_s *group;
+       char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_group._uri, &record);
+               group = (ctsvc_group_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else
+               {
+                       field_count = s_query->projection_count;
+
+                       if( CONTACTS_ERROR_NONE != ctsvc_record_set_projection_flags(record, s_query->projection, s_query->projection_count, s_query->property_count) )
+                       {
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+                       }
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_GROUP_ID:
+                               group->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_GROUP_ADDRESSBOOK_ID:
+                               group->addressbook_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_GROUP_NAME:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               group->name = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_GROUP_RINGTONE:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               group->ringtone_path = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_GROUP_IMAGE:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               if (temp) {
+                                       snprintf(full_path, sizeof(full_path), "%s/%s", CTS_GROUP_IMAGE_LOCATION, temp);
+                                       group->image_thumbnail_path = strdup(full_path);
+                               }
+                               break;
+                       case CTSVC_PROPERTY_GROUP_VIBRATION:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               group->vibration = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_GROUP_MESSAGE_ALERT:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               group->message_alert = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_GROUP_EXTRA_DATA:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               group->extra_data = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_GROUP_IS_READ_ONLY:
+                               group->is_read_only = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_group_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_group_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_group_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
+
+
diff --git a/native/ctsvc_db_plugin_group_helper.c b/native/ctsvc_db_plugin_group_helper.c
new file mode 100644 (file)
index 0000000..9a5a552
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <ctype.h>
+#include <unistd.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_plugin_group_helper.h"
+
+// Whenever deleting group, this function will be called
+// in order to deleting group image file
+void ctsvc_db_group_delete_callback(sqlite3_context *context, int argc, sqlite3_value ** argv)
+{
+       int ret;
+       const unsigned char* path;
+
+       if (argc > 1) {
+               sqlite3_result_null(context);
+               return;
+       }
+       path = sqlite3_value_text(argv[0]);
+
+       if (path) {
+               char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+               snprintf(full_path, sizeof(full_path), "%s/%s", CTS_GROUP_IMAGE_LOCATION, path);
+               ret = unlink(full_path);
+               if (ret < 0) {
+                       CTS_WARN("unlink Failed(%d)", errno);
+               }
+       }
+
+       return;
+}
+
+
diff --git a/native/ctsvc_db_plugin_group_helper.h b/native/ctsvc_db_plugin_group_helper.h
new file mode 100644 (file)
index 0000000..2000884
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_GROUP_HELPER_H__
+#define __CTSVC_DB_PLUGIN_GROUP_HELPER_H__
+
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
+
+#define CTS_GROUP_IMAGE_LOCATION "/opt/usr/data/contacts-svc/img/group"
+
+void ctsvc_db_group_delete_callback(sqlite3_context *context, int argc, sqlite3_value ** argv);
+
+#endif // __CTSVC_DB_PLUGIN_GROUP_HELPER_H__
diff --git a/native/ctsvc_db_plugin_grouprelation.c b/native/ctsvc_db_plugin_grouprelation.c
new file mode 100644 (file)
index 0000000..f832376
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_list.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_record.h"
+#include "ctsvc_db_access_control.h"
+
+static int __ctsvc_db_grouprelation_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_grouprelation_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_grouprelation_update_record( contacts_record_h record );
+static int __ctsvc_db_grouprelation_delete_record( int id );
+static int __ctsvc_db_grouprelation_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_grouprelation_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_grouprelation_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_grouprelation_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_grouprelation_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_grouprelation = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_grouprelation_insert_record,
+       .get_record = __ctsvc_db_grouprelation_get_record,
+       .update_record = __ctsvc_db_grouprelation_update_record,
+       .delete_record = __ctsvc_db_grouprelation_delete_record,
+       .get_all_records = __ctsvc_db_grouprelation_get_all_records,
+       .get_records_with_query = __ctsvc_db_grouprelation_get_records_with_query,
+       .insert_records = NULL, //__ctsvc_db_grouprelation_insert_records,
+       .update_records = NULL, //__ctsvc_db_grouprelation_update_records,
+       .delete_records = NULL, //__ctsvc_db_grouprelation_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_grouprelation_insert_record( contacts_record_h record, int *id )
+{
+       CTS_ERR("Please use the contacts_group_add_contact()");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_db_grouprelation_get_record( int id, contacts_record_h* out_record )
+{
+       CTS_ERR("Not support get group-relation");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_db_grouprelation_update_record( contacts_record_h record )
+{
+       CTS_ERR("Not support update group-relation");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_db_grouprelation_delete_record( int id )
+{
+       CTS_ERR("Please use the contacts_group_remove_contact()");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_db_grouprelation_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int len;
+       int ret;
+       contacts_list_h list;
+       ctsvc_group_relation_s *grouprel;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       char *temp;
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT group_id, contact_id, group_name FROM "CTSVC_DB_VIEW_GROUP_RELATION);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               contacts_record_create(_contacts_group_relation._uri, (contacts_record_h*)&grouprel);
+
+               if (grouprel) {
+                       grouprel->group_id = ctsvc_stmt_get_int(stmt, 0);
+                       grouprel->id = grouprel->group_id;
+                       grouprel->contact_id = ctsvc_stmt_get_int(stmt, 1);
+                       temp = ctsvc_stmt_get_text(stmt, 2);
+                       grouprel->group_name = SAFE_STRDUP(temp);
+
+                       ctsvc_list_prepend(list, (contacts_record_h)grouprel);
+               }
+       }
+
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_grouprelation_get_records_with_query( contacts_query_h query,
+               int offset, int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_group_relation_s *group_relation;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_group_relation._uri, &record);
+               group_relation = (ctsvc_group_relation_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else
+               {
+                       field_count = s_query->projection_count;
+
+                       if( CONTACTS_ERROR_NONE != ctsvc_record_set_projection_flags(record, s_query->projection, s_query->projection_count, s_query->property_count) )
+                       {
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+                       }
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       if (CTSVC_PROPERTY_GROUP_RELATION_ID == property_id)
+                               continue;
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_GROUP_RELATION_CONTACT_ID:
+                               group_relation->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_GROUP_RELATION_GROUP_ID:
+                               group_relation->group_id = ctsvc_stmt_get_int(stmt, i);
+                               group_relation->id = group_relation->group_id;
+                               break;
+                       case CTSVC_PROPERTY_GROUP_RELATION_GROUP_NAME:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               group_relation->group_name = SAFE_STRDUP(temp);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_grouprelation_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_grouprelation_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_grouprelation_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_image.c b/native/ctsvc_db_plugin_image.c
new file mode 100644 (file)
index 0000000..540950c
--- /dev/null
@@ -0,0 +1,675 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_image_helper.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_list.h"
+#include "ctsvc_notification.h"
+
+static int __ctsvc_db_image_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_image_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_image_update_record( contacts_record_h record );
+static int __ctsvc_db_image_delete_record( int id );
+static int __ctsvc_db_image_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_image_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_image_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_image_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_image_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_image = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_image_insert_record,
+       .get_record = __ctsvc_db_image_get_record,
+       .update_record = __ctsvc_db_image_update_record,
+       .delete_record = __ctsvc_db_image_delete_record,
+       .get_all_records = __ctsvc_db_image_get_all_records,
+       .get_records_with_query = __ctsvc_db_image_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_image_insert_records,
+       .update_records = NULL,//__ctsvc_db_image_update_records,
+       .delete_records = NULL,//__ctsvc_db_image_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_image_get_default_image_id(int contact_id)
+{
+       int ret;
+       int image_id = 0;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE datatype=%d AND contact_id=%d AND is_default=1",
+                       CTSVC_DATA_IMAGE, contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &image_id);
+       if (CONTACTS_ERROR_NONE != ret)
+               return 0;
+       return image_id;
+}
+
+static int __ctsvc_db_image_set_primary_default(int image_id, bool is_primary_default)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_DATA" SET is_primary_default = %d WHERE id = %d",
+                       is_primary_default, image_id);
+       ret = ctsvc_query_exec(query);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Failed(%d)", ret);
+       return ret;
+}
+
+static int __ctsvc_db_image_set_default(int image_id, int contact_id, bool is_default, bool is_primary_default)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_DATA" SET is_default = %d, is_primary_default = %d WHERE id = %d",
+                       is_default, is_primary_default, image_id);
+       ret = ctsvc_query_exec(query);
+
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Failed(%d)", ret);
+       return ret;
+}
+
+static int __ctsvc_db_image_get_primary_default_image_id(int person_id)
+{
+       int ret;
+       int default_image_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_CONTACTS" c, "CTS_TABLE_DATA" d "
+                       "WHERE c.person_id = %d AND d.datatype = %d AND c.contact_id = d.contact_id AND d.is_default = 1",
+                       person_id, CTSVC_DATA_IMAGE);
+       ret = ctsvc_query_get_first_int_result(query, &default_image_id);
+       if (CONTACTS_ERROR_NONE != ret)
+               return 0;
+       return default_image_id;
+}
+
+static int __ctsvc_db_image_get_primary_default_contact_id(int person_id)
+{
+       int ret;
+       int default_contact_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "SELECT c.contact_id FROM "CTS_TABLE_CONTACTS" c, "CTS_TABLE_DATA" d "
+                       "WHERE c.person_id = %d AND d.datatype = %d AND c.contact_id = d.contact_id AND d.is_primary_default = 1",
+                       person_id, CTSVC_DATA_IMAGE);
+       ret = ctsvc_query_get_first_int_result(query, &default_contact_id);
+       if (CONTACTS_ERROR_NONE != ret)
+               return 0;
+       return default_contact_id;
+}
+
+static int __ctsvc_db_image_update_contact_image(int contact_id, const char *image_path)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt;
+
+       snprintf(query, sizeof(query), "UPDATE "CTS_TABLE_CONTACTS" SET image_thumbnail_path=? WHERE contact_id = %d", contact_id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       if (image_path)
+               ctsvc_stmt_bind_text(stmt, 1, image_path);
+
+       ret = ctsvc_stmt_step(stmt);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_stmt_step() Failed(%d)", ret);
+
+       ctsvc_stmt_finalize(stmt);
+
+       return ret;
+}
+
+static int __ctsvc_db_image_update_person_image(int person_id, const char *image_path)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt;
+
+       snprintf(query, sizeof(query), "UPDATE "CTS_TABLE_PERSONS" SET image_thumbnail_path=? WHERE person_id = %d", person_id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       if (image_path)
+               ctsvc_stmt_bind_text(stmt, 1, image_path);
+
+       ret = ctsvc_stmt_step(stmt);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_stmt_step() Failed(%d)", ret);
+
+       ctsvc_stmt_finalize(stmt);
+
+       return ret;
+}
+
+static int __ctsvc_db_image_insert_record( contacts_record_h record, int *id )
+{
+       int len = 0;
+       int ret;
+       int version;
+       int addressbook_id;
+       int person_id;
+       int old_default_image_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_image_s *image = (ctsvc_image_s *)record;
+       cts_stmt stmt = NULL;
+
+       RETVM_IF(NULL == image->path, CONTACTS_ERROR_INVALID_PARAMETER,
+               "Invalid parameter : image path is NULL");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id, person_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", image->contact_id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (ret == CONTACTS_ERROR_NONE)
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               else
+                       return ret;
+       }
+
+       addressbook_id = ctsvc_stmt_get_int(stmt, 0);
+       person_id = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this image record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       old_default_image_id = __ctsvc_db_image_get_default_image_id(image->contact_id);
+       if (0 == old_default_image_id)
+               image->is_default = true;
+
+       ret = ctsvc_db_image_insert(record, image->contact_id, false, id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       version = ctsvc_get_next_ver();
+       len = snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_CONTACTS" SET changed_ver = %d, changed_time = %d, image_changed_ver = %d ",
+                       version, (int)time(NULL), version);
+
+       if (image->is_default)
+               len += snprintf(query + len, sizeof(query) - len, ", image_thumbnail_path=? ");
+
+       snprintf(query + len, sizeof(query) - len, " WHERE contact_id = %d", image->contact_id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       if (image->is_default)
+               ctsvc_stmt_bind_text(stmt, 1, image->path);
+
+       ret = ctsvc_stmt_step(stmt);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_stmt_step() Failed(%d)", ret);
+       ctsvc_stmt_finalize(stmt);
+
+       if (image->is_default) {
+               int primary_default_contact_id;
+
+               primary_default_contact_id = __ctsvc_db_image_get_primary_default_contact_id(person_id);
+               if (primary_default_contact_id == 0 || primary_default_contact_id == image->contact_id) {
+                       __ctsvc_db_image_set_primary_default(*id, true);
+                       __ctsvc_db_image_update_person_image(person_id, image->path);
+               }
+       }
+
+       ctsvc_set_contact_noti();
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_image_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE id = %d AND datatype = %d ",
+                               id, CTSVC_DATA_IMAGE);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ctsvc_db_image_get_value_from_stmt(stmt, out_record, 0);
+
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_image_update_record( contacts_record_h record )
+{
+       int len = 0;
+       int ret;
+       int version;
+       int person_id;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_image_s *image = (ctsvc_image_s *)record;
+       cts_stmt stmt = NULL;
+       RETVM_IF(NULL == image->path, CONTACTS_ERROR_INVALID_PARAMETER, "path is empty");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id, person_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", image->contact_id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+       addressbook_id = ctsvc_stmt_get_int(stmt, 0);
+       person_id = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this image record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_image_update(record, image->contact_id, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       version = ctsvc_get_next_ver();
+       len = snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_CONTACTS" SET changed_ver = %d, changed_time = %d, image_changed_ver = %d ",
+                       version, (int)time(NULL), version);
+
+       if (image->is_default)
+               len += snprintf(query + len, sizeof(query) - len, ", image_thumbnail_path=? ");
+
+       snprintf(query + len, sizeof(query) - len, " WHERE contact_id = %d", image->contact_id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       if (image->is_default)
+               ctsvc_stmt_bind_text(stmt, 1, image->path);
+
+       ret = ctsvc_stmt_step(stmt);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_stmt_step() Failed(%d)", ret);
+       ctsvc_stmt_finalize(stmt);
+
+       if (image->is_default) {
+               int primary_default_contact_id;
+               primary_default_contact_id = __ctsvc_db_image_get_primary_default_contact_id(image->contact_id);
+               if (image->contact_id == primary_default_contact_id) {
+                       __ctsvc_db_image_set_primary_default(image->id, true);
+                       __ctsvc_db_image_update_person_image(person_id, image->path);
+               }
+       }
+
+       ctsvc_set_contact_noti();
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_image_delete_record( int id )
+{
+       int ret;
+       int version;
+       int image_id;
+       int contact_id;
+       int person_id;
+       int is_default;
+       int is_primary_default;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt = NULL;
+       int addressbook_id;
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, person_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
+                       "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               CTS_ERR("The id(%d) is Invalid(%d)", id, ret);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+       contact_id = ctsvc_stmt_get_int(stmt, 0);
+       person_id = ctsvc_stmt_get_int(stmt, 1);
+       addressbook_id = ctsvc_stmt_get_int(stmt, 2);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this image record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT is_default, is_primary_default FROM "CTS_TABLE_DATA" WHERE id = %d", id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       is_default = ctsvc_stmt_get_int(stmt, 0);
+       is_primary_default = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       ret = ctsvc_db_image_delete(id, false);
+
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       version = ctsvc_get_next_ver();
+       snprintf(query, sizeof(query),
+               "UPDATE "CTS_TABLE_CONTACTS" SET changed_ver = %d, changed_time = %d, image_changed_ver = %d "
+                       "WHERE contact_id = %d",
+                       version, (int)time(NULL), version, contact_id);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (is_default) {
+               snprintf(query, sizeof(query),
+                               "SELECT id FROM "CTS_TABLE_DATA" WHERE datatype = %d AND contact_id = %d AND is_my_profile = 0 limit 1",
+                               CTSVC_DATA_IMAGE, contact_id);
+               ret = ctsvc_query_get_first_int_result(query, &image_id);
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_get_first_int_result() Fail(%d)", ret);
+
+               if (image_id) {
+                       __ctsvc_db_image_set_default(image_id, contact_id, is_default, is_primary_default);
+               }
+               else {
+                       __ctsvc_db_image_update_contact_image(contact_id, NULL);
+                       if (is_primary_default) {
+                               int default_img_id = 0;
+                               default_img_id = __ctsvc_db_image_get_primary_default_image_id(person_id);
+                               if (default_img_id)
+                                       __ctsvc_db_image_set_primary_default(default_img_id, true);
+                               else
+                                       __ctsvc_db_image_update_person_image(person_id, NULL);
+                       }
+               }
+       }
+
+       ctsvc_set_contact_noti();
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_image_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int len;
+       int ret;
+       contacts_list_h list;
+       ctsvc_image_s *image;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE datatype = %d AND is_my_profile=0 ",
+                               CTSVC_DATA_IMAGE);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB : ctsvc_stmt_step fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_db_image_get_value_from_stmt(stmt, (contacts_record_h*)&image, 0);
+               ctsvc_list_prepend(list, (contacts_record_h)image);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_image_get_records_with_query( contacts_query_h query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_image_s *image;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_image._uri, &record);
+               image = (ctsvc_image_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if(CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_IMAGE_ID:
+                               image->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_IMAGE_CONTACT_ID:
+                               image->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_IMAGE_TYPE:
+                               image->type = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_IMAGE_LABEL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               image->label = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_IMAGE_PATH:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               image->path = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_IMAGE_IS_DEFAULT:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               image->is_default = SAFE_STRDUP(temp);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_image_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_image_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_image_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_image_helper.c b/native/ctsvc_db_plugin_image_helper.c
new file mode 100644 (file)
index 0000000..2905f6f
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_plugin_image_helper.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_access_control.h"
+
+int ctsvc_db_image_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count)
+{
+       int ret;
+       char *temp;
+       ctsvc_image_s *image;
+
+       ret = contacts_record_create(_contacts_image._uri, (contacts_record_h *)&image);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+
+       image->id = ctsvc_stmt_get_int(stmt, start_count++);
+       image->contact_id = ctsvc_stmt_get_int(stmt, start_count++);
+       image->is_default = ctsvc_stmt_get_int(stmt, start_count++);
+       image->type = ctsvc_stmt_get_int(stmt, start_count++);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       image->label = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       if (temp) {
+               char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+               snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
+               image->path = strdup(full_path);
+       }
+
+       *record = (contacts_record_h)image;
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_image_bind_stmt(cts_stmt stmt, ctsvc_image_s *image, int start_cnt)
+{
+       if (image->label)
+               ctsvc_stmt_bind_text(stmt, start_cnt, image->label);
+       if (image->path)
+               ctsvc_stmt_bind_text(stmt, start_cnt+1, image->path);
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_image_reset_default(int image_id, int contact_id)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_DATA" SET is_default=0, is_primary_default=0 WHERE id != %d AND contact_id = %d AND datatype=%d",
+                       image_id, contact_id, CTSVC_DATA_IMAGE);
+       ret = ctsvc_query_exec(query);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Failed(%d)", ret);
+       return ret;
+}
+
+int ctsvc_db_image_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id)
+{
+       int ret;
+       int image_id;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       char image_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+       ctsvc_image_s *image = (ctsvc_image_s *)record;
+
+       // These check should be done in client side
+       RETV_IF(NULL == image->path, CONTACTS_ERROR_NONE);
+       RETVM_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : contact_id(%d) is mandatory field to insert image record", image->contact_id);
+       RETVM_IF(0 < image->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", image->id);
+
+       ret = ctsvc_have_file_read_permission(image->path);
+       RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "ctsvc_have_file_read_permission fail(%d)", ret);
+
+       image_id = ctsvc_db_get_next_id(CTS_TABLE_DATA);
+       ret = ctsvc_contact_add_image_file(contact_id, image_id, image->path, image_path, sizeof(image_path));
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_contact_add_image_file() Failed(%d)", ret);
+               return ret;
+       }
+       free(image->path);
+       image->path = strdup(image_path);
+
+       snprintf(query, sizeof(query),
+                       "INSERT INTO "CTS_TABLE_DATA"(id, contact_id, is_my_profile, datatype, is_default, is_primary_default, data1, data2, data3) "
+                       "VALUES(%d, %d, %d, %d, %d, %d, %d, ?, ?)",
+                       image_id, contact_id, is_my_profile, CTSVC_DATA_IMAGE, image->is_default, image->is_default, image->type);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       __ctsvc_image_bind_stmt(stmt, image, 1);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+
+       //image->id = ctsvc_db_get_last_insert_id();
+       if (id)
+               *id = image_id;
+       ctsvc_stmt_finalize(stmt);
+
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_image.is_default, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               if (image->is_default)
+                       __ctsvc_db_image_reset_default(image_id, contact_id);
+       }
+
+       if (!is_my_profile)
+               ctsvc_set_image_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_image_update(contacts_record_h record, int contact_id, bool is_my_profile)
+{
+       int id;
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       ctsvc_image_s *image = (ctsvc_image_s*)record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(!image->id, CONTACTS_ERROR_INVALID_PARAMETER, "image of contact has no ID.");
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (image->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE id = %d", image->id);
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       RETV_IF(ret != CONTACTS_ERROR_NONE, ret);
+
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_image.path, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               char image_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+               if (image->path) {
+                       ret = ctsvc_have_file_read_permission(image->path);
+                       if (ret != CONTACTS_ERROR_NONE) {
+                               CTS_ERR("ctsvc_have_file_read_permission Fail(%d)", ret);
+                               return ret;
+                       }
+               }
+
+               ret = ctsvc_contact_update_image_file(contact_id, image->id, image->path, image_path, sizeof(image_path));
+               RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_contact_update_image_file() Failed(%d)", ret);
+
+               if (*image_path) {
+                       free(image->path);
+                       image->path = strdup(image_path);
+               }
+       }
+
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_image.is_default, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               if (image->is_default)
+                       __ctsvc_db_image_reset_default(image->id, contact_id);
+       }
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_DATA, image->id))) break;
+               if (!is_my_profile)
+                       ctsvc_set_image_noti();
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+       return ret;
+}
+
+int ctsvc_db_image_delete(int id, bool is_my_profile)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE id = %d AND datatype = %d",
+                       id, CTSVC_DATA_IMAGE);
+
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_exec() Failed(%d)", ret);
+
+       if (!is_my_profile)
+               ctsvc_set_image_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
+// Whenever deleting image recode in data table, this funcion will be called
+// in order to delete the image file
+void ctsvc_db_image_delete_callback(sqlite3_context *context, int argc, sqlite3_value ** argv)
+{
+       int ret;
+       const unsigned char* image_path;
+
+       if (argc > 1) {
+               sqlite3_result_null(context);
+               return;
+       }
+       image_path = sqlite3_value_text(argv[0]);
+
+       ret = ctsvc_contact_delete_image_file_with_path(image_path);
+       WARN_IF (CONTACTS_ERROR_NONE != ret && CONTACTS_ERROR_NO_DATA != ret,
+                       "ctsvc_contact_delete_image_file_with_path Failed(%d)", ret);
+
+       return;
+}
+
+
diff --git a/native/ctsvc_db_plugin_image_helper.h b/native/ctsvc_db_plugin_image_helper.h
new file mode 100644 (file)
index 0000000..6a6daac
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_IMAGE_HELPER_H__
+#define __CTSVC_DB_PLUGIN_IMAGE_HELPER_H__
+
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
+
+int ctsvc_db_image_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id);
+int ctsvc_db_image_update(contacts_record_h record, int contact_id, bool is_my_profile);
+int ctsvc_db_image_delete(int id, bool is_my_profile);
+int ctsvc_db_image_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count);
+void ctsvc_db_image_delete_callback(sqlite3_context *context, int argc, sqlite3_value ** argv);
+
+#endif // __CTSVC_DB_PLUGIN_RELATIONSHIP_HELPER_H__
diff --git a/native/ctsvc_db_plugin_messenger.c b/native/ctsvc_db_plugin_messenger.c
new file mode 100644 (file)
index 0000000..f3e7cfd
--- /dev/null
@@ -0,0 +1,405 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_db_plugin_messenger_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_list.h"
+
+static int __ctsvc_db_messenger_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_messenger_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_messenger_update_record( contacts_record_h record );
+static int __ctsvc_db_messenger_delete_record( int id );
+static int __ctsvc_db_messenger_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_messenger_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_messenger_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_messenger_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_messenger_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_messenger = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_messenger_insert_record,
+       .get_record = __ctsvc_db_messenger_get_record,
+       .update_record = __ctsvc_db_messenger_update_record,
+       .delete_record = __ctsvc_db_messenger_delete_record,
+       .get_all_records = __ctsvc_db_messenger_get_all_records,
+       .get_records_with_query = __ctsvc_db_messenger_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_messenger_insert_records,
+       .update_records = NULL,//__ctsvc_db_messenger_update_records,
+       .delete_records = NULL,//__ctsvc_db_messenger_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_messenger_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_messenger_s *messenger = (ctsvc_messenger_s *)record;
+
+       RETVM_IF(NULL == messenger->im_id, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : messenger id is NULL");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", messenger->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       CTS_ERR("No data : contact_id (%d) is not exist", messenger->contact_id);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               else {
+                       CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this messenger record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_messenger_insert(record, messenger->contact_id, false, id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(messenger->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_messenger_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE id = %d AND datatype = %d ",
+                               id, CTSVC_DATA_MESSENGER);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ctsvc_db_messenger_get_value_from_stmt(stmt, out_record, 0);
+
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_messenger_update_record( contacts_record_h record )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_messenger_s *messenger = (ctsvc_messenger_s *)record;
+       RETVM_IF(NULL == messenger->im_id, CONTACTS_ERROR_INVALID_PARAMETER, "im_id is empty");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", messenger->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : contact_id (%d) is not exist", messenger->contact_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this messenger record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_messenger_update(record, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("Update record Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(messenger->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_messenger_delete_record( int id )
+{
+       int ret;
+       int contact_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt = NULL;
+       int addressbook_id;
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
+                               "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("The id(%d) is Invalid(%d)", id, ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       contact_id = ctsvc_stmt_get_int(stmt, 0);
+       addressbook_id = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this messenger record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_messenger_delete(id, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_messenger_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int len;
+       int ret;
+       contacts_list_h list;
+       ctsvc_messenger_s *messenger;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE datatype = %d AND is_my_profile=0 ",
+                               CTSVC_DATA_MESSENGER);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB : ctsvc_stmt_step fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_db_messenger_get_value_from_stmt(stmt, (contacts_record_h*)&messenger, 0);
+               ctsvc_list_prepend(list, (contacts_record_h)messenger);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_messenger_get_records_with_query( contacts_query_h query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_messenger_s *messenger;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_messenger._uri, &record);
+               messenger = (ctsvc_messenger_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if(CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_MESSENGER_ID:
+                               messenger->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_MESSENGER_CONTACT_ID:
+                               messenger->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_MESSENGER_TYPE:
+                               messenger->type = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_MESSENGER_LABEL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               messenger->label = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_MESSENGER_IM_ID:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               messenger->im_id = SAFE_STRDUP(temp);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_messenger_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_messenger_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_messenger_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_messenger_helper.c b/native/ctsvc_db_plugin_messenger_helper.c
new file mode 100644 (file)
index 0000000..c8018ad
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_plugin_messenger_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+
+
+int ctsvc_db_messenger_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count)
+{
+       int ret;
+       char *temp;
+       ctsvc_messenger_s *messenger;
+
+       ret = contacts_record_create(_contacts_messenger._uri, (contacts_record_h *)&messenger);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+
+       messenger->id = ctsvc_stmt_get_int(stmt, start_count++);
+       messenger->contact_id = ctsvc_stmt_get_int(stmt, start_count++);
+       start_count++;
+       messenger->type = ctsvc_stmt_get_int(stmt, start_count++);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       messenger->label = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       messenger->im_id = SAFE_STRDUP(temp);
+
+       *record = (contacts_record_h)messenger;
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_messenger_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       ctsvc_messenger_s *messenger =(ctsvc_messenger_s*)record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETV_IF(NULL == messenger->im_id, CONTACTS_ERROR_NONE);
+       RETVM_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : contact_id(%d) is mandatory field to insert messenger record ", messenger->contact_id);
+       RETVM_IF(0 < messenger->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", messenger->id);
+
+       snprintf(query, sizeof(query),
+               "INSERT INTO "CTS_TABLE_DATA"(contact_id, is_my_profile, datatype, data1, data2, data3) "
+                                       "VALUES(%d, %d, %d, %d, ?, ?)",
+                       contact_id, is_my_profile, CTSVC_DATA_MESSENGER, messenger->type);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       if (messenger->label)
+               sqlite3_bind_text(stmt, 1, messenger->label,
+                       strlen(messenger->label), SQLITE_STATIC);
+       if (messenger->im_id)
+               sqlite3_bind_text(stmt, 2, messenger->im_id,
+                               strlen(messenger->im_id), SQLITE_STATIC);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+
+       //messenger->id = ctsvc_db_get_last_insert_id();
+       if (id)
+               *id = ctsvc_db_get_last_insert_id();
+       ctsvc_stmt_finalize(stmt);
+
+       if (!is_my_profile)
+               ctsvc_set_messenger_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_messenger_update(contacts_record_h record, bool is_my_profile)
+{
+       int id;
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       ctsvc_messenger_s *messenger = (ctsvc_messenger_s*)record;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       RETVM_IF(!messenger->id, CONTACTS_ERROR_INVALID_PARAMETER, "messenger of contact has no ID.");
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (messenger->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE id = %d", messenger->id);
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       RETV_IF(ret != CONTACTS_ERROR_NONE, ret);
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_DATA, messenger->id))) break;
+               if (!is_my_profile)
+                       ctsvc_set_messenger_noti();
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       return ret;
+}
+
+int ctsvc_db_messenger_delete(int id, bool is_my_profile)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE id = %d AND datatype = %d",
+                       id, CTSVC_DATA_MESSENGER);
+
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_exec() Failed(%d)", ret);
+
+       if (!is_my_profile)
+               ctsvc_set_messenger_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/native/ctsvc_db_plugin_messenger_helper.h b/native/ctsvc_db_plugin_messenger_helper.h
new file mode 100644 (file)
index 0000000..f7e3671
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_MESSENGER_HELPER_H__
+#define __CTSVC_DB_PLUGIN_MESSENGER_HELPER_H__
+
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
+
+int ctsvc_db_messenger_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id);
+int ctsvc_db_messenger_update(contacts_record_h record, bool is_my_profile);
+int ctsvc_db_messenger_delete(int id, bool is_my_profile);
+int ctsvc_db_messenger_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count);
+
+#endif // __CTSVC_DB_PLUGIN_MESSENGER_HELPER_H__
diff --git a/native/ctsvc_db_plugin_my_profile.c b/native/ctsvc_db_plugin_my_profile.c
new file mode 100644 (file)
index 0000000..81e810f
--- /dev/null
@@ -0,0 +1,1254 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_record.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_list.h"
+#include "ctsvc_setting.h"
+#include "ctsvc_localize_ch.h"
+#include "ctsvc_group.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_localize_utils.h"
+#include "ctsvc_db_access_control.h"
+
+#include "ctsvc_db_plugin_contact_helper.h"
+
+#define CTSVC_MY_PROFILE_DISPLAY_NAME_MAX_LEN 1024
+
+static int __ctsvc_db_my_profile_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_my_profile_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_my_profile_update_record( contacts_record_h record );
+static int __ctsvc_db_my_profile_delete_record( int id );
+
+static int __ctsvc_db_my_profile_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_my_profile_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_my_profile = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_my_profile_insert_record,
+       .get_record = __ctsvc_db_my_profile_get_record,
+       .update_record = __ctsvc_db_my_profile_update_record,
+       .delete_record = __ctsvc_db_my_profile_delete_record,
+       .get_all_records = __ctsvc_db_my_profile_get_all_records,
+       .get_records_with_query = __ctsvc_db_my_profile_get_records_with_query,
+       .insert_records = NULL,
+       .update_records = NULL,
+       .delete_records = NULL,
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_get_my_profile_base_info(int id, ctsvc_my_profile_s *my_profile)
+{
+       int ret;
+       int i;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       char *temp;
+       char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+
+       snprintf(query, sizeof(query),
+                       "SELECT my_profile_id, addressbook_id, changed_time, %s, image_thumbnail_path, uid "
+                               "FROM "CTS_TABLE_MY_PROFILES" WHERE my_profile_id = %d AND deleted = 0",
+                               ctsvc_get_display_column(), id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       i = 0;
+       my_profile->id = ctsvc_stmt_get_int(stmt, i++);
+       my_profile->addressbook_id = ctsvc_stmt_get_int(stmt, i++);
+       my_profile->changed_time = ctsvc_stmt_get_int(stmt, i++);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       my_profile->display_name = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       if (temp) {
+               snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
+               my_profile->image_thumbnail_path = strdup(full_path);
+       }
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       my_profile->uid = SAFE_STRDUP(temp);
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_my_profile_get_data(int id, ctsvc_my_profile_s *my_profile)
+{
+       int ret;
+       int datatype;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                               "SELECT datatype, id, contact_id, is_default, data1, data2, "
+                                       "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
+                                       "FROM "CTS_TABLE_DATA" WHERE contact_id = %d AND is_my_profile = 1", id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE */!= ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+
+       do {
+               datatype = ctsvc_stmt_get_int(stmt, 0);
+               switch (datatype) {
+               case CTSVC_DATA_NAME:
+                       ctsvc_get_data_info_name(stmt, (contacts_list_h)my_profile->name);
+                       break;
+               case CTSVC_DATA_EVENT:
+                       ctsvc_get_data_info_event(stmt, (contacts_list_h)my_profile->events);
+                       break;
+               case CTSVC_DATA_MESSENGER:
+                       ctsvc_get_data_info_messenger(stmt, (contacts_list_h)my_profile->messengers);
+                       break;
+               case CTSVC_DATA_POSTAL:
+                       ctsvc_get_data_info_address(stmt, (contacts_list_h)my_profile->postal_addrs);
+                       break;
+               case CTSVC_DATA_URL:
+                       ctsvc_get_data_info_url(stmt, (contacts_list_h)my_profile->urls);
+                       break;
+               case CTSVC_DATA_NICKNAME:
+                       ctsvc_get_data_info_nickname(stmt, (contacts_list_h)my_profile->nicknames);
+                       break;
+               case CTSVC_DATA_NUMBER:
+                       ctsvc_get_data_info_number(stmt, (contacts_list_h)my_profile->numbers);
+                       break;
+               case CTSVC_DATA_EMAIL:
+                       ctsvc_get_data_info_email(stmt, (contacts_list_h)my_profile->emails);
+                       break;
+               case CTSVC_DATA_PROFILE:
+                       ctsvc_get_data_info_profile(stmt, (contacts_list_h)my_profile->profiles);
+                       break;
+               case CTSVC_DATA_RELATIONSHIP:
+                       ctsvc_get_data_info_relationship(stmt, (contacts_list_h)my_profile->relationships);
+                       break;
+               case CTSVC_DATA_IMAGE:
+                       ctsvc_get_data_info_image(stmt, (contacts_list_h)my_profile->images);
+                       break;
+               case CTSVC_DATA_COMPANY:
+                       ctsvc_get_data_info_company(stmt, (contacts_list_h)my_profile->company);
+                       break;
+               case CTSVC_DATA_NOTE:
+                       ctsvc_get_data_info_note(stmt, (contacts_list_h)my_profile->note);
+                       break;
+               case CTSVC_DATA_EXTENSION:
+                       ctsvc_get_data_info_extension(stmt, (contacts_list_h)my_profile->extensions);
+                       break;
+               default:
+                       CTS_ERR("Intenal : Not supported data type (%d)", datatype);
+                       break;
+               }
+
+       }while(1 /*CTS_TRUE*/ == ctsvc_stmt_step(stmt));
+
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+
+}
+
+static int __ctsvc_db_my_profile_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       contacts_record_h record;
+       ctsvc_my_profile_s *my_profile;
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       contacts_record_create(_contacts_my_profile._uri, &record);
+       my_profile = (ctsvc_my_profile_s *)record;
+       ret = __ctsvc_db_get_my_profile_base_info(id, my_profile);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("cts_get_main_contacts_info(ALL) Failed(%d)", ret);
+               contacts_record_destroy(record, true);
+               return ret;
+       }
+
+       ret = __ctsvc_db_my_profile_get_data(id, my_profile);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_db_my_profile_get_data Failed(%d)", ret);
+               contacts_record_destroy(record, true);
+               return ret;
+       }
+
+       *out_record = record;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_my_profile_delete_record( int id )
+{
+       CTS_FN_CALL;
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+               "SELECT addressbook_id FROM "CTSVC_DB_VIEW_MY_PROFILE" WHERE my_profile_id = %d", id);
+       ret  = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_get_first_int_result Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this contact");
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       snprintf(query, sizeof(query), "UPDATE "CTS_TABLE_MY_PROFILES" "
+                                       "SET deleted = 1, changed_ver = %d WHERE my_profile_id = %d", ctsvc_get_next_ver(), id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_set_my_profile_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_my_profile_update_data(ctsvc_my_profile_s *my_profile)
+{
+       int ret;
+
+       if (my_profile->name) {
+               ret = ctsvc_contact_update_data_name((contacts_list_h)my_profile->name, my_profile->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_name() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (my_profile->company) {
+               ret = ctsvc_contact_update_data_company((contacts_list_h)my_profile->company, my_profile->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_company() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (my_profile->note) {
+               ret = ctsvc_contact_update_data_note((contacts_list_h)my_profile->note, my_profile->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_note() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (my_profile->events) {
+               ret = ctsvc_contact_update_data_event((contacts_list_h)my_profile->events, my_profile->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_events() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (my_profile->messengers) {
+               ret = ctsvc_contact_update_data_messenger((contacts_list_h)my_profile->messengers, my_profile->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_messengers() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (my_profile->postal_addrs) {
+               ret = ctsvc_contact_update_data_address((contacts_list_h)my_profile->postal_addrs, my_profile->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_address() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (my_profile->urls) {
+               ret = ctsvc_contact_update_data_url((contacts_list_h)my_profile->urls, my_profile->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_url() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (my_profile->nicknames) {
+               ret = ctsvc_contact_update_data_nickname((contacts_list_h)my_profile->nicknames, my_profile->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_nickname() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (my_profile->numbers) {
+               bool had_phonenumber;
+               ret = ctsvc_contact_update_data_number((contacts_list_h)my_profile->numbers, my_profile->id, true, &had_phonenumber);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_number() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (my_profile->emails) {
+               bool had_email;
+               ret = ctsvc_contact_update_data_email((contacts_list_h)my_profile->emails, my_profile->id, true, &had_email);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_email() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (my_profile->profiles) {
+               ret = ctsvc_contact_update_data_profile((contacts_list_h)my_profile->profiles, my_profile->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_profile() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (my_profile->relationships) {
+               ret = ctsvc_contact_update_data_relationship((contacts_list_h)my_profile->relationships, my_profile->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_relationship() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (my_profile->images) {
+               ret = ctsvc_contact_update_data_image((contacts_list_h)my_profile->images, my_profile->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_image() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (my_profile->extensions) {
+               ret = ctsvc_contact_update_data_extension((contacts_list_h)my_profile->extensions, my_profile->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_update_data_extension() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static void __ctsvc_my_profile_check_default_data(ctsvc_my_profile_s *my_profile)
+{
+       ctsvc_contact_check_default_number((contacts_list_h)my_profile->numbers);
+       ctsvc_contact_check_default_email((contacts_list_h)my_profile->emails);
+       ctsvc_contact_check_default_image((contacts_list_h)my_profile->images);
+       ctsvc_contact_check_default_address((contacts_list_h)my_profile->postal_addrs);
+}
+
+static void __ctsvc_make_my_profile_display_name(ctsvc_my_profile_s *my_profile)
+{
+       ctsvc_name_s *name = NULL;
+
+       free(my_profile->display_name);
+       my_profile->display_name = NULL;
+
+       free(my_profile->reverse_display_name);
+       my_profile->reverse_display_name = NULL;
+
+       if (my_profile->name->count > 0 && my_profile->name->records != NULL && my_profile->name->records->data != NULL) {
+               name = (ctsvc_name_s *)my_profile->name->records->data;
+       }
+
+       if (name && (name->first || name->last  || name->prefix || name->addition || name->suffix)) {
+               char *display = NULL;
+               int len, display_len;
+               int reverse_lang_type = -1;
+               int temp_display_len;
+               char *temp_display = NULL;
+
+               ///////////////////////////////////////////////
+               // Make reverse display name (Last name first)
+               // Default         : Prefix Last, First Middle(addition), Suffix
+               // Korean, Chinese : Prefix LastFirstMiddleSuffix
+               // Japanese        : Prefix Last Middle First Suffix
+               // reverse sort name does not include prefix
+               //    But, if there is only prefix, reverse sort_name is prefix
+               //////////////////////////////////////////////
+               temp_display_len = SAFE_STRLEN(name->first)
+                                               + SAFE_STRLEN(name->addition)
+                                               + SAFE_STRLEN(name->last)
+                                               + SAFE_STRLEN(name->suffix);
+               if (0 < temp_display_len) {
+                       temp_display_len += 7;
+                       temp_display = calloc(1, temp_display_len);
+                       RETM_IF(NULL == temp_display, "calloc() return NULL");
+                       len=0;
+
+                       if (name->last) {
+                               len += snprintf(temp_display + len, temp_display_len - len, "%s", name->last);
+
+                               if (reverse_lang_type < 0) {
+                                       reverse_lang_type = ctsvc_check_language_type(temp_display);
+                               }
+
+                               if (reverse_lang_type != CTSVC_LANG_KOREAN &&
+                                       reverse_lang_type != CTSVC_LANG_CHINESE &&
+                                       reverse_lang_type != CTSVC_LANG_JAPANESE) {
+                                       if(name->first || name->addition)
+                                               len += snprintf(temp_display + len, temp_display_len - len, ",");
+                               }
+                       }
+
+                       if (reverse_lang_type < 0) {
+                               if (*temp_display) {
+                                       reverse_lang_type = ctsvc_check_language_type(temp_display);
+                               }
+                               else if (name->first) {
+                                       reverse_lang_type = ctsvc_check_language_type(name->first);
+                               }
+                               else if (name->addition) {
+                                       reverse_lang_type = ctsvc_check_language_type(name->addition);
+                               }
+                       }
+
+                       if(reverse_lang_type == CTSVC_LANG_JAPANESE) {
+                               // make temp_display name Prefix - Last - Middle - First - Suffix
+                               if(name->addition) {
+                                       if (*temp_display)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", name->addition);
+                               }
+
+                               if(name->first) {
+                                       if (*temp_display)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", name->first);
+                               }
+                       }
+                       else {
+                               if (name->first) {
+                                       if (*temp_display) {
+                                               if (reverse_lang_type < 0) {
+                                                       reverse_lang_type = ctsvc_check_language_type(temp_display);
+                                               }
+
+                                               if (reverse_lang_type != CTSVC_LANG_KOREAN &&
+                                                               reverse_lang_type != CTSVC_LANG_CHINESE)
+                                                       len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       }
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", name->first);
+                               }
+
+                               if (name->addition) {
+                                       if (*temp_display) {
+                                               if (reverse_lang_type < 0) {
+                                                       reverse_lang_type = ctsvc_check_language_type(temp_display);
+                                               }
+
+                                               if (reverse_lang_type != CTSVC_LANG_KOREAN &&
+                                                               reverse_lang_type != CTSVC_LANG_CHINESE)
+                                                       len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       }
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", name->addition);
+                               }
+                       }
+
+                       if (name->suffix) {
+                               if (*temp_display) {
+                                       if (reverse_lang_type < 0) {
+                                               reverse_lang_type = ctsvc_check_language_type(temp_display);
+                                       }
+
+                                       if (reverse_lang_type == CTSVC_LANG_JAPANESE)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       else if (reverse_lang_type != CTSVC_LANG_KOREAN &&
+                                                                       reverse_lang_type != CTSVC_LANG_CHINESE)
+                                               len += snprintf(temp_display + len, temp_display_len - len, ", ");
+                               }
+                               len += snprintf(temp_display + len, temp_display_len - len, "%s", name->suffix);
+                       }
+               }
+
+               if(name->prefix && temp_display) {
+                       display_len = SAFE_STRLEN(name->prefix) + temp_display_len + 2;
+                       display = calloc(1, display_len);
+                       if (NULL == display) {
+                               CTS_ERR("calloc() return NULL");
+                               free(temp_display);
+                               return;
+                       }
+
+                       snprintf(display, display_len , "%s %s", name->prefix, temp_display);
+                       my_profile->reverse_display_name = display;
+                       free(temp_display);
+               }
+               else if (temp_display) {
+                       my_profile->reverse_display_name = temp_display;
+               }
+               else if (name->prefix) {
+                       my_profile->reverse_display_name = strdup(name->prefix);
+                       RETM_IF(NULL == my_profile->reverse_display_name, "strdup() return NULL");
+               }
+
+               ///////////////////////////////////////////////
+               // Make display name (First name first)
+               // Default         : Prefix First Middle Last, Suffix
+               // Korean, Chinese : Prefix LastFirstMiddleSuffix (Same as reverse display name)
+               // Japanese        : Prefix First Middle Last Suffix
+               // sort name does not include prefix
+               //    But, if there is only prefix, sort_name is prefix
+               //////////////////////////////////////////////
+               if (reverse_lang_type == CTSVC_LANG_KOREAN ||
+                       reverse_lang_type == CTSVC_LANG_CHINESE)
+                       my_profile->display_name = SAFE_STRDUP(my_profile->reverse_display_name);
+               else {
+                       int lang_type = -1;
+                       temp_display = NULL;
+                       temp_display_len = SAFE_STRLEN(name->first)
+                                                               + SAFE_STRLEN(name->addition)
+                                                               + SAFE_STRLEN(name->last)
+                                                               + SAFE_STRLEN(name->suffix);
+                       if (0 < temp_display_len) {
+                               temp_display_len += 6;
+                               // make reverse_temp_display_name
+                               temp_display = calloc(1, temp_display_len);
+                               RETM_IF(NULL == temp_display, "calloc() return NULL");
+                               len = 0;
+
+                               if (name->first) {
+                                       if (*temp_display)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", name->first);
+                               }
+
+                               if (name->addition) {
+                                       if (*temp_display)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", name->addition);
+                               }
+
+                               if (name->last) {
+                                       if (*temp_display)
+                                               len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", name->last);
+                               }
+
+                               if(name->suffix) {
+                                       if (*temp_display) {
+                                               lang_type = ctsvc_check_language_type(temp_display);
+                                               if (lang_type == CTSVC_LANG_JAPANESE)
+                                                       len += snprintf(temp_display + len, temp_display_len - len, " ");
+                                               else
+                                                       len += snprintf(temp_display + len, temp_display_len - len, ", ");
+                                       }
+                                       len += snprintf(temp_display + len, temp_display_len - len, "%s", name->suffix);
+                               }
+
+                       }
+                       if (name->prefix && temp_display) {
+                               display_len = SAFE_STRLEN(name->prefix) + temp_display_len + 2;
+                               display = calloc(1, display_len);
+                               if (NULL == display) {
+                                       CTS_ERR("calloc() return NULL");
+                                       free(temp_display);
+                                       return;
+                               }
+                               snprintf(display, display_len , "%s %s", name->prefix, temp_display);
+                               my_profile->display_name = display;
+                               free(temp_display);
+                       }
+                       else if (temp_display) {
+                               my_profile->display_name = temp_display;
+                       }
+                       else if (name->prefix) {
+                               my_profile->display_name = strdup(name->prefix);
+                               RETM_IF(NULL == my_profile->display_name, "strdup() return NULL");
+                       }
+               }
+
+               ctsvc_record_set_property_flag((ctsvc_record_s *)my_profile, _contacts_my_profile.display_name, CTSVC_PROPERTY_FLAG_DIRTY);
+       }
+       else {
+               GList *cur;
+               if (my_profile->company && my_profile->company->records) {
+                       for (cur=my_profile->company->records;cur;cur=cur->next) {
+                               ctsvc_company_s *company = (ctsvc_company_s *)cur->data;
+                               if (company && company->name) {
+                                       ctsvc_record_set_property_flag((ctsvc_record_s *)my_profile, _contacts_my_profile.display_name, CTSVC_PROPERTY_FLAG_DIRTY);
+                                       FREEandSTRDUP(my_profile->display_name, company->name);
+                                       break;
+                               }
+                       }
+               }
+
+               if (!ctsvc_record_check_property_flag((ctsvc_record_s *)my_profile, _contacts_my_profile.display_name, CTSVC_PROPERTY_FLAG_DIRTY) &&
+                               my_profile->nicknames && my_profile->nicknames->records) {
+                       for (cur=my_profile->nicknames->records;cur;cur=cur->next) {
+                               ctsvc_nickname_s *nickname = (ctsvc_nickname_s *)cur->data;
+                               if (nickname && nickname->nickname) {
+                                       ctsvc_record_set_property_flag((ctsvc_record_s *)my_profile, _contacts_my_profile.display_name, CTSVC_PROPERTY_FLAG_DIRTY);
+                                       FREEandSTRDUP(my_profile->display_name, nickname->nickname);
+                                       break;
+                               }
+                       }
+               }
+
+               if (!ctsvc_record_check_property_flag((ctsvc_record_s *)my_profile, _contacts_my_profile.display_name, CTSVC_PROPERTY_FLAG_DIRTY) &&
+                               my_profile->numbers && my_profile->numbers->records) {
+                       for (cur=my_profile->numbers->records;cur;cur=cur->next) {
+                               ctsvc_number_s *number = (ctsvc_number_s *)cur->data;
+                               if (number && number->number) {
+                                       ctsvc_record_set_property_flag((ctsvc_record_s *)my_profile, _contacts_my_profile.display_name, CTSVC_PROPERTY_FLAG_DIRTY);
+                                       FREEandSTRDUP(my_profile->display_name, number->number);
+                                       break;
+                               }
+                       }
+               }
+
+               if (!ctsvc_record_check_property_flag((ctsvc_record_s *)my_profile, _contacts_my_profile.display_name, CTSVC_PROPERTY_FLAG_DIRTY) &&
+                               my_profile->emails && my_profile->emails->records) {
+                       for (cur=my_profile->emails->records;cur;cur=cur->next) {
+                               ctsvc_email_s *email = (ctsvc_email_s *)cur->data;
+                               if (email && email->email_addr) {
+                                       ctsvc_record_set_property_flag((ctsvc_record_s *)my_profile, _contacts_my_profile.display_name, CTSVC_PROPERTY_FLAG_DIRTY);
+                                       FREEandSTRDUP(my_profile->display_name, email->email_addr);
+                                       break;
+                               }
+                       }
+               }
+
+               if (ctsvc_record_check_property_flag((ctsvc_record_s *)my_profile, _contacts_my_profile.display_name, CTSVC_PROPERTY_FLAG_DIRTY)) {
+                       FREEandSTRDUP(my_profile->reverse_display_name, my_profile->display_name);
+               }
+               else {
+                       // Update as NULL
+                       ctsvc_record_set_property_flag((ctsvc_record_s *)my_profile, _contacts_my_profile.display_name, CTSVC_PROPERTY_FLAG_DIRTY);
+               }
+       }
+       return;
+}
+
+
+static int __ctsvc_db_my_profile_update_record( contacts_record_h record )
+{
+       int id;
+       int ret;
+       char *set = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_my_profile_s *my_profile = (ctsvc_my_profile_s*)record;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+               "SELECT my_profile_id FROM "CTSVC_DB_VIEW_MY_PROFILE" WHERE my_profile_id = %d", my_profile->id);
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("The index(%d) is Invalid. %d Record(s) is(are) found", my_profile->id, ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(my_profile->addressbook_id)) {
+               CTS_ERR("ctsvc_have_ab_write_permission fail : does not have permission(addressbook_id : %d)",
+                                       my_profile->addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       __ctsvc_make_my_profile_display_name(my_profile);
+       __ctsvc_my_profile_check_default_data(my_profile);
+
+       //update data
+       ret = __ctsvc_my_profile_update_data(my_profile);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_my_profile_update_data() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       //////////////////////////////////////////////////////////////////////
+       // this code will be removed.
+       if (my_profile->images) {
+               int ret = CONTACTS_ERROR_NONE;
+               contacts_record_h record_image = NULL;
+               int count = 0;
+               ctsvc_image_s *image;
+
+               contacts_list_get_count((contacts_list_h)my_profile->images, &count);
+               if (count) {
+                       contacts_list_first((contacts_list_h)my_profile->images);
+                       ret = contacts_list_get_current_record_p((contacts_list_h)my_profile->images, &record_image);
+
+                       if (CONTACTS_ERROR_NONE != ret) {
+                               CTS_ERR("contacts_list_get_current_record_p() Failed(%d)", ret);
+                               ctsvc_end_trans(false);
+                               return CONTACTS_ERROR_DB;
+                       }
+
+                       image = (ctsvc_image_s*)record_image;
+                       if ((NULL == my_profile->image_thumbnail_path && NULL != image->path) ||
+                                       (NULL != my_profile->image_thumbnail_path && NULL == image->path) ||
+                                       (my_profile->image_thumbnail_path && image->path && 0 != strcmp(my_profile->image_thumbnail_path, image->path))) {
+                               ctsvc_record_set_property_flag((ctsvc_record_s *)my_profile, _contacts_my_profile.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY);
+
+                               if (ctsvc_contact_check_image_location(image->path))
+                                       my_profile->image_thumbnail_path = SAFE_STRDUP(image->path + strlen(CTSVC_CONTACT_IMG_FULL_LOCATION) + 1);
+                               else
+                                       my_profile->image_thumbnail_path = SAFE_STRDUP(image->path);
+                       }
+               }
+               else if (my_profile->image_thumbnail_path) {
+                       free(my_profile->image_thumbnail_path);
+                       my_profile->image_thumbnail_path = NULL;
+                       ctsvc_record_set_property_flag((ctsvc_record_s *)my_profile, _contacts_my_profile.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY);
+               }
+       }
+       // this code will be removed.
+       //////////////////////////////////////////////////////////////////////
+
+       do {
+               int len = 0;
+               int version;
+               char query[CTS_SQL_MAX_LEN] = {0};
+               char query_set[CTS_SQL_MIN_LEN] = {0, };
+               cts_stmt stmt = NULL;
+
+               version = ctsvc_get_next_ver();
+
+               ret = ctsvc_db_create_set_query(record, &set, &bind_text);
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_db_create_set_query() Failed(%d)", ret);
+
+               if (set && *set)
+                       len = snprintf(query_set, sizeof(query_set), "%s, ", set);
+               len += snprintf(query_set+len, sizeof(query_set)-len, " changed_ver=%d, changed_time=%d", version, (int)time(NULL));
+
+               if (ctsvc_record_check_property_flag((ctsvc_record_s *)my_profile, _contacts_my_profile.display_name, CTSVC_PROPERTY_FLAG_DIRTY)) {
+                       len += snprintf(query_set+len, sizeof(query_set)-len,
+                                       ", display_name=?, reverse_display_name=?");
+                       bind_text = g_slist_append(bind_text, strdup(SAFE_STR(my_profile->display_name)));
+                       bind_text = g_slist_append(bind_text, strdup(SAFE_STR(my_profile->reverse_display_name)));
+               }
+
+               snprintf(query, sizeof(query), "UPDATE %s SET %s WHERE my_profile_id = %d", CTS_TABLE_MY_PROFILES, query_set, my_profile->id);
+
+               ret = ctsvc_query_prepare(query, &stmt);
+               if (NULL == stmt) {
+                       CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+                       break;
+               }
+
+               if (bind_text) {
+                       int i = 0;
+                       for (cursor=bind_text,i=1;cursor;cursor=cursor->next,i++) {
+                               const char *text = cursor->data;
+                               if (*text)
+                                       ctsvc_stmt_bind_text(stmt, i, text);
+                       }
+               }
+
+               ret = ctsvc_stmt_step(stmt);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       break;
+               }
+               ctsvc_stmt_finalize(stmt);
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       ctsvc_set_my_profile_noti();
+
+       ret = ctsvc_end_trans(true);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "DB error : ctsvc_end_trans() Failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_my_profile_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int len;
+       int my_profile_id;
+       cts_stmt stmt;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_list_h list;
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT my_profile_id FROM "CTSVC_DB_VIEW_MY_PROFILE);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               my_profile_id = ctsvc_stmt_get_int(stmt, 0);
+               ret = contacts_db_get_record(_contacts_my_profile._uri, my_profile_id, &record);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : contacts_db_get_record() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_my_profile_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_my_profile_s *my_profile;
+       char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+       bool had_my_profile_id = false;
+       int my_profile_id = 0;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       if (s_query->projection) {
+               for (i=0;i<s_query->projection_count;i++) {
+                       if (s_query->projection[i] == CTSVC_PROPERTY_MY_PROFILE_ID) {
+                               had_my_profile_id = true;
+                               break;
+                       }
+               }
+       }
+       else
+               had_my_profile_id = true;
+
+       if (!had_my_profile_id) {
+               unsigned int *temp = realloc(s_query->projection, s_query->projection_count+1);
+               RETVM_IF(NULL == temp, CONTACTS_ERROR_OUT_OF_MEMORY, "realloc() return NULL");
+               s_query->projection = temp;
+               s_query->projection[s_query->projection_count] = CTSVC_PROPERTY_MY_PROFILE_ID;
+               s_query->projection_count++;
+       }
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_my_profile._uri, &record);
+               my_profile = (ctsvc_my_profile_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if (CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_MY_PROFILE_ID:
+                               my_profile_id = ctsvc_stmt_get_int(stmt, i);
+                               if (had_my_profile_id)
+                                       my_profile->id = my_profile_id;
+                               break;
+                       case CTSVC_PROPERTY_MY_PROFILE_DISPLAY_NAME:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               my_profile->display_name = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_MY_PROFILE_ADDRESSBOOK_ID:
+                               my_profile->addressbook_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_MY_PROFILE_IMAGE_THUMBNAIL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               if (temp) {
+                                       snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
+                                       my_profile->image_thumbnail_path = strdup(full_path);
+                               }
+                               break;
+                       case CTSVC_PROPERTY_MY_PROFILE_CHANGED_TIME:
+                               my_profile->changed_time = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_MY_PROFILE_UID:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               my_profile->uid = SAFE_STRDUP(temp);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ret = __ctsvc_db_my_profile_get_data(my_profile_id, my_profile);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("__ctsvc_db_my_profile_get_data Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_my_profile_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_my_profile_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_my_profile_delete_records(int ids[], int count) { return CONTACTS_ERROR_NONE; }
+
+static int __ctsvc_my_profile_insert_data(ctsvc_my_profile_s *contact)
+{
+       int ret;
+
+       //Insert the name
+       if (contact->name) {
+               ret = ctsvc_contact_insert_data_name((contacts_list_h)contact->name, contact->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_insert_data_name() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the company
+       if (contact->company) {
+               ret = ctsvc_contact_insert_data_company((contacts_list_h)contact->company, contact->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_insert_my_profile_data_company() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the events
+       if (contact->events) {
+               ret = ctsvc_contact_insert_data_event((contacts_list_h)contact->events, contact->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_insert_my_profile_data_event() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the messengers
+       if (contact->messengers) {
+               ret = ctsvc_contact_insert_data_messenger((contacts_list_h)contact->messengers, contact->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_insert_my_profile_data_messenger() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the postals
+       if (contact->postal_addrs) {
+               ret = ctsvc_contact_insert_data_address((contacts_list_h)contact->postal_addrs, contact->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_insert_my_profile_data_postal() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the Web addrs
+       if (contact->urls) {
+               ret = ctsvc_contact_insert_data_url((contacts_list_h)contact->urls, contact->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_insert_my_profile_data_web() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the Nick names
+       if (contact->nicknames) {
+               ret = ctsvc_contact_insert_data_nickname((contacts_list_h)contact->nicknames, contact->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_insert_my_profile_data_nickname() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the numbers
+       if (contact->numbers) {
+               ret = ctsvc_contact_insert_data_number((contacts_list_h)contact->numbers, contact->id, true);
+               if (ret < CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_contact_insert_data_number() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the emails
+       if (contact->emails) {
+               ret = ctsvc_contact_insert_data_email((contacts_list_h)contact->emails, contact->id, true);
+               if (ret < CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_insert_my_profile_data_email() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the profile values
+       if (contact->profiles) {
+               ret = ctsvc_contact_insert_data_profile((contacts_list_h)contact->profiles, contact->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_insert_my_profile_data_profile() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the relationship values
+       if (contact->relationships) {
+               ret = ctsvc_contact_insert_data_relationship((contacts_list_h)contact->relationships, contact->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_insert_data_relationship() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the image values
+       if (contact->images) {
+               ret = ctsvc_contact_insert_data_image((contacts_list_h)contact->images, contact->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_insert_data_image() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the note values
+       if (contact->note) {
+               ret = ctsvc_contact_insert_data_note((contacts_list_h)contact->note, contact->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_insert_data_note() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       //Insert the extensions values
+       if (contact->extensions) {
+               ret = ctsvc_contact_insert_data_extension((contacts_list_h)contact->extensions, contact->id, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_contact_insert_data_extension() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_my_profile_insert_record( contacts_record_h record, int *id)
+{
+       CTS_FN_CALL;
+       int ret;
+       int version;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       ctsvc_my_profile_s *my_profile = (ctsvc_my_profile_s*)record;
+       cts_stmt stmt;
+
+       // These check should be done in client side
+       RETVM_IF(NULL == my_profile, CONTACTS_ERROR_INVALID_PARAMETER,
+                                       "Invalid parameter : my_profile is NULL");
+       RETVM_IF(my_profile->addressbook_id < 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : addressbook_id(%d) is mandatory field to insert my_profile record ", my_profile->addressbook_id);
+       RETVM_IF(0 < my_profile->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", my_profile->id);
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       if (false == ctsvc_have_ab_write_permission(my_profile->addressbook_id)) {
+               CTS_ERR("ctsvc_have_ab_write_permission fail : does not have permission(addressbook_id : %d)",
+                                       my_profile->addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_MY_PROFILES" WHERE addressbook_id = %d AND deleted = 1", my_profile->addressbook_id);
+       ret = ctsvc_query_exec(query);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "Delete deleted my_profile of addressbook(%d) failed", my_profile->addressbook_id);
+
+       ret = ctsvc_db_get_next_id(CTS_TABLE_MY_PROFILES);
+       if (ret < CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_db_get_next_id() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       my_profile->id = ret;
+       if (id)
+               *id = ret;
+
+       __ctsvc_make_my_profile_display_name(my_profile);
+       __ctsvc_my_profile_check_default_data(my_profile);
+
+       //Insert Data
+       ret = __ctsvc_my_profile_insert_data(my_profile);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("cts_insert_my_profile_data() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       //////////////////////////////////////////////////////////////////////
+       // this code will be removed.
+       free(my_profile->image_thumbnail_path);
+       my_profile->image_thumbnail_path = NULL;
+
+       if (my_profile->images) {
+               ctsvc_image_s *image;
+               int count = 0;
+
+               contacts_list_get_count((contacts_list_h)my_profile->images, &count);
+
+               while (count) {
+                       contacts_list_first((contacts_list_h)my_profile->images);
+                       ret = contacts_list_get_current_record_p((contacts_list_h)my_profile->images, (contacts_record_h*)&image);
+                       if (CONTACTS_ERROR_NONE != ret) {
+                               CTS_ERR("contacts_list_get_current_record_p() Failed(%d)", ret);
+                               ctsvc_end_trans(false);
+                               return CONTACTS_ERROR_DB;
+                       }
+
+                       if (image->path && image->is_default) {
+                               my_profile->image_thumbnail_path = strdup(image->path);
+                               break;
+                       }
+                       count--;
+               }
+       }
+       // this code will be removed.
+       //////////////////////////////////////////////////////////////////////
+
+       version = ctsvc_get_next_ver();
+
+       snprintf(query, sizeof(query),
+               "INSERT INTO "CTS_TABLE_MY_PROFILES"(my_profile_id, addressbook_id, "
+                       "created_ver, changed_ver, changed_time, "
+                       "display_name, reverse_display_name, uid, image_thumbnail_path) "
+                       "VALUES(%d, %d, %d, %d, %d, ?, ?, ?, ?)",
+                       my_profile->id, my_profile->addressbook_id, version, version, (int)time(NULL));
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (my_profile->display_name)
+               ctsvc_stmt_bind_text(stmt, 1, my_profile->display_name);
+       if (my_profile->reverse_display_name)
+               ctsvc_stmt_bind_text(stmt, 2, my_profile->reverse_display_name);
+       if (my_profile->uid)
+               ctsvc_stmt_bind_text(stmt, 3, my_profile->uid);
+       if (my_profile->image_thumbnail_path)
+               ctsvc_stmt_bind_text(stmt, 4, my_profile->image_thumbnail_path);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       ctsvc_set_my_profile_noti();
+
+       ret = ctsvc_end_trans(true);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_svc_end_trans() Failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/native/ctsvc_db_plugin_name.c b/native/ctsvc_db_plugin_name.c
new file mode 100644 (file)
index 0000000..131fa5e
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_db_plugin_name_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_list.h"
+#include "ctsvc_notification.h"
+
+static int __ctsvc_db_name_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_name_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_name_update_record( contacts_record_h record );
+static int __ctsvc_db_name_delete_record( int id );
+static int __ctsvc_db_name_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_name_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_name_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_name_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_name_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_name = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_name_insert_record,
+       .get_record = __ctsvc_db_name_get_record,
+       .update_record = __ctsvc_db_name_update_record,
+       .delete_record = __ctsvc_db_name_delete_record,
+       .get_all_records = __ctsvc_db_name_get_all_records,
+       .get_records_with_query = __ctsvc_db_name_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_name_insert_records,
+       .update_records = NULL,//__ctsvc_db_name_update_records,
+       .delete_records = NULL,//__ctsvc_db_name_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_name_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int name_id = 0;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_name_s *name = (ctsvc_name_s *)record;
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", name->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       CTS_ERR("No data : contact_id (%d) is not exist", name->contact_id);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               else {
+                       CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this name record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE contact_id = %d AND datatype=%d", name->contact_id, CTSVC_DATA_NAME);
+       ret = ctsvc_query_get_first_int_result(query, &name_id);
+       if (name_id) {
+               CTS_ERR("name_id (%d) is exist", name_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = ctsvc_db_name_insert(record, name->contact_id, false, id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_contact_update_display_name(name->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME);
+
+       ret = ctsvc_db_contact_update_changed_time(name->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_name_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, "
+                               "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE id = %d AND datatype = %d ",
+                               id, CTSVC_DATA_NAME);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ctsvc_db_name_get_value_from_stmt(stmt, out_record, 0);
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_name_update_record( contacts_record_h record )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_name_s *name = (ctsvc_name_s *)record;
+
+       RETVM_IF(NULL == name->first && NULL == name->last && NULL == name->addition &&
+                       NULL == name->prefix && NULL == name->suffix && NULL == name->phonetic_first &&
+                       NULL == name->phonetic_middle && NULL == name->phonetic_last, CONTACTS_ERROR_INVALID_PARAMETER, "name is empty");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", name->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : contact_id (%d) is not exist", name->contact_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this name record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_name_update(record, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_contact_update_display_name(name->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME);
+
+       ret = ctsvc_db_contact_update_changed_time(name->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+
+static int __ctsvc_db_name_delete_record( int id )
+{
+       int ret;
+       int contact_id;
+       int addressbook_id;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
+                       "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("The id(%d) is Invalid(%d)", id, ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       contact_id = ctsvc_stmt_get_int(stmt, 0);
+       addressbook_id = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this name record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_name_delete(id, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_contact_update_display_name(contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME);
+
+       ret = ctsvc_db_contact_update_changed_time(contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_name_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int len;
+       int ret;
+       contacts_list_h list;
+       ctsvc_name_s *name;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, "
+                               "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE datatype = %d AND is_my_profile=0 ",
+                               CTSVC_DATA_NAME);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error :         ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_db_name_get_value_from_stmt(stmt, (contacts_record_h*)&name, 0);
+               ctsvc_list_prepend(list, (contacts_record_h)name);
+       }
+
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_name_get_records_with_query( contacts_query_h query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_name_s *name;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_name._uri, &record);
+               name = (ctsvc_name_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if( CONTACTS_ERROR_NONE !=  ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_NAME_ID:
+                               name->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_NAME_CONTACT_ID:
+                               name->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_NAME_FIRST:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               name->first = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_NAME_LAST:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               name->last = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_NAME_ADDITION:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               name->addition = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_NAME_SUFFIX:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               name->suffix = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_NAME_PREFIX:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               name->prefix = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_NAME_PHONETIC_FIRST:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               name->phonetic_first = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_NAME_PHONETIC_MIDDLE:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               name->phonetic_middle = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_NAME_PHONETIC_LAST:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               name->phonetic_last = SAFE_STRDUP(temp);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_name_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_name_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_name_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_name_helper.c b/native/ctsvc_db_plugin_name_helper.c
new file mode 100644 (file)
index 0000000..abaa864
--- /dev/null
@@ -0,0 +1,390 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_localize_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_plugin_name_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_setting.h"
+#include "ctsvc_notification.h"
+
+enum{
+       CTSVC_NN_FIRST,
+       CTSVC_NN_LAST,
+       CTSVC_NN_MAX,
+};
+
+static inline void __ctsvc_make_name_lookup(int op_code, const char *name_first,
+               const char *name_last, char **name_lookup)
+{
+       if (name_first && !name_last)
+               *name_lookup = SAFE_STRDUP(name_first);
+       else if (!name_first && name_last)
+               *name_lookup = SAFE_STRDUP(name_last);
+       else {
+               if (CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST == op_code) {
+                       *name_lookup = calloc(1, SAFE_STRLEN(name_first) + SAFE_STRLEN(name_last) + 3);
+                       RETM_IF(NULL == *name_lookup, "calloc() return NULL");
+                       snprintf(*name_lookup, SAFE_STRLEN(name_first) + SAFE_STRLEN(name_last) + 3, "%s %c%s",
+                                       SAFE_STR(name_first), 0x7E, SAFE_STR(name_last));
+               }
+               else {
+                       *name_lookup = calloc(1, SAFE_STRLEN(name_first) + SAFE_STRLEN(name_last) + 5);
+                       RETM_IF(NULL == *name_lookup, "calloc() return NULL");
+                       snprintf(*name_lookup, SAFE_STRLEN(name_first) + SAFE_STRLEN(name_last) + 5, "%s,%c %c%s",
+                                       SAFE_STR(name_last), 0x7E, 0x7E, SAFE_STR(name_first));
+               }
+       }
+}
+
+static inline int __ctsvc_name_bind_stmt(cts_stmt stmt, ctsvc_name_s *name, int start_cnt)
+{
+       ctsvc_stmt_bind_int(stmt, start_cnt, name->is_default);
+       ctsvc_stmt_bind_int(stmt, start_cnt+1, name->language_type);
+       if (name->first)
+               sqlite3_bind_text(stmt, start_cnt+2, name->first,
+                               strlen(name->first), SQLITE_STATIC);
+       if (name->last)
+               sqlite3_bind_text(stmt, start_cnt+3, name->last,
+                               strlen(name->last), SQLITE_STATIC);
+       if (name->addition)
+               sqlite3_bind_text(stmt, start_cnt+4, name->addition,
+                               strlen(name->addition), SQLITE_STATIC);
+       if (name->prefix)
+               sqlite3_bind_text(stmt, start_cnt+5, name->prefix,
+                               strlen(name->prefix), SQLITE_STATIC);
+       if (name->suffix)
+               sqlite3_bind_text(stmt, start_cnt+6, name->suffix,
+                               strlen(name->suffix), SQLITE_STATIC);
+       if (name->phonetic_first)
+               sqlite3_bind_text(stmt, start_cnt+7, name->phonetic_first,
+                               strlen(name->phonetic_first), SQLITE_STATIC);
+       if (name->phonetic_middle)
+               sqlite3_bind_text(stmt, start_cnt+8, name->phonetic_middle,
+                               strlen(name->phonetic_middle), SQLITE_STATIC);
+       if (name->phonetic_last)
+               sqlite3_bind_text(stmt, start_cnt+9, name->phonetic_last,
+                               strlen(name->phonetic_last), SQLITE_STATIC);
+       if (name->lookup)
+               sqlite3_bind_text(stmt, start_cnt+10, name->lookup,
+                               strlen(name->lookup), SQLITE_STATIC);
+       if (name->reverse_lookup)
+               sqlite3_bind_text(stmt, start_cnt+11, name->reverse_lookup,
+                               strlen(name->reverse_lookup), SQLITE_STATIC);
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_normalize_name(ctsvc_name_s *src, char *dest[])
+{
+       int ret = CONTACTS_ERROR_NO_DATA;
+       int language_type = 0;
+
+       if (src->first) {
+               ret = ctsvc_normalize_str(src->first, &dest[CTSVC_NN_FIRST]);
+               RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_normalize_str() Failed(%d)", ret);
+               language_type = ret;
+       }
+
+       if (src->last) {
+               ret = ctsvc_normalize_str(src->last, &dest[CTSVC_NN_LAST]);
+               RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_normalize_str() Failed(%d)", ret);
+               if (language_type < ret)
+                       language_type = ret;
+       }
+       return language_type;
+}
+
+int ctsvc_db_name_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id)
+{
+       int ret, len = 0;
+       cts_stmt stmt = NULL;
+       ctsvc_name_s *name = (ctsvc_name_s*)record;
+       char query[CTS_SQL_MAX_LEN]={0};
+       char *normal_name[CTSVC_NN_MAX]={NULL}; //insert name search info
+       char *temp_normal_first = NULL;
+       char *temp_normal_last = NULL;
+       int len_normal_first = 0;
+       int len_normal_last = 0;
+
+       RETV_IF(NULL == name, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       RETVM_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : contact_id(%d) is mandatory field to insert name record ", name->contact_id);
+       RETVM_IF(0 < name->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", name->id);
+
+       if (name->first || name->last || name->addition || name->prefix || name->suffix
+               || name->phonetic_first || name->phonetic_middle || name->phonetic_last) {
+               // If name record already exists, delete current name record
+               // If user update record with out-of-date record, name record can be two
+               snprintf(query, sizeof(query),
+                               "DELETE FROM "CTS_TABLE_DATA" "
+                                               "WHERE contact_id = %d AND datatype=%d "
+                                                                       "AND is_my_profile = %d",
+                                               contact_id, CTSVC_DATA_NAME, is_my_profile);
+               ret = ctsvc_query_exec(query);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_query_exec Faild(%d)", ret);
+                       return ret;
+               }
+
+               snprintf(query, sizeof(query),
+                       "INSERT INTO "CTS_TABLE_DATA"(contact_id, is_my_profile, datatype, is_default, data1, data2, data3, "
+                                               "data4, data5, data6, data7, data8, data9, data10, data11, data12) "
+                                               "VALUES(%d, %d, %d, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+                               contact_id, is_my_profile, CTSVC_DATA_NAME);
+
+               ret = ctsvc_query_prepare(query, &stmt);
+               RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+               ret = __ctsvc_normalize_name(name, normal_name);
+               WARN_IF(ret < CONTACTS_ERROR_NONE, "__ctsvc_normalize_name() Failed(%d)", ret);
+
+               switch (ret) {
+               case CTSVC_LANG_KOREAN:
+                       len_normal_first = SAFE_STRLEN(normal_name[CTSVC_NN_FIRST]);
+                       len_normal_last = SAFE_STRLEN(normal_name[CTSVC_NN_LAST]);
+                       temp_normal_first = calloc(1, len_normal_first + len_normal_last + 1);
+                       if (normal_name[CTSVC_NN_LAST]) {
+                               len = snprintf(temp_normal_first, len_normal_first + len_normal_last + 1,
+                                       "%s", normal_name[CTSVC_NN_LAST]);
+                       }
+                       if (normal_name[CTSVC_NN_FIRST]) {
+                               snprintf(temp_normal_first+len, len_normal_first + len_normal_last + 1 - len,
+                                       "%s", normal_name[CTSVC_NN_FIRST]);
+                       }
+                       temp_normal_last = NULL;
+                       break;
+               case CTSVC_LANG_ENGLISH:
+               default:
+                       if (normal_name[CTSVC_NN_FIRST] && normal_name[CTSVC_NN_FIRST][0])
+                               temp_normal_first = SAFE_STRDUP(normal_name[CTSVC_NN_FIRST]);
+
+                       if (normal_name[CTSVC_NN_LAST] && normal_name[CTSVC_NN_LAST][0])
+                               temp_normal_last = SAFE_STRDUP(normal_name[CTSVC_NN_LAST]);
+
+                       break;
+               }
+
+
+               if (ctsvc_get_primary_sort() == ret)
+                       name->language_type = CTSVC_LANG_DEFAULT;
+               else if (ctsvc_get_secondary_sort() == ret)
+                       name->language_type = CTSVC_LANG_SECONDARY;
+               else
+                       name->language_type = ret;
+
+
+               __ctsvc_make_name_lookup(CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST,
+                                                                       temp_normal_first, temp_normal_last, &name->lookup);
+
+               __ctsvc_make_name_lookup(CONTACTS_NAME_DISPLAY_ORDER_LASTFIRST,
+                                                                       temp_normal_first, temp_normal_last, &name->reverse_lookup);
+
+               free(temp_normal_first);
+               free(temp_normal_last);
+               free(normal_name[CTSVC_NN_FIRST]);
+               free(normal_name[CTSVC_NN_LAST]);
+
+               __ctsvc_name_bind_stmt(stmt, name, 1);
+
+               ret = ctsvc_stmt_step(stmt);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       return ret;
+               }
+
+               //name->id = ctsvc_db_get_last_insert_id();
+               if (id)
+                       *id = ctsvc_db_get_last_insert_id();
+               name->contact_id = contact_id;
+               ctsvc_stmt_finalize(stmt);
+
+               if (!is_my_profile)
+                       ctsvc_set_name_noti();
+       }
+
+       // update search index table
+       return CONTACTS_ERROR_NONE;
+}
+
+
+int ctsvc_db_name_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count)
+{
+       int ret;
+       char *temp;
+       ctsvc_name_s *name;
+
+       ret = contacts_record_create(_contacts_name._uri, (contacts_record_h *)&name);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+
+       name->id = ctsvc_stmt_get_int(stmt, start_count++);
+       name->contact_id = ctsvc_stmt_get_int(stmt, start_count++);
+       name->is_default = ctsvc_stmt_get_int(stmt, start_count++);
+       name->language_type = ctsvc_stmt_get_int(stmt, start_count++);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       name->first = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       name->last = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       name->addition = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       name->prefix = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       name->suffix = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       name->phonetic_first = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       name->phonetic_middle = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       name->phonetic_last = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       name->lookup = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       name->reverse_lookup = SAFE_STRDUP(temp);
+
+       *record = (contacts_record_h)name;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_name_update(contacts_record_h record, bool is_my_profile)
+{
+       int ret, len=0;
+       int id;
+       char* set = NULL;
+       GSList *cursor = NULL;
+       GSList *bind_text = NULL;
+       ctsvc_name_s *name = (ctsvc_name_s*)record;
+       char *tmp_first, *tmp_last;
+       char *normal_name[CTSVC_NN_MAX] = {NULL};
+       char *temp_normal_first = NULL;
+       char *temp_normal_last = NULL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       RETVM_IF(!name->id, CONTACTS_ERROR_INVALID_PARAMETER, "name of contact has no ID.");
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (name->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE id = %d", name->id);
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       RETV_IF(ret != CONTACTS_ERROR_NONE, ret);
+
+       tmp_first = name->first;
+       tmp_last = name->last;
+
+       ret = __ctsvc_normalize_name(name, normal_name);
+       if (ret < CONTACTS_ERROR_NONE) {
+               CTS_ERR("cts_normalize_name() Failed(%d)", ret);
+               return ret;
+       }
+
+       switch (ret) {
+       case CTSVC_LANG_KOREAN:
+               temp_normal_first = calloc(1, SAFE_STRLEN(normal_name[CTSVC_NN_LAST]) +  SAFE_STRLEN(normal_name[CTSVC_NN_LAST]) + 1);
+               if (normal_name[CTSVC_NN_LAST]) {
+                       len = snprintf(temp_normal_first, SAFE_STRLEN(normal_name[CTSVC_NN_LAST]) +  SAFE_STRLEN(normal_name[CTSVC_NN_LAST]) + 1,
+                               "%s", normal_name[CTSVC_NN_LAST]);
+               }
+               if (normal_name[CTSVC_NN_FIRST]) {
+                       snprintf(temp_normal_first+len, SAFE_STRLEN(normal_name[CTSVC_NN_LAST]) +  SAFE_STRLEN(normal_name[CTSVC_NN_LAST]) + 1 - len,
+                               "%s", normal_name[CTSVC_NN_FIRST]);
+               }
+               temp_normal_last = NULL;
+               break;
+       case CTSVC_LANG_ENGLISH:
+       default:
+               if (normal_name[CTSVC_NN_FIRST] && normal_name[CTSVC_NN_FIRST][0])
+                       temp_normal_first = normal_name[CTSVC_NN_FIRST];
+               else
+                       name->first = NULL;
+
+               if (normal_name[CTSVC_NN_LAST] && normal_name[CTSVC_NN_LAST][0])
+                       temp_normal_last = normal_name[CTSVC_NN_LAST];
+               else
+                       name->last = NULL;
+               break;
+       }
+
+       if (ctsvc_get_primary_sort() == ret)
+               name->language_type = CTSVC_LANG_DEFAULT;
+       else if (ctsvc_get_secondary_sort() == ret)
+                       name->language_type = CTSVC_LANG_SECONDARY;
+       else
+               name->language_type = ret;
+
+       name->first = tmp_first;
+       name->last = tmp_last;
+
+       __ctsvc_make_name_lookup(CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST,
+                                                               temp_normal_first, temp_normal_last, &name->lookup);
+
+       __ctsvc_make_name_lookup(CONTACTS_NAME_DISPLAY_ORDER_LASTFIRST,
+                                                               temp_normal_first, temp_normal_last, &name->reverse_lookup);
+
+       free(normal_name[CTSVC_NN_FIRST]);
+       free(normal_name[CTSVC_NN_LAST]);
+
+       do {
+               char query_set[CTS_SQL_MAX_LEN] = {0};
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               snprintf(query_set, sizeof(query_set), "%s, is_default=%d, data1=%d, data11=?, data12=?",
+                               set, name->is_default, name->language_type);
+               bind_text = g_slist_append(bind_text, strdup(SAFE_STR(name->lookup)));
+               bind_text = g_slist_append(bind_text, strdup(SAFE_STR(name->reverse_lookup)));
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(query_set, bind_text, CTS_TABLE_DATA, name->id))) break;
+
+               if (!is_my_profile)
+                       ctsvc_set_name_noti();
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_name_delete(int id, bool is_my_profile)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE id = %d", id);
+
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_exec() Failed(%d)", ret);
+
+       if (!is_my_profile)
+               ctsvc_set_name_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/native/ctsvc_db_plugin_name_helper.h b/native/ctsvc_db_plugin_name_helper.h
new file mode 100644 (file)
index 0000000..f73f940
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_NAME_HELPER_H__
+#define __CTSVC_DB_PLUGIN_NAME_HELPER_H__
+
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
+
+int ctsvc_db_name_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id);
+int ctsvc_db_name_update(contacts_record_h record, bool is_my_profile);
+int ctsvc_db_name_delete(int id, bool is_my_profile);
+
+int ctsvc_db_name_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count);
+
+#endif // __CTSVC_DB_PLUGIN_NAME_HELPER_H__
diff --git a/native/ctsvc_db_plugin_nickname.c b/native/ctsvc_db_plugin_nickname.c
new file mode 100644 (file)
index 0000000..004c3f2
--- /dev/null
@@ -0,0 +1,405 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_db_plugin_nickname_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_list.h"
+#include "ctsvc_notification.h"
+
+static int __ctsvc_db_nickname_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_nickname_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_nickname_update_record( contacts_record_h record );
+static int __ctsvc_db_nickname_delete_record( int id );
+static int __ctsvc_db_nickname_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_nickname_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_nickname_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_nickname_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_nickname_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_nickname = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_nickname_insert_record,
+       .get_record = __ctsvc_db_nickname_get_record,
+       .update_record = __ctsvc_db_nickname_update_record,
+       .delete_record = __ctsvc_db_nickname_delete_record,
+       .get_all_records = __ctsvc_db_nickname_get_all_records,
+       .get_records_with_query = __ctsvc_db_nickname_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_nickname_insert_records,
+       .update_records = NULL,//__ctsvc_db_nickname_update_records,
+       .delete_records = NULL,//__ctsvc_db_nickname_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_nickname_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_nickname_s *nickname = (ctsvc_nickname_s *)record;
+
+       RETVM_IF(NULL == nickname->nickname, CONTACTS_ERROR_INVALID_PARAMETER,
+               "Invalid parameter : nickname is NULL");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", nickname->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       CTS_ERR("No data : contact_id (%d) is not exist", nickname->contact_id);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               else {
+                       CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this nickname record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_nickname_insert(record, nickname->contact_id, false, id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_contact_update_display_name(nickname->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NICKNAME);
+
+       ret = ctsvc_db_contact_update_changed_time(nickname->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_nickname_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE id = %d AND datatype = %d ",
+                               id, CTSVC_DATA_NICKNAME);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ctsvc_db_nickname_get_value_from_stmt(stmt, out_record, 0);
+
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_nickname_update_record( contacts_record_h record )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_nickname_s *nickname = (ctsvc_nickname_s *)record;
+       RETVM_IF(NULL == nickname->nickname, CONTACTS_ERROR_INVALID_PARAMETER, "nickname is empty");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", nickname->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : contact_id (%d) is not exist", nickname->contact_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this nickname record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_nickname_update(record, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("Update record Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_contact_update_display_name(nickname->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NICKNAME);
+
+       ret = ctsvc_db_contact_update_changed_time(nickname->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_nickname_delete_record( int id )
+{
+       int ret;
+       int contact_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt;
+       int addressbook_id;
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
+                               "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("The id(%d) is Invalid(%d)", id, ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       contact_id = ctsvc_stmt_get_int(stmt, 0);
+       addressbook_id = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this nickname record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_nickname_delete(id, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_contact_update_display_name(contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NICKNAME);
+
+       ret = ctsvc_db_contact_update_changed_time(contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_nickname_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int len;
+       int ret;
+       contacts_list_h list;
+       ctsvc_nickname_s *nickname;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE datatype = %d AND is_my_profile=0 ",
+                               CTSVC_DATA_NICKNAME);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB : ctsvc_stmt_step fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_db_nickname_get_value_from_stmt(stmt, (contacts_record_h*)&nickname, 0);
+               ctsvc_list_prepend(list, (contacts_record_h)nickname);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_nickname_get_records_with_query( contacts_query_h query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_nickname_s *nickname;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_nickname._uri, &record);
+               nickname = (ctsvc_nickname_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if(CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_NICKNAME_ID:
+                               nickname->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_NICKNAME_CONTACT_ID:
+                               nickname->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_NICKNAME_NAME:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               nickname->nickname = SAFE_STRDUP(temp);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_nickname_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_nickname_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_nickname_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_nickname_helper.c b/native/ctsvc_db_plugin_nickname_helper.c
new file mode 100644 (file)
index 0000000..b2b214c
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_plugin_nickname_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+
+
+int ctsvc_db_nickname_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count)
+{
+       int ret;
+       char *temp;
+       ctsvc_nickname_s *nickname;
+
+       ret = contacts_record_create(_contacts_nickname._uri, (contacts_record_h *)&nickname);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+
+       nickname->id = ctsvc_stmt_get_int(stmt, start_count++);
+       nickname->contact_id = ctsvc_stmt_get_int(stmt, start_count++);
+       start_count++;
+       start_count++;
+       start_count++;
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       nickname->nickname = SAFE_STRDUP(temp);
+
+       *record = (contacts_record_h)nickname;
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_nickname_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_nickname_s *nickname = (ctsvc_nickname_s *)record;
+
+       RETV_IF(NULL == nickname->nickname, CONTACTS_ERROR_NONE);
+       RETVM_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : contact_id(%d) is mandatory field to insert nickname record ", nickname->contact_id);
+       RETVM_IF(0 < nickname->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", nickname->id);
+
+       snprintf(query, sizeof(query),
+               "INSERT INTO "CTS_TABLE_DATA"(contact_id, is_my_profile, datatype, data1, data2, data3) "
+                                                                       "VALUES(%d, %d, %d, %d, ?, ?)",
+                       contact_id, is_my_profile, CTSVC_DATA_NICKNAME, nickname->type);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       if (nickname->label)
+               ctsvc_stmt_bind_text(stmt, 1, nickname->label);
+       if (nickname->nickname)
+               ctsvc_stmt_bind_text(stmt, 2, nickname->nickname);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+
+       //nickname->id = ctsvc_db_get_last_insert_id();
+       if (id)
+               *id = ctsvc_db_get_last_insert_id();
+       ctsvc_stmt_finalize(stmt);
+
+       if (!is_my_profile)
+               ctsvc_set_nickname_noti();
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_nickname_update(contacts_record_h record, bool is_my_profile)
+{
+       int id;
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       ctsvc_nickname_s *nickname = (ctsvc_nickname_s*)record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(!nickname->id, CONTACTS_ERROR_INVALID_PARAMETER, "nickname of contact has no ID.");
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (nickname->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE id = %d", nickname->id);
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       RETV_IF(ret != CONTACTS_ERROR_NONE, ret);
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_DATA, nickname->id))) break;
+               if (!is_my_profile)
+                       ctsvc_set_nickname_noti();
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+       return ret;
+}
+
+int ctsvc_db_nickname_delete(int id, bool is_my_profile)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE id = %d AND datatype = %d",
+                       id, CTSVC_DATA_NICKNAME);
+
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_exec() Failed(%d)", ret);
+
+       if (!is_my_profile)
+               ctsvc_set_nickname_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/native/ctsvc_db_plugin_nickname_helper.h b/native/ctsvc_db_plugin_nickname_helper.h
new file mode 100644 (file)
index 0000000..0041f9e
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_NICKNAME_HELPER_H__
+#define __CTSVC_DB_PLUGIN_NICKNAME_HELPER_H__
+
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
+
+int ctsvc_db_nickname_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id);
+int ctsvc_db_nickname_update(contacts_record_h record, bool is_my_profile);
+int ctsvc_db_nickname_delete(int id, bool is_my_profile);
+int ctsvc_db_nickname_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count);
+
+#endif // __CTSVC_DB_PLUGIN_NICKNAME_HELPER_H__
diff --git a/native/ctsvc_db_plugin_note.c b/native/ctsvc_db_plugin_note.c
new file mode 100644 (file)
index 0000000..620e595
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_db_plugin_note_helper.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_list.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+
+static int __ctsvc_db_note_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_note_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_note_update_record( contacts_record_h record );
+static int __ctsvc_db_note_delete_record( int id );
+static int __ctsvc_db_note_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_note_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_note_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_note_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_note_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_note = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_note_insert_record,
+       .get_record = __ctsvc_db_note_get_record,
+       .update_record = __ctsvc_db_note_update_record,
+       .delete_record = __ctsvc_db_note_delete_record,
+       .get_all_records = __ctsvc_db_note_get_all_records,
+       .get_records_with_query = __ctsvc_db_note_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_note_insert_records,
+       .update_records = NULL,//__ctsvc_db_note_update_records,
+       .delete_records = NULL,//__ctsvc_db_note_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_note_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE id = %d AND datatype = %d ",
+                               id, CTSVC_DATA_NOTE);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ctsvc_db_note_get_value_from_stmt(stmt, out_record, 0);
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_note_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_note_s *note = (ctsvc_note_s *)record;
+
+       RETVM_IF(NULL == note->note, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : note is NULL");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", note->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       CTS_ERR("No data : contact_id (%d) is not exist", note->contact_id);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               else {
+                       CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this note record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_note_insert(record, note->contact_id, false, id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(note->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_note_update_record( contacts_record_h record )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_note_s *note = (ctsvc_note_s *)record;
+
+       RETVM_IF(NULL == note->note, CONTACTS_ERROR_INVALID_PARAMETER, "note is empty");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", note->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : contact_id (%d) is not exist", note->contact_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this note record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_note_update(record, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("Update record Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       // TODO ; contact display note update
+       ret = ctsvc_db_contact_update_changed_time(note->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+
+static int __ctsvc_db_note_delete_record( int id )
+{
+       int ret;
+       int contact_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt;
+       int addressbook_id;
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
+                               "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("The id(%d) is Invalid(%d)", id, ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       contact_id = ctsvc_stmt_get_int(stmt, 0);
+       addressbook_id = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this note record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_note_delete(id, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       // TODO ; contact name update
+       ret = ctsvc_db_contact_update_changed_time(contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_note_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int len;
+       int ret;
+       contacts_list_h list;
+       ctsvc_note_s *note;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE datatype = %d AND is_my_profile=0 ",
+                               CTSVC_DATA_NOTE);
+
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB : ctsvc_stmt_step fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_db_note_get_value_from_stmt(stmt, (contacts_record_h*)&note, 0);
+               ctsvc_list_prepend(list, (contacts_record_h)note);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_note_get_records_with_query( contacts_query_h query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_note_s *note;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_note._uri, &record);
+               note = (ctsvc_note_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if(CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_NOTE_ID:
+                               note->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_NOTE_CONTACT_ID:
+                               note->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_NOTE_NOTE:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               note->note = SAFE_STRDUP(temp);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_note_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_note_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_note_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_note_helper.c b/native/ctsvc_db_plugin_note_helper.c
new file mode 100644 (file)
index 0000000..d82b45e
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_plugin_note_helper.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_record.h"
+
+int ctsvc_db_note_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count)
+{
+       int ret;
+       char *temp;
+       ctsvc_note_s *note;
+
+       ret = contacts_record_create(_contacts_note._uri, (contacts_record_h *)&note);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+
+       note->id = ctsvc_stmt_get_int(stmt, start_count++);
+       note->contact_id = ctsvc_stmt_get_int(stmt, start_count++);
+       start_count++;
+       start_count++;
+       start_count++;
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       note->note = SAFE_STRDUP(temp);
+
+       *record = (contacts_record_h)note;
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_note_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       ctsvc_note_s *note = (ctsvc_note_s*)record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETV_IF(NULL == note->note, CONTACTS_ERROR_NONE);
+       RETVM_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : contact_id(%d) is mandatory field to insert note record ", note->contact_id);
+       RETVM_IF(0 < note->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", note->id);
+
+       snprintf(query, sizeof(query),
+               "INSERT INTO "CTS_TABLE_DATA"(contact_id, is_my_profile, datatype, data3) "
+                                       "VALUES(%d, %d, %d, ?)", contact_id, is_my_profile, CTSVC_DATA_NOTE);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       sqlite3_bind_text(stmt, 1, note->note,
+                       strlen(note->note), SQLITE_STATIC);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+       if (id)
+               *id = ctsvc_db_get_last_insert_id();
+       ctsvc_stmt_finalize(stmt);
+
+       if (!is_my_profile)
+               ctsvc_set_note_noti();
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_note_update(contacts_record_h record, bool is_my_profile)
+{
+       int id;
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       ctsvc_note_s *note = (ctsvc_note_s*)record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(!note->id, CONTACTS_ERROR_INVALID_PARAMETER, "note of contact has no ID.");
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (note->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE id = %d", note->id);
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       RETV_IF(ret != CONTACTS_ERROR_NONE, ret);
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_DATA, note->id))) break;
+
+               if (!is_my_profile)
+                       ctsvc_set_messenger_noti();
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       return ret;
+}
+
+int ctsvc_db_note_delete(int id, bool is_my_profile)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE id = %d AND datatype = %d",
+                       id, CTSVC_DATA_NOTE);
+
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_exec() Failed(%d)", ret);
+
+       if (!is_my_profile)
+               ctsvc_set_note_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/native/ctsvc_db_plugin_note_helper.h b/native/ctsvc_db_plugin_note_helper.h
new file mode 100644 (file)
index 0000000..1fa1ef0
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_NOTE_HELPER_H__
+#define __CTSVC_DB_PLUGIN_NOTE_HELPER_H__
+
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
+
+int ctsvc_db_note_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id);
+int ctsvc_db_note_update(contacts_record_h record, bool is_my_profile);
+int ctsvc_db_note_delete(int id, bool is_my_profile);
+int ctsvc_db_note_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count);
+
+#endif // __CTSVC_DB_PLUGIN_NOTE_HELPER_H__
diff --git a/native/ctsvc_db_plugin_number.c b/native/ctsvc_db_plugin_number.c
new file mode 100644 (file)
index 0000000..d8eb653
--- /dev/null
@@ -0,0 +1,602 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_number_helper.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_list.h"
+
+static int __ctsvc_db_number_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_number_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_number_update_record( contacts_record_h record );
+static int __ctsvc_db_number_delete_record( int id );
+static int __ctsvc_db_number_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_number_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_number_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_number_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_number_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_number = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_number_insert_record,
+       .get_record = __ctsvc_db_number_get_record,
+       .update_record = __ctsvc_db_number_update_record,
+       .delete_record = __ctsvc_db_number_delete_record,
+       .get_all_records = __ctsvc_db_number_get_all_records,
+       .get_records_with_query = __ctsvc_db_number_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_number_insert_records,
+       .update_records = NULL,//__ctsvc_db_number_update_records,
+       .delete_records = NULL,//__ctsvc_db_number_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_number_get_person_default_number(int person_id)
+{
+       int ret;
+       int default_number_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+               "SELECT id FROM "CTS_TABLE_CONTACTS" c, "CTS_TABLE_DATA" d "
+               "WHERE c.person_id = %d AND d.datatype = %d AND c.contact_id = d.contact_id AND d.is_default = 1",
+               person_id, CTSVC_DATA_NUMBER);
+       ret = ctsvc_query_get_first_int_result(query, &default_number_id);
+       if (CONTACTS_ERROR_NONE != ret)
+               return 0;
+       return default_number_id;
+}
+
+
+static int __ctsvc_db_number_update_person_has_phonenumber(int person_id, bool has_phonenumber)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_PERSONS" SET has_phonenumber = %d WHERE person_id = %d",
+                       has_phonenumber, person_id);
+
+       ret = ctsvc_query_exec(query);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Failed(%d)", ret);
+       return ret;
+}
+
+static int __ctsvc_db_number_get_default_number_id(int contact_id)
+{
+       int ret;
+       int number_id = 0;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE datatype=%d AND contact_id=%d AND is_default=1",
+                       CTSVC_DATA_NUMBER, contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &number_id);
+       if (CONTACTS_ERROR_NONE != ret)
+               return 0;
+       return number_id;
+}
+
+static int __ctsvc_db_number_update_default(int number_id, int contact_id, bool is_default, bool is_primary_default)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_DATA" SET is_default = %d, is_primary_default = %d WHERE id = %d",
+                       is_default, is_primary_default, number_id);
+       ret = ctsvc_query_exec(query);
+
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Failed(%d)", ret);
+       return ret;
+}
+
+static int __ctsvc_db_number_get_primary_default(int contact_id)
+{
+       int ret;
+       int number_id = 0;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE datatype=%d AND contact_id=%d AND is_primary_default=%d",
+                       CTSVC_DATA_NUMBER, contact_id, 1);
+       ret = ctsvc_query_get_first_int_result(query, &number_id);
+       if (CONTACTS_ERROR_NONE != ret)
+               return 0;
+       return number_id;
+}
+
+static int __ctsvc_db_number_get_primary_default_contact_id(int person_id)
+{
+       int ret;
+       int default_contact_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "SELECT c.contact_id FROM "CTS_TABLE_CONTACTS" c, "CTS_TABLE_DATA" d "
+                       "WHERE c.person_id = %d AND d.datatype = %d AND c.contact_id = d.contact_id AND d.is_primary_default = 1",
+                       person_id, CTSVC_DATA_NUMBER);
+       ret = ctsvc_query_get_first_int_result(query, &default_contact_id);
+       if (CONTACTS_ERROR_NONE != ret)
+               return 0;
+       return default_contact_id;
+}
+
+
+static int __ctsvc_db_number_set_primary_default(int number_id, bool is_primary_default)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_DATA" SET is_primary_default = %d WHERE id = %d",
+                       is_primary_default, number_id);
+       ret = ctsvc_query_exec(query);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Failed(%d)", ret);
+       return ret;
+}
+
+static int __ctsvc_db_number_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int person_id;
+       int old_default_number_id = 0;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt = NULL;
+       ctsvc_number_s *number = (ctsvc_number_s *)record;
+       RETVM_IF(NULL == number->number, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : number is NULL");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id, person_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", number->contact_id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NO_DATA)
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               else
+                       return ret;
+       }
+       addressbook_id = ctsvc_stmt_get_int(stmt, 0);
+       person_id = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this number record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       old_default_number_id = __ctsvc_db_number_get_default_number_id(number->contact_id);
+       if (0 == old_default_number_id)
+               number->is_default = true;
+
+       ret = ctsvc_db_number_insert(record, number->contact_id, false, id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+               "UPDATE "CTS_TABLE_CONTACTS" SET has_phonenumber = %d, changed_ver = %d, changed_time = %d "
+                       "WHERE contact_id = %d",
+                       1, ctsvc_get_next_ver(), (int)time(NULL), number->contact_id);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (number->is_default) {
+               int primary_default_contact_id = 0;
+               __ctsvc_db_number_update_person_has_phonenumber(person_id, true);
+
+               primary_default_contact_id = __ctsvc_db_number_get_primary_default_contact_id(person_id);
+               if (0 == primary_default_contact_id || number->contact_id == primary_default_contact_id)
+                       __ctsvc_db_number_set_primary_default(*id, true);
+
+               ctsvc_contact_update_display_name(number->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NUMBER);
+       }
+
+       ctsvc_set_contact_noti();
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_number_get_record( int id, contacts_record_h* out_record )
+{
+       char query[CTS_SQL_MAX_LEN] = {0};
+       int ret;
+       cts_stmt stmt = NULL;
+
+       snprintf(query, sizeof(query),
+               "SELECT id, contact_id, is_default, data1, data2, data3, data4, data5, data6 "
+                               "FROM "CTSVC_DB_VIEW_NUMBER" WHERE id = %d", id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ctsvc_db_number_get_value_from_stmt(stmt, out_record, 0);
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_number_update_record( contacts_record_h record )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_number_s *number = (ctsvc_number_s *)record;
+       RETVM_IF(NULL == number->number, CONTACTS_ERROR_INVALID_PARAMETER, "number is empty");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", number->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : contact_id (%d) is not exist", number->contact_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this number record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_number_update(record, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (number->is_default) {
+               int old_primary_default_number_id = 0;
+               old_primary_default_number_id = __ctsvc_db_number_get_primary_default(number->contact_id);
+               if (old_primary_default_number_id)
+                       __ctsvc_db_number_set_primary_default(number->id, true);
+       }
+       ctsvc_contact_update_display_name(number->contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NUMBER);
+
+       ret = ctsvc_db_contact_update_changed_time(number->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_number_delete_record( int id )
+{
+       int ret;
+       int number_id;
+       int contact_id;
+       int person_id;
+       int addressbook_id;
+       int is_default;
+       int is_primary_default;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       bool has_phonenumber = false;
+       cts_stmt stmt = NULL;
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, person_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
+                       "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       contact_id = ctsvc_stmt_get_int(stmt, 0);
+       person_id = ctsvc_stmt_get_int(stmt, 1);
+       addressbook_id = ctsvc_stmt_get_int(stmt, 2);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this number record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT is_default, is_primary_default FROM "CTS_TABLE_DATA" WHERE id = %d", id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+       is_default = ctsvc_stmt_get_int(stmt, 0);
+       is_primary_default = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       ret = ctsvc_db_number_delete(id, false);
+
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE datatype = %d AND contact_id = %d AND is_my_profile = 0 limit 1",
+                       CTSVC_DATA_NUMBER, contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &number_id);
+       if ( 0 < ret )
+               has_phonenumber = true;
+
+       snprintf(query, sizeof(query),
+               "UPDATE "CTS_TABLE_CONTACTS" SET has_phonenumber = %d, changed_ver = %d, changed_time = %d "
+                       "WHERE contact_id = %d",
+                       has_phonenumber, ctsvc_get_next_ver(), (int)time(NULL), contact_id);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (is_default) {
+               if (number_id) {
+                       __ctsvc_db_number_update_default(number_id, contact_id, is_default, is_primary_default);
+               }
+               else if (is_primary_default) {
+                       int default_number_id = 0;
+                       default_number_id = __ctsvc_db_number_get_person_default_number(person_id);
+                       if (default_number_id)
+                               __ctsvc_db_number_set_primary_default(default_number_id, true);
+                       else
+                               __ctsvc_db_number_update_person_has_phonenumber(person_id, false);
+               }
+               ctsvc_contact_update_display_name(contact_id, CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NUMBER);
+       }
+
+       ctsvc_set_contact_noti();
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "DB error : ctsvc_end_trans() Failed(%d)", ret);
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_number_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int len;
+       int ret;
+       contacts_list_h list;
+       ctsvc_number_s *number;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3, data4, data5, data6 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE datatype = %d AND is_my_profile=0 ",
+                               CTSVC_DATA_NUMBER);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step Failed (%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_db_number_get_value_from_stmt(stmt, (contacts_record_h*)&number, 0);
+               ctsvc_list_prepend(list, (contacts_record_h)number);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_number_get_records_with_query( contacts_query_h query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_number_s *number;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_number._uri, &record);
+               number = (ctsvc_number_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if(CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_NUMBER_ID:
+                               number->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_NUMBER_CONTACT_ID:
+                               number->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_NUMBER_TYPE:
+                               number->type = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_NUMBER_IS_DEFAULT:
+                               number->is_default = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_NUMBER_LABEL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               number->label = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_NUMBER_NUMBER:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               number->number = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_NUMBER_NUMBER_FILTER:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               number->lookup = SAFE_STRDUP(temp);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_number_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_number_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_number_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_number_helper.c b/native/ctsvc_db_plugin_number_helper.c
new file mode 100644 (file)
index 0000000..21f33c2
--- /dev/null
@@ -0,0 +1,338 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_number_utils.h"
+#include "ctsvc_db_plugin_number_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_setting.h"
+#include "ctsvc_localize_utils.h"
+
+#ifdef ENABLE_LOG_FEATURE
+#include "ctsvc_phonelog.h"
+#endif // ENABLE_LOG_FEATURE
+
+static int __ctsvc_db_number_reset_default(int number_id, int contact_id)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_DATA" SET is_default = 0, is_primary_default = 0 WHERE id != %d AND contact_id = %d AND datatype = %d",
+                       number_id, contact_id, CTSVC_DATA_NUMBER);
+       ret = ctsvc_query_exec(query);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec() Failed(%d)", ret);
+       return ret;
+}
+
+int ctsvc_db_number_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id)
+{
+       int ret;
+       int number_id;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_number_s *number = (ctsvc_number_s *)record;
+
+       RETV_IF(NULL == number->number, CONTACTS_ERROR_NONE);
+       RETVM_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : contact_id(%d) is mandatory field to insert number record ", number->contact_id);
+       RETVM_IF(0 < number->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", number->id);
+
+       snprintf(query, sizeof(query),
+               "INSERT INTO "CTS_TABLE_DATA"(contact_id, is_my_profile, datatype, is_default, data1, data2, data3, data4, data5, data6) "
+                                                                       "VALUES(%d, %d, %d, %d, %d, ?, ?, ?, ?, ?)",
+                       contact_id, is_my_profile, CTSVC_DATA_NUMBER, number->is_default, number->type);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       if (number->label)
+               ctsvc_stmt_bind_text(stmt, 1, number->label);
+
+       ctsvc_stmt_bind_text(stmt, 2, number->number);
+
+       char clean_num[SAFE_STRLEN(number->number) + 1];
+       ret = ctsvc_clean_number(number->number, clean_num, sizeof(clean_num), true);
+       if (0 < ret) {
+               char normal_num[sizeof(clean_num) + 20];
+               ctsvc_stmt_bind_copy_text(stmt, 5, clean_num, strlen(clean_num));
+               ret = ctsvc_normalize_number(clean_num, normal_num, sizeof(normal_num), true);
+               if (0 < ret) {
+                       ctsvc_stmt_bind_copy_text(stmt, 4, normal_num, strlen(normal_num));
+                       char minmatch[sizeof(normal_num) + 1];
+                       ret = ctsvc_get_minmatch_number(normal_num, minmatch, sizeof(minmatch), ctsvc_get_phonenumber_min_match_digit());
+                       if (CONTACTS_ERROR_NONE == ret)
+                               ctsvc_stmt_bind_copy_text(stmt, 3, minmatch, strlen(minmatch));
+               }
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+
+       number_id = ctsvc_db_get_last_insert_id();
+       if (id)
+               *id = number_id;
+       ctsvc_stmt_finalize(stmt);
+
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_number.is_default, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               if (number->is_default)
+                       __ctsvc_db_number_reset_default(number_id, contact_id);
+       }
+
+       if (!is_my_profile) {
+#ifdef ENABLE_LOG_FEATURE
+               // updata phonelog
+               int person_id = -1;
+               snprintf(query, sizeof(query),
+                               "SELECT person_id, data3 FROM "CTS_TABLE_CONTACTS", "CTS_TABLE_DATA" "
+                                                                               "ON "CTS_TABLE_CONTACTS".contact_id = "CTS_TABLE_DATA".contact_id "
+                                                                               "WHERE data.id = %d", number_id);
+               ret = ctsvc_query_get_first_int_result(query, &person_id);
+               if (person_id > 0)
+                       ctsvc_db_phone_log_update_person_id(number->number, -1, person_id, false);
+#endif // ENABLE_LOG_FEATURE
+               ctsvc_set_number_noti();
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+
+int ctsvc_db_number_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count)
+{
+       int ret;
+       char *temp;
+       ctsvc_number_s *number;
+
+       ret = contacts_record_create(_contacts_number._uri, (contacts_record_h *)&number);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+
+       number->id = ctsvc_stmt_get_int(stmt, start_count++);
+       number->contact_id = ctsvc_stmt_get_int(stmt, start_count++);
+       number->is_default = ctsvc_stmt_get_int(stmt, start_count++);
+       number->type = ctsvc_stmt_get_int(stmt, start_count++);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       number->label = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       number->number = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       number->lookup = SAFE_STRDUP(temp);                     // data4 : minmatch
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       number->normalized = SAFE_STRDUP(temp); // data5 : normalized number
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       number->cleaned = SAFE_STRDUP(temp);            // data6 : cleaned number
+
+       *record = (contacts_record_h)number;
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_number_update(contacts_record_h record, bool is_my_profile)
+{
+       int id;
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       ctsvc_number_s *number = (ctsvc_number_s *)record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+#ifdef ENABLE_LOG_FEATURE
+       // for updating phonelog
+       char *pre_number = NULL;
+       int person_id = -1;
+       cts_stmt stmt = NULL;
+#endif // ENABLE_LOG_FEATURE
+
+       RETVM_IF(!number->id, CONTACTS_ERROR_INVALID_PARAMETER, "number of contact has no ID.");
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (number->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY),
+                               CONTACTS_ERROR_NONE, "No update");
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE id = %d", number->id);
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       RETV_IF(ret != CONTACTS_ERROR_NONE, ret);
+
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_number.is_default, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               if (number->is_default)
+                       __ctsvc_db_number_reset_default(number->id, number->contact_id);
+       }
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, CTSVC_PROPERTY_NUMBER_NUMBER, CTSVC_PROPERTY_FLAG_DIRTY)) {
+                       int len;
+                       char query_set[CTS_SQL_MAX_LEN] = {0};
+
+#ifdef ENABLE_LOG_FEATURE
+                       // updata phonelog
+                       snprintf(query, sizeof(query),
+                                       "SELECT person_id, data3 FROM "CTS_TABLE_CONTACTS", "CTS_TABLE_DATA" "
+                                                                                       "ON "CTS_TABLE_CONTACTS".contact_id = "CTS_TABLE_DATA".contact_id "
+                                                                                       "WHERE data.id = %d", number->id);
+                       ret = ctsvc_query_prepare(query, &stmt);
+                       if (stmt != NULL) {
+                               ret = ctsvc_stmt_step(stmt);
+                               if (ret == 1) {
+                                       person_id = ctsvc_stmt_get_int(stmt, 0);
+                                       pre_number = ctsvc_stmt_get_text(stmt, 1);
+                               }
+                               else
+                                       WARN("ctsvc_stmt_step fail (%d)", ret);
+                       }
+                       else
+                               WARN("ctsvc_query_prepare fail (%d)", ret);
+#endif // ENABLE_LOG_FEATURE
+
+                       char clean_num[SAFE_STRLEN(number->number) + 1];
+                       ret = ctsvc_clean_number(number->number, clean_num, sizeof(clean_num), true);
+                       if (0 < ret) {
+                               char normal_num[sizeof(clean_num) + 20];
+                               len = snprintf(query_set, sizeof(query_set), "%s, data6=?", set);
+                               bind_text = g_slist_append(bind_text, strdup(clean_num));
+                               free(set);
+
+                               ret = ctsvc_normalize_number(clean_num, normal_num, sizeof(normal_num), true);
+                               if (0 < ret) {
+                                       len += snprintf(query_set+len, sizeof(query_set)-len, ", data5=?");
+                                       bind_text = g_slist_append(bind_text, strdup(normal_num));
+                                       char minmatch[sizeof(normal_num)+1];
+                                       ret = ctsvc_get_minmatch_number(normal_num, minmatch, sizeof(minmatch), ctsvc_get_phonenumber_min_match_digit());
+                                       if (CONTACTS_ERROR_NONE == ret) {
+                                               len += snprintf(query_set+len, sizeof(query_set)-len, ", data4=?");
+                                               bind_text = g_slist_append(bind_text, strdup(minmatch));
+                                       }
+                               }
+                               set = strdup(query_set);
+                       }
+               }
+#ifdef ENABLE_LOG_FEATURE
+               if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, CTSVC_PROPERTY_NUMBER_TYPE, CTSVC_PROPERTY_FLAG_DIRTY)) {
+                       if (person_id <= 0) {
+                               // updata phonelog
+                               snprintf(query, sizeof(query),
+                                               "SELECT person_id, data3 FROM "CTS_TABLE_CONTACTS", "CTS_TABLE_DATA" "
+                                                                                               "ON "CTS_TABLE_CONTACTS".contact_id = "CTS_TABLE_DATA".contact_id "
+                                                                                               "WHERE data.id = %d", number->id);
+                               ret = ctsvc_query_prepare(query, &stmt);
+                               if (stmt != NULL) {
+                                       ret = ctsvc_stmt_step(stmt);
+                                       if (ret == 1) {
+                                               person_id = ctsvc_stmt_get_int(stmt, 0);
+                                               pre_number = ctsvc_stmt_get_text(stmt, 1);
+                                       }
+                                       else
+                                               WARN("ctsvc_stmt_step fail (%d)", ret);
+                               }
+                               else
+                                       WARN("ctsvc_query_prepare fail (%d)", ret);
+                       }
+               }
+#endif // ENABLE_LOG_FEATURE
+
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_DATA, number->id))) break;
+
+               if (!is_my_profile)
+                       ctsvc_set_number_noti();
+
+#ifdef ENABLE_LOG_FEATURE
+               // update phone log
+               if (person_id > 0 && pre_number != NULL)
+                       ctsvc_db_phone_log_update_person_id(pre_number, person_id, -1, false);
+               if (person_id > 0)
+                       ctsvc_db_phone_log_update_person_id(number->number, -1, person_id, false);
+               ctsvc_stmt_finalize(stmt);
+#endif // ENABLE_LOG_FEATURE
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       return ret;
+}
+
+int ctsvc_db_number_delete(int id, bool is_my_profile)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+#ifdef ENABLE_LOG_FEATURE
+       // for updating phonelog
+       char *pre_number = NULL;
+       int person_id = -1;
+       cts_stmt stmt = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT person_id, data3 FROM "CTS_TABLE_CONTACTS", "CTS_TABLE_DATA" "
+                                                                       "ON "CTS_TABLE_CONTACTS".contact_id = "CTS_TABLE_DATA".contact_id "
+                                                                       "WHERE data.id = %d", id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (stmt != NULL) {
+               ret = ctsvc_stmt_step(stmt);
+               if (ret == 1) {
+                       person_id = ctsvc_stmt_get_int(stmt, 0);
+                       pre_number = ctsvc_stmt_get_text(stmt, 1);
+               }
+               else
+                       WARN("ctsvc_stmt_step fail (%d)", ret);
+       }
+       else
+               WARN("ctsvc_query_prepare fail (%d)", ret);
+#endif // ENABLE_LOG_FEATURE
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE id = %d AND datatype = %d",
+                       id, CTSVC_DATA_NUMBER);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+#ifdef ENABLE_LOG_FEATURE
+               ctsvc_stmt_finalize(stmt);
+#endif // ENABLE_LOG_FEATURE
+               return ret;
+       }
+
+#ifdef ENABLE_LOG_FEATURE
+       // update phone log
+       if (person_id > 0 && pre_number != NULL)
+               ctsvc_db_phone_log_update_person_id(pre_number, person_id, -1, false);
+       ctsvc_stmt_finalize(stmt);
+#endif // ENABLE_LOG_FEATURE
+
+       if (!is_my_profile)
+               ctsvc_set_number_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/native/ctsvc_db_plugin_number_helper.h b/native/ctsvc_db_plugin_number_helper.h
new file mode 100644 (file)
index 0000000..4991391
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_NUMBER_HELPER_H__
+#define __CTSVC_DB_PLUGIN_NUMBER_HELPER_H__
+
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
+
+int ctsvc_db_number_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id);
+int ctsvc_db_number_update(contacts_record_h record, bool is_my_profile);
+int ctsvc_db_number_delete(int id, bool is_my_profile);
+
+int ctsvc_db_number_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count);
+
+#endif // __CTSVC_DB_PLUGIN_NUMBER_HELPER_H__
diff --git a/native/ctsvc_db_plugin_person.c b/native/ctsvc_db_plugin_person.c
new file mode 100644 (file)
index 0000000..c486488
--- /dev/null
@@ -0,0 +1,636 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_plugin_person_helper.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_list.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_record.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_notification.h"
+
+#ifdef _CONTACTS_IPC_SERVER
+#include "ctsvc_server_change_subject.h"
+#endif
+
+static int __ctsvc_db_person_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_person_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_person_update_record( contacts_record_h record );
+static int __ctsvc_db_person_delete_record( int id );
+static int __ctsvc_db_person_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_person_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_person_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_person_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_person_delete_records(int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_person = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_person_insert_record,
+       .get_record = __ctsvc_db_person_get_record,
+       .update_record = __ctsvc_db_person_update_record,
+       .delete_record = __ctsvc_db_person_delete_record,
+       .get_all_records = __ctsvc_db_person_get_all_records,
+       .get_records_with_query = __ctsvc_db_person_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_person_insert_records,
+       .update_records = NULL,//__ctsvc_db_person_update_records,
+       .delete_records = NULL,//__ctsvc_db_person_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_person_insert_record( contacts_record_h record, int *id )
+{
+       CTS_ERR("Can not insert person record directly");
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+static int __ctsvc_db_person_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_record_h record;
+
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+               "SELECT persons.person_id, "
+                               "%s, "
+                               "_NORMALIZE_INDEX_(%s), "
+                               "name_contact_id, "
+                               "persons.image_thumbnail_path, "
+                               "persons.ringtone_path, "
+                               "persons.vibration, "
+                               "persons.message_alert, "
+                               "status, "
+                               "link_count, "
+                               "addressbook_ids, "
+                               "persons.has_phonenumber, "
+                               "persons.has_email, "
+                               "EXISTS(SELECT person_id FROM "CTS_TABLE_FAVORITES" WHERE person_id=persons.person_id) is_favorite "
+                       "FROM "CTS_TABLE_PERSONS" "
+                       "LEFT JOIN "CTS_TABLE_CONTACTS" "
+                       "ON (name_contact_id = contacts.contact_id AND contacts.deleted = 0) "
+                       "WHERE persons.person_id = %d",
+                       ctsvc_get_display_column(), ctsvc_get_sort_name_column(), id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if( 1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+       ret = ctsvc_db_person_create_record_from_stmt(stmt, &record);
+       ctsvc_stmt_finalize(stmt);
+
+       if(CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_db_person_create_record_from_stmt() Failed(%d)", ret);
+               return ret;
+       }
+
+       *out_record = record;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_person_update_record( contacts_record_h record )
+{
+       int ret, i, len;
+       int person_id;
+       cts_stmt stmt = NULL;
+       char *set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       char contact_query[CTS_SQL_MIN_LEN] = {0};
+       char query[CTS_SQL_MIN_LEN] = {0};
+       ctsvc_person_s *person = (ctsvc_person_s *)record;
+       const char *display_name = NULL;
+       int index_favorite = 0;
+
+       RETV_IF(NULL == person, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(person->person_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "SELECT person_id FROM "CTS_TABLE_PERSONS" WHERE person_id = %d", person->person_id);
+       ret = ctsvc_query_get_first_int_result(query, &person_id);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)person, _contacts_person.display_contact_id, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               // check name_contact_id validation
+               char *temp;
+               char check_query[CTS_SQL_MIN_LEN] = {0};
+               snprintf(check_query, sizeof(check_query), "SELECT contact_id, %s FROM "CTS_TABLE_CONTACTS
+                               " WHERE person_id = %d AND contact_id = %d AND deleted = 0",
+                               ctsvc_get_display_column(), person->person_id, person->name_contact_id);
+               ret = ctsvc_query_prepare(check_query, &stmt);
+               if (NULL == stmt) {
+                       CTS_ERR("ctsvc_query_prepare() Failed(%d)", ret);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+
+               ret = ctsvc_stmt_step(stmt);
+               if ( 1 != ret) {
+                       if ( CONTACTS_ERROR_NONE == ret) {
+                               CTS_ERR("Invalid parameter : the name_contact_id(%d) is not linked with person_id(%d)",
+                                       person->name_contact_id, person->person_id);
+                               ctsvc_stmt_finalize(stmt);
+                               ctsvc_end_trans(false);
+                               return CONTACTS_ERROR_INVALID_PARAMETER;
+                       }
+                       else {
+                               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+                               ctsvc_stmt_finalize(stmt);
+                               ctsvc_end_trans(false);
+                               return ret;
+                       }
+               }
+               temp = ctsvc_stmt_get_text(stmt, 0);
+               display_name = SAFE_STRDUP(temp);
+
+               ctsvc_stmt_finalize(stmt);
+       }
+
+       // update favorite
+       index_favorite = CTSVC_PROPERTY_PERSON_IS_FAVORITE & 0x000000FF;
+       if (person->base.properties_flags &&
+                       CTSVC_PROPERTY_FLAG_DIRTY == person->base.properties_flags[index_favorite]) {
+               ret = ctsvc_db_person_set_favorite(person->person_id, person->is_favorite, true);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_db_person_set_favorite() Failed(%d)", ret);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+               person->base.properties_flags[index_favorite] = 0;
+               ctsvc_set_contact_noti();
+       }
+
+       do {
+               int ret = CONTACTS_ERROR_NONE;
+               char query[CTS_SQL_MAX_LEN] = {0};
+               char query_set[CTS_SQL_MIN_LEN] = {0, };
+               GSList *cursor = NULL;
+
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (NULL == set || '\0' == *set)
+                       break;
+               snprintf(query_set, sizeof(query_set), "%s, changed_ver=%d", set, ctsvc_get_next_ver());
+               snprintf(query, sizeof(query), "UPDATE %s SET %s WHERE person_id = %d", CTS_TABLE_PERSONS, query_set, person->person_id);
+
+               ret = ctsvc_query_prepare(query, &stmt);
+               if (NULL == stmt) {
+                       CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+                       break;
+               }
+
+               if (bind_text) {
+                       int i = 0;
+                       for (cursor=bind_text,i=1;cursor;cursor=cursor->next,i++) {
+                               const char *text = cursor->data;
+                               if (text && *text)
+                                       ctsvc_stmt_bind_text(stmt, i, text);
+                       }
+               }
+               ret = ctsvc_stmt_step(stmt);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       break;
+               }
+               ctsvc_stmt_finalize(stmt);
+       } while (0);
+
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+               CONTACTS_FREE(set);
+               if (bind_text) {
+                       for (cursor=bind_text;cursor;cursor=cursor->next)
+                               CONTACTS_FREE(cursor->data);
+                       g_slist_free(bind_text);
+               }
+               return ret;
+       }
+
+       len = snprintf(contact_query, sizeof(contact_query), "UPDATE "CTS_TABLE_CONTACTS" SET changed_ver=%d ", ctsvc_get_next_ver());
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)person, _contacts_person.ringtone_path, CTSVC_PROPERTY_FLAG_DIRTY))
+               len += snprintf(contact_query + len, sizeof(contact_query) - len, ", ringtone_path=? ");
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)person, _contacts_person.vibration, CTSVC_PROPERTY_FLAG_DIRTY))
+               len += snprintf(contact_query + len, sizeof(contact_query) - len, ", vibration=? ");
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)person, _contacts_person.message_alert, CTSVC_PROPERTY_FLAG_DIRTY))
+               len += snprintf(contact_query + len, sizeof(contact_query) - len, ", message_alert=? ");
+       snprintf(contact_query+len, sizeof(contact_query)-len, " WHERE person_id=%d AND deleted = 0", person->person_id);
+
+       ret = ctsvc_query_prepare(contact_query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+               CONTACTS_FREE(set);
+               if (bind_text) {
+                       for (cursor=bind_text;cursor;cursor=cursor->next)
+                               CONTACTS_FREE(cursor->data);
+                       g_slist_free(bind_text);
+               }
+               return ret;
+       }
+
+       i = 1;
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)person, _contacts_person.ringtone_path, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               if (person->ringtone_path)
+                       ctsvc_stmt_bind_text(stmt, i, person->ringtone_path);
+               i++;
+       }
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)person, _contacts_person.vibration, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               if (person->vibration)
+                       ctsvc_stmt_bind_text(stmt, i, person->vibration);
+               i++;
+       }
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)person, _contacts_person.message_alert, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               if (person->message_alert)
+                       ctsvc_stmt_bind_text(stmt, i, person->message_alert);
+               i++;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+               CONTACTS_FREE(set);
+               if (bind_text) {
+                       for (cursor=bind_text;cursor;cursor=cursor->next)
+                               CONTACTS_FREE(cursor->data);
+                       g_slist_free(bind_text);
+               }
+               return ret;
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       // update person display_name
+       if (display_name) {
+               char *temp = NULL;
+               person->display_name = SAFE_STRDUP(display_name);
+               ret = ctsvc_normalize_index(person->display_name, &temp);
+               if (0 <= ret)
+                       person->display_name_index = strdup(temp);
+
+               free(temp);
+               // TODO : update name primary_default??
+       }
+       ctsvc_set_person_noti();
+#ifdef _CONTACTS_IPC_SERVER
+       ctsvc_change_subject_add_changed_person_id(CONTACTS_CHANGE_UPDATED, person->person_id);
+#endif
+
+       ret = ctsvc_end_trans(true);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "DB error : ctsvc_end_trans() Failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_person_delete_record( int id )
+{
+       int ret, rel_changed;
+       int person_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       int version;
+       int *addressbook_ids = NULL;
+       int count;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "SELECT person_id FROM "CTS_TABLE_PERSONS" WHERE person_id = %d", id);
+       ret = ctsvc_query_get_first_int_result(query, &person_id);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       version = ctsvc_get_next_ver();
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_GROUPS" SET member_changed_ver=%d "
+                               "WHERE group_id IN (SELECT distinct group_id "
+                                                                       "FROM "CTS_TABLE_CONTACTS" C, "CTS_TABLE_GROUP_RELATIONS" R "
+                                                                       "ON C.contact_id=R.contact_id AND R.deleted = 0 AND C.deleted = 0 "
+                                                                       "WHERE person_id = %d)",
+                               version, id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       rel_changed = ctsvc_db_change();
+
+       ret = ctsvc_get_write_permitted_addressbook_ids(&addressbook_ids, &count);
+       if (CONTACTS_ERROR_INTERNAL == ret) {
+               CTS_ERR("ctsvc_get_write_permitted_addressbook_ids() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (addressbook_ids && count > 0) {
+               int i;
+               int len = snprintf(query, sizeof(query),
+                               "UPDATE "CTS_TABLE_CONTACTS" SET deleted = 1, person_id = 0, changed_ver = %d "
+                                       "WHERE person_id = %d AND (",
+                               version, id);
+
+               for (i=0;i<count;i++) {
+                       if(i == 0)
+                               len += snprintf(query+len, sizeof(query) + len, "addressbook_id = %d ", addressbook_ids[i]);
+                       else
+                               len += snprintf(query+len, sizeof(query) + len, "OR addressbook_id = %d ", addressbook_ids[i]);
+               }
+               len += snprintf(query+len, sizeof(query)-len, " ) ");
+
+               ret = ctsvc_query_exec(query);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+                       ctsvc_end_trans(false);
+                       free(addressbook_ids);
+                       return ret;
+               }
+       }
+       free(addressbook_ids);
+
+       // access control logic should be enabled
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_CONTACTS" SET person_id = 0, changed_ver = %d WHERE person_id = %d",
+                       version, id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       // images are deleted by db trigger callback function in ctsvc_db_image_delete_callback
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_PERSONS" WHERE person_id = %d", id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_set_contact_noti();
+       ctsvc_set_person_noti();
+       if (rel_changed > 0)
+               ctsvc_set_group_rel_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE) {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_person_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int len;
+       cts_stmt stmt;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_list_h list;
+
+       len = snprintf(query, sizeof(query),
+               "SELECT person_id, "
+                               "%s, "
+                               "_NORMALIZE_INDEX_(%s), "
+                               "name_contact_id, "
+                               "image_thumbnail_path, "
+                               "ringtone_path, "
+                               "vibration, "
+                               "message_alert, "
+                               "status, "
+                               "link_count, "
+                               "addressbook_ids, "
+                               "has_phonenumber, "
+                               "has_email, "
+                               "is_favorite "
+               "FROM "CTSVC_DB_VIEW_PERSON,
+                       ctsvc_get_display_column(), ctsvc_get_sort_name_column());
+
+       len += snprintf(query+len, sizeof(query)-len, " ORDER BY %s", ctsvc_get_sort_column());
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ret = ctsvc_db_person_create_record_from_stmt(stmt, &record);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : ctsvc_db_person_create_record_from_stmt() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_person_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_person_s *person;
+       char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_person._uri, &record);
+               person = (ctsvc_person_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else
+               {
+                       field_count = s_query->projection_count;
+
+                       if( CONTACTS_ERROR_NONE != ctsvc_record_set_projection_flags(record, s_query->projection, s_query->projection_count, s_query->property_count) )
+                       {
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+                       }
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_PERSON_ID:
+                               person->person_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_PERSON_DISPLAY_NAME:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               person->display_name = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               person->display_name_index = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID:
+                               person->name_contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_PERSON_RINGTONE:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               person->ringtone_path = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               if (temp && *temp) {
+                                       snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
+                                       person->image_thumbnail_path = strdup(full_path);
+                               }
+                               break;
+                       case CTSVC_PROPERTY_PERSON_IS_FAVORITE:
+                               person->is_favorite = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER:
+                               person->has_phonenumber = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_PERSON_HAS_EMAIL:
+                               person->has_email = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_PERSON_LINK_COUNT:
+                               person->link_count = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               person->addressbook_ids = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_PERSON_VIBRATION:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               person->vibration = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_PERSON_STATUS:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               person->status = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_PERSON_MESSAGE_ALERT:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               person->message_alert = SAFE_STRDUP(temp);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+#if 0
+static int __ctsvc_db_person_insert_records(const contacts_list_h in_list, int **ids)
+{
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_person_update_records(const contacts_list_h in_list)
+{
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_person_delete_records(int ids[], int count)
+{
+       return CONTACTS_ERROR_NONE;
+}
+#endif
diff --git a/native/ctsvc_db_plugin_person_helper.c b/native/ctsvc_db_plugin_person_helper.c
new file mode 100755 (executable)
index 0000000..fb543b6
--- /dev/null
@@ -0,0 +1,631 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <vconf.h>
+#include <vconf-keys.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_person_helper.h"
+#include "ctsvc_localize.h"
+#include "ctsvc_localize_utils.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+
+#ifdef _CONTACTS_IPC_SERVER
+#include "ctsvc_server_change_subject.h"
+#endif
+
+int ctsvc_db_person_create_record_from_stmt_with_projection(cts_stmt stmt, unsigned int *projection, int projection_count, contacts_record_h *record)
+{
+       ctsvc_person_s *person;
+       char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+
+       contacts_record_create(_contacts_person._uri, record);
+       person = (ctsvc_person_s*)*record;
+
+       int i;
+       for(i=0;i<projection_count;i++) {
+               char *temp;
+               int property_id = projection[i];
+
+               switch(property_id) {
+               case CTSVC_PROPERTY_PERSON_ID:
+                       person->person_id = ctsvc_stmt_get_int(stmt, i);
+                       break;
+               case CTSVC_PROPERTY_PERSON_DISPLAY_NAME:
+                       temp = ctsvc_stmt_get_text(stmt, i);
+                       person->display_name = SAFE_STRDUP(temp);
+                       break;
+               case CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX:
+                       temp = ctsvc_stmt_get_text(stmt, i);
+                       person->display_name_index = SAFE_STRDUP(temp);
+                       break;
+               case CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID:
+                       person->name_contact_id = ctsvc_stmt_get_int(stmt, i);
+                       break;
+               case CTSVC_PROPERTY_PERSON_RINGTONE:
+                       temp = ctsvc_stmt_get_text(stmt, i);
+                       person->ringtone_path = SAFE_STRDUP(temp);
+                       break;
+               case CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL:
+                       temp = ctsvc_stmt_get_text(stmt, i);
+                       if (temp && *temp) {
+                               snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
+                               person->image_thumbnail_path = strdup(full_path);
+                       }
+                       break;
+               case CTSVC_PROPERTY_PERSON_VIBRATION:
+                       temp = ctsvc_stmt_get_text(stmt, i);
+                       person->vibration = SAFE_STRDUP(temp);
+                       break;
+               case CTSVC_PROPERTY_PERSON_MESSAGE_ALERT:
+                       temp = ctsvc_stmt_get_text(stmt, i);
+                       person->message_alert = SAFE_STRDUP(temp);
+                       break;
+               case CTSVC_PROPERTY_PERSON_STATUS:
+                       temp = ctsvc_stmt_get_text(stmt, i);
+                       person->status = SAFE_STRDUP(temp);
+                       break;
+               case CTSVC_PROPERTY_PERSON_IS_FAVORITE:
+                       person->is_favorite = ctsvc_stmt_get_int(stmt, i);
+                       break;
+               case CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER:
+                       person->has_phonenumber = ctsvc_stmt_get_int(stmt, i);
+                       break;
+               case CTSVC_PROPERTY_PERSON_HAS_EMAIL:
+                       person->has_email = ctsvc_stmt_get_int(stmt, i);
+                       break;
+               case CTSVC_PROPERTY_PERSON_LINK_COUNT:
+                       person->link_count = ctsvc_stmt_get_int(stmt, i);
+                       break;
+               case CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS:
+                       temp = ctsvc_stmt_get_text(stmt, i);
+                       person->addressbook_ids = SAFE_STRDUP(temp);
+                       break;
+               case CTSVC_PROPERTY_PERSON_FAVORITE_PRIORITY:
+                       {
+                       // TODO: Fixme (BS)
+                               int value = ctsvc_stmt_get_int(stmt, i);
+                               value++; // fix warning
+                       }
+                       break;
+                       //      ASSERT_NOT_REACHED("Invalid parameter : property_id(0x%0x) is not supported in projection value(person)", property_id);
+                       // return CONTACTS_ERROR_INVALID_PARAMETER;
+               default:
+                       ASSERT_NOT_REACHED("Invalid parameter : property_id(0x%0x) is not supported in value(person)", property_id);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+
+int ctsvc_db_person_create_record_from_stmt_with_query(cts_stmt stmt, contacts_query_h query, contacts_record_h *record)
+{
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       ctsvc_query_s *s_query = (ctsvc_query_s *)query;
+
+       if (0 == s_query->projection_count)
+       {
+               unsigned int *projection = malloc(sizeof(unsigned int)*s_query->property_count);
+               RETVM_IF(NULL == projection, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+               int i;
+               for(i=0;i<s_query->property_count;i++)
+               {
+                       projection[i] = s_query->properties[i].property_id;
+               }
+
+               int ret = ctsvc_db_person_create_record_from_stmt_with_projection(stmt, projection, s_query->property_count, record);
+
+               free(projection);
+
+               return ret;
+       }
+       else
+               return ctsvc_db_person_create_record_from_stmt_with_projection(stmt, s_query->projection, s_query->projection_count, record);
+
+}
+
+int ctsvc_db_person_create_record_from_stmt(cts_stmt stmt, contacts_record_h *record)
+{
+       int ret;
+       int i;
+       char *temp;
+       ctsvc_person_s *person;
+
+       i = 0;
+       ret = contacts_record_create(_contacts_person._uri, record);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+       person = (ctsvc_person_s *)*record;
+       person->person_id = ctsvc_stmt_get_int(stmt, i++);
+
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       person->display_name = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       person->display_name_index = SAFE_STRDUP(temp);
+       person->name_contact_id = ctsvc_stmt_get_int(stmt, i++);
+
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       if (temp && *temp) {
+               char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+               snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
+               person->image_thumbnail_path = strdup(full_path);
+       }
+
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       person->ringtone_path = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       person->vibration = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       person->message_alert = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       person->status = SAFE_STRDUP(temp);
+
+       person->link_count = ctsvc_stmt_get_int(stmt, i++);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       person->addressbook_ids = SAFE_STRDUP(temp);
+
+       person->has_phonenumber = ctsvc_stmt_get_int(stmt, i++);
+       person->has_email = ctsvc_stmt_get_int(stmt, i++);
+       person->is_favorite = ctsvc_stmt_get_int(stmt, i++);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+inline static const char* __ctsvc_get_image_filename(const char* src)
+{
+       const char* dir = CTSVC_CONTACT_IMG_FULL_LOCATION;
+       int pos=0;
+       while (dir[pos]==src[pos]) {
+               pos++;
+       }
+
+       if ('/' == src[pos])
+               return src + pos + 1;
+
+       return src+pos;
+}
+
+int ctsvc_db_person_set_favorite(int person_id, bool set, bool propagate)
+{
+       int ret;
+       double prio = 0.0;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       if (set) {
+               snprintf(query, sizeof(query),
+                       "SELECT MAX(favorite_prio) FROM "CTS_TABLE_FAVORITES);
+
+               ret = ctsvc_query_prepare(query, &stmt);
+               RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+               ret = ctsvc_stmt_step(stmt);
+               if (1 /*CTS_TRUE*/ == ret) {
+                       prio = ctsvc_stmt_get_dbl(stmt, 0);
+               }
+               else if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       return ret;
+               }
+               ctsvc_stmt_finalize(stmt);
+
+               prio = prio + 1.0;
+               snprintf(query, sizeof(query),
+                       "INSERT OR REPLACE INTO "CTS_TABLE_FAVORITES" values(%d, %f)", person_id, prio);
+       }
+       else {
+               snprintf(query, sizeof(query),
+                       "DELETE FROM "CTS_TABLE_FAVORITES" WHERE person_id = %d", person_id);
+       }
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               return ret;
+       }
+
+       if (propagate) {
+               snprintf(query, sizeof(query),
+                               "UPDATE "CTS_TABLE_CONTACTS" SET is_favorite = %d "
+                                       "WHERE person_id=%d AND deleted = 0", set?1:0, person_id);
+               ret = ctsvc_query_exec(query);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_insert_person(contacts_record_h record)
+{
+       int ret, index;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+       int version;
+       ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
+       char *status = NULL;
+
+       snprintf(query, sizeof(query),
+               "SELECT status FROM %s "
+               "WHERE contact_id=%d "
+               "ORDER BY timestamp DESC LIMIT 1",
+               CTS_TABLE_ACTIVITIES, contact->id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       if (1 == ctsvc_stmt_step(stmt))
+               status = SAFE_STRDUP(ctsvc_stmt_get_text(stmt, 0));
+       ctsvc_stmt_finalize(stmt);
+
+       version = ctsvc_get_next_ver();
+       snprintf(query, sizeof(query),
+               "INSERT INTO "CTS_TABLE_PERSONS"(name_contact_id, created_ver, changed_ver, "
+                       "has_phonenumber, has_email, ringtone_path, vibration, message_alert, status, "
+                       "image_thumbnail_path, link_count, addressbook_ids) "
+                       "VALUES(%d, %d, %d, %d, %d, ?, ?, ?, ?, ?, 1, '%d') ",
+                       contact->id, version, version,
+                       contact->has_phonenumber, contact->has_email, contact->addressbook_id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               free(status);
+               return ret;
+       }
+       if(contact->ringtone_path)
+               ctsvc_stmt_bind_text(stmt, 1, contact->ringtone_path);
+       if(contact->vibration)
+               ctsvc_stmt_bind_text(stmt, 2, contact->vibration);
+       if(contact->message_alert)
+               ctsvc_stmt_bind_text(stmt, 3, contact->message_alert);
+       if(status)
+               ctsvc_stmt_bind_text(stmt, 4, status);
+       if(contact->image_thumbnail_path)
+               ctsvc_stmt_bind_text(stmt, 5, __ctsvc_get_image_filename(contact->image_thumbnail_path));
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               free(status);
+               return ret;
+       }
+       index = ctsvc_db_get_last_insert_id();
+
+       ctsvc_stmt_finalize(stmt);
+
+       snprintf(query, sizeof(query),
+               "UPDATE "CTS_TABLE_DATA" SET is_primary_default = 1 "
+                       "WHERE is_default = 1 AND contact_id = %d  AND is_my_profile = 0", contact->id);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec Failed(%d)", ret);
+               free(status);
+               return ret;
+       }
+
+       // set favorite
+       if (contact->is_favorite) {
+               ret = ctsvc_db_person_set_favorite(index, contact->is_favorite, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_db_person_set_favorite() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       free(status);
+       ctsvc_set_person_noti();
+#ifdef _CONTACTS_IPC_SERVER
+       ctsvc_change_subject_add_changed_person_id(CONTACTS_CHANGE_INSERTED, index);
+#endif
+
+       return index;
+}
+
+static inline int __ctsvc_db_update_person_default(int person_id, int datatype)
+{
+       int ret, data_id;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+       char *temp = NULL;
+       char *image_thumbnail_path = NULL;
+
+       snprintf(query, sizeof(query),
+               "SELECT D.id FROM "CTS_TABLE_CONTACTS" C, "CTS_TABLE_DATA" D "
+               "ON C.contact_id = D.contact_id AND C.deleted = 0 "
+               "WHERE C.person_id=%d AND D.datatype=%d AND is_primary_default=1 AND D.is_my_profile = 0",
+               person_id, datatype);
+
+       ret = ctsvc_query_get_first_int_result(query, &data_id);
+       if (CONTACTS_ERROR_NO_DATA == ret ) {
+               snprintf(query, sizeof(query),
+                       "SELECT D.id, D.data3 FROM "CTS_TABLE_CONTACTS" C, "CTS_TABLE_DATA" D "
+                       "ON C.contact_id = D.contact_id AND C.deleted = 0 "
+                       "WHERE C.person_id=%d AND D.datatype=%d AND D.is_default=1 AND D.is_my_profile = 0 ORDER BY D.id",
+                       person_id, datatype);
+
+               ret = ctsvc_query_prepare(query, &stmt);
+               RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+               ret = ctsvc_stmt_step(stmt);
+               if (1 == ret) {
+                       data_id = ctsvc_stmt_get_int(stmt, 0);
+
+                       snprintf(query, sizeof(query),
+                                       "UPDATE "CTS_TABLE_DATA" SET is_primary_default=1 WHERE id=%d"
+                                       ,data_id);
+
+                       ret = ctsvc_query_exec(query);
+                       if (CONTACTS_ERROR_NONE != ret) {
+                               CTS_ERR("ctsvc_query_exec Failed(%d)", ret);
+                               ctsvc_stmt_finalize(stmt);
+                               return ret;
+                       }
+                       temp = ctsvc_stmt_get_text(stmt, 1);
+                       image_thumbnail_path = SAFE_STRDUP(temp);
+               }
+               ctsvc_stmt_finalize(stmt);
+
+               if (CTSVC_DATA_IMAGE == datatype) {
+                       if (image_thumbnail_path) {
+                               snprintf(query, sizeof(query),
+                                               "UPDATE "CTS_TABLE_PERSONS" SET image_thumbnail_path=? WHERE person_id=%d", person_id);
+                               ret = ctsvc_query_prepare(query, &stmt);
+                               RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+                               ctsvc_stmt_bind_text(stmt, 1, image_thumbnail_path);
+                               ret = ctsvc_stmt_step(stmt);
+                               ctsvc_stmt_finalize(stmt);
+                               free(image_thumbnail_path);
+                               if (CONTACTS_ERROR_NONE != ret) {
+                                       CTS_ERR("ctsvc_stmt_step Failed(%d)", ret);
+                                       return ret;
+                               }
+                       }
+               }
+               else {
+                       free(image_thumbnail_path);
+               }
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static bool __ctsvc_get_has_column(int person_id, const char *culumn)
+{
+       int ret;
+       int contact_count = 0;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                               "SELECT count(contact_id) FROM "CTS_TABLE_CONTACTS" "
+                               "WHERE person_id=%d AND %s=1 AND deleted = 0",
+                               person_id, culumn);
+
+       ret = ctsvc_query_get_first_int_result(query, &contact_count);
+       RETV_IF(CONTACTS_ERROR_NONE != ret, false);
+
+       if (contact_count)
+               return true;
+       return false;
+}
+
+static int __ctsvc_get_thumbnail_contact_id(int person_id)
+{
+       int ret;
+       int contact_id = 0;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "SELECT D.contact_id FROM "CTS_TABLE_CONTACTS" C, "CTS_TABLE_DATA" D "
+                       "ON C.contact_id = D.contact_id AND C.deleted = 0 "
+                       "WHERE C.person_id=%d AND D.datatype=%d AND is_primary_default=1 AND D.is_my_profile = 0",
+                       person_id, CTSVC_DATA_IMAGE);
+       ret = ctsvc_query_get_first_int_result(query, &contact_id);
+       RETV_IF(CONTACTS_ERROR_NONE != ret, -1);
+       return contact_id;
+}
+
+int ctsvc_db_update_person(contacts_record_h record)
+{
+       int ret, i=1, len=0;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+       ctsvc_contact_s *contact = (ctsvc_contact_s*)record;
+       bool has_phonenumber=false, has_email=false;
+       int thumbnail_contact_id = 0;
+       int person_id = 0;
+       int is_favorite = 0;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       __ctsvc_db_update_person_default(contact->person_id, CTSVC_DATA_NUMBER);
+       __ctsvc_db_update_person_default(contact->person_id, CTSVC_DATA_EMAIL);
+       __ctsvc_db_update_person_default(contact->person_id, CTSVC_DATA_IMAGE);
+
+       has_phonenumber = __ctsvc_get_has_column(contact->person_id, "has_phonenumber");
+       has_email = __ctsvc_get_has_column(contact->person_id, "has_email");
+       thumbnail_contact_id = __ctsvc_get_thumbnail_contact_id(contact->person_id);
+
+       len = snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_PERSONS" SET changed_ver=%d, has_phonenumber=%d, has_email=%d ",
+                       ctsvc_get_next_ver(), has_phonenumber, has_email);
+
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_contact.ringtone_path, CTSVC_PROPERTY_FLAG_DIRTY))
+               len += snprintf(query+len, sizeof(query)-len, ", ringtone_path=?");
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_contact.vibration, CTSVC_PROPERTY_FLAG_DIRTY))
+               len += snprintf(query+len, sizeof(query)-len, ", vibration=?");
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_contact.message_alert, CTSVC_PROPERTY_FLAG_DIRTY))
+               len += snprintf(query+len, sizeof(query)-len, ", message_alert=?");
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY) &&
+                       (contact->id == thumbnail_contact_id || thumbnail_contact_id == -1))
+               len += snprintf(query+len, sizeof(query)-len, ", image_thumbnail_path=?");
+
+       snprintf(query+len, sizeof(query)-len,
+                       " WHERE person_id=%d", contact->person_id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_contact.ringtone_path, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               if (contact->ringtone_path)
+                       ctsvc_stmt_bind_text(stmt, i, contact->ringtone_path);
+               i++;
+       }
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_contact.vibration, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               if (contact->vibration)
+                       ctsvc_stmt_bind_text(stmt, i, contact->vibration);
+               i++;
+       }
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_contact.message_alert, CTSVC_PROPERTY_FLAG_DIRTY)) {
+               if (contact->message_alert)
+                       ctsvc_stmt_bind_text(stmt, i, contact->message_alert);
+               i++;
+       }
+       if (ctsvc_record_check_property_flag((ctsvc_record_s *)record, _contacts_contact.image_thumbnail_path, CTSVC_PROPERTY_FLAG_DIRTY) &&
+                       (contact->id == thumbnail_contact_id || thumbnail_contact_id == -1)) {
+               if (contact->image_thumbnail_path)
+                       ctsvc_stmt_bind_text(stmt, i, contact->image_thumbnail_path);
+               i++;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       // update favorite
+       snprintf(query, sizeof(query),
+                       "SELECT is_favorite FROM "CTS_TABLE_CONTACTS" WHERE contact_id =%d ", contact->id);
+       ret = ctsvc_query_get_first_int_result(query, &is_favorite);
+       if (ret < CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_query_get_first_int_result() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT person_id FROM "CTS_TABLE_FAVORITES" WHERE person_id =%d ", contact->person_id);
+       ret = ctsvc_query_get_first_int_result(query, &person_id);
+       if (CONTACTS_ERROR_NO_DATA == ret && is_favorite) {
+               ret = ctsvc_db_person_set_favorite(contact->person_id, true, false);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_db_person_set_favorite() Failed(%d)", ret);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+       }
+       else if (CONTACTS_ERROR_NONE == ret && !is_favorite) {
+               snprintf(query, sizeof(query),
+                       "SELECT person_id FROM "CTS_TABLE_CONTACTS" WHERE person_id =%d AND is_favorite = 1", contact->person_id);
+               ret = ctsvc_query_get_first_int_result(query, &person_id);
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       ret = ctsvc_db_person_set_favorite(contact->person_id, false, false);
+                       if (CONTACTS_ERROR_NONE != ret) {
+                               CTS_ERR("ctsvc_db_person_set_favorite() Failed(%d)", ret);
+                               ctsvc_end_trans(false);
+                               return ret;
+                       }
+               }
+               else if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_query_get_first_int_result() Failed(%d)", ret);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+       }
+       else if (ret < CONTACTS_ERROR_NONE && CONTACTS_ERROR_NO_DATA != ret) {
+               CTS_ERR("ctsvc_query_get_first_int_result() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_set_person_noti();
+
+#ifdef _CONTACTS_IPC_SERVER
+       ctsvc_change_subject_add_changed_person_id(CONTACTS_CHANGE_UPDATED, contact->person_id);
+#endif
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+// This function will return group letter of the person
+void ctsvc_db_normalize_str_callback(sqlite3_context * context,
+               int argc, sqlite3_value ** argv)
+{
+       const char *display_name;
+       int display_name_language = CTSVC_LANG_OTHERS;
+
+       if (argc < 1) {
+               sqlite3_result_null(context);
+               return;
+       }
+
+       display_name_language = sqlite3_value_int(argv[1]);
+       if (display_name_language == CTSVC_SORT_OTHERS || display_name_language == CTSVC_SORT_NUMBER) {
+               sqlite3_result_text(context, "#", 1, SQLITE_TRANSIENT);
+               return;
+       }
+       else {
+               display_name = (const char *)sqlite3_value_text(argv[0]);
+               if (display_name) {
+                       int ret;
+                       char *dest = NULL;
+                       ret = ctsvc_normalize_index(display_name, &dest);
+                       if (ret < CONTACTS_ERROR_NONE) {
+                               CTS_ERR("ctsvc_normalize_index() Failed(%d)", ret);
+                               sqlite3_result_null(context);
+                               return;
+                       }
+                       sqlite3_result_text(context, dest, strlen(dest), SQLITE_TRANSIENT);
+                       free(dest);
+                       return;
+               }
+       }
+
+       sqlite3_result_null(context);
+       return;
+}
+
diff --git a/native/ctsvc_db_plugin_person_helper.h b/native/ctsvc_db_plugin_person_helper.h
new file mode 100755 (executable)
index 0000000..40efc68
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_PERSON_HELPER_H__
+#define __CTSVC_DB_PLUGIN_PERSON_HELPER_H__
+
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
+
+#define ADDRESSBOOK_ID_DELIM   " "
+
+int ctsvc_db_insert_person(contacts_record_h contact);
+int ctsvc_db_update_person(contacts_record_h contact);
+int ctsvc_db_person_create_record_from_stmt(cts_stmt stmt, contacts_record_h *record);
+int ctsvc_db_person_create_record_from_stmt_with_query(cts_stmt stmt, contacts_query_h query, contacts_record_h *record);
+int ctsvc_db_person_create_record_from_stmt_with_projection(cts_stmt stmt, unsigned int *projection, int projection_count, contacts_record_h *record);
+void ctsvc_db_normalize_str_callback(sqlite3_context * context,        int argc, sqlite3_value ** argv);
+int ctsvc_db_person_set_favorite(int person_id, bool set, bool propagate);
+
+#endif // __CTSVC_DB_PLUGIN_PERSON_HELPER_H__
diff --git a/native/ctsvc_db_plugin_phonelog.c b/native/ctsvc_db_plugin_phonelog.c
new file mode 100644 (file)
index 0000000..8f372b9
--- /dev/null
@@ -0,0 +1,523 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_number_utils.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_list.h"
+#include "ctsvc_record.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_setting.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_localize_utils.h"
+#include "ctsvc_phonelog.h"
+
+#ifdef _CONTACTS_IPC_SERVER
+#include "ctsvc_server_change_subject.h"
+#ifdef ENABLE_SIM_FEATURE
+#include "ctsvc_server_sim.h"
+#include "ctsvc_server_utils.h"
+#endif // ENABLE_SIM_FEATURE
+#endif
+
+static int __ctsvc_db_phonelog_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_phonelog_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_phonelog_update_record( contacts_record_h record );
+static int __ctsvc_db_phonelog_delete_record( int id );
+static int __ctsvc_db_phonelog_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_phonelog_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_phonelog_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_phonelog_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_phonelog_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_phonelog = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_phonelog_insert_record,
+       .get_record = __ctsvc_db_phonelog_get_record,
+       .update_record = __ctsvc_db_phonelog_update_record,
+       .delete_record = __ctsvc_db_phonelog_delete_record,
+       .get_all_records = __ctsvc_db_phonelog_get_all_records,
+       .get_records_with_query = __ctsvc_db_phonelog_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_phonelog_insert_records,
+       .update_records = NULL,//__ctsvc_db_phonelog_update_records,
+       .delete_records = NULL,//__ctsvc_db_phonelog_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_phonelog_value_set(cts_stmt stmt, contacts_record_h *record)
+{
+       int i;
+       int ret;
+       char *temp;
+       ctsvc_phonelog_s *phonelog;
+
+       ret = contacts_record_create(_contacts_phone_log._uri, record);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+       phonelog = (ctsvc_phonelog_s*)*record;
+
+       i = 0;
+       phonelog->id = ctsvc_stmt_get_int(stmt, i++);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       phonelog->address = SAFE_STRDUP(temp);
+       phonelog->person_id = ctsvc_stmt_get_int(stmt, i++);
+       phonelog->log_type = ctsvc_stmt_get_int(stmt, i++);
+       phonelog->log_time = ctsvc_stmt_get_int(stmt, i++);
+       phonelog->extra_data1 = ctsvc_stmt_get_int(stmt, i++);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       phonelog->extra_data2 = SAFE_STRDUP(temp);
+#ifdef _CONTACTS_IPC_SERVER
+#ifdef ENABLE_SIM_FEATURE
+       phonelog->sim_slot_no = ctsvc_server_sim_get_sim_slot_no_by_info_id(ctsvc_stmt_get_int(stmt, i++));
+#endif // ENABLE_SIM_FEATURE
+#endif
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_phonelog_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_record_h record;
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT id, number, person_id, log_type, log_time, data1, data2, sim_id "
+                       "FROM "CTS_TABLE_PHONELOGS" WHERE id = %d", id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ret = __ctsvc_db_phonelog_value_set(stmt, &record);
+
+       ctsvc_stmt_finalize(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_db_phonelog_value_set(ALL) Failed(%d)", ret);
+               return ret;
+       }
+
+       *out_record = record;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_phonelog_update_record( contacts_record_h record )
+{
+       int phonelog_id;
+       char query[CTS_SQL_MIN_LEN] = {0};
+       ctsvc_phonelog_s *phonelog = (ctsvc_phonelog_s *)record;
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+
+       RETVM_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : record is null");
+       RETVM_IF(phonelog->id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : The phone_log has ID(%d)", phonelog->id);
+       RETVM_IF(phonelog->log_type != CONTACTS_PLOG_TYPE_VOICE_INCOMMING_SEEN &&
+                       phonelog->log_type != CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : the type is can not updated(%d)", phonelog->log_type);
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (phonelog->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_PHONELOGS" WHERE id = %d", phonelog->id);
+       ret = ctsvc_query_get_first_int_result(query, &phonelog_id);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_PHONELOGS, phonelog->id))) break;
+
+               if (ctsvc_db_change()) {
+                       ctsvc_set_phonelog_noti();
+
+#ifdef _CONTACTS_IPC_SERVER
+                       ctsvc_change_subject_add_changed_phone_log_id(CONTACTS_CHANGE_UPDATED, phonelog->id);
+#endif
+               }
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       ret = ctsvc_end_trans(true);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "DB error : ctsvc_end_trans() Failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_phonelog_delete_record( int id )
+{
+       int ret;
+       int phonelog_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_PHONELOGS" WHERE id = %d", id);
+       ret = ctsvc_query_get_first_int_result(query, &phonelog_id);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE id = %d",
+                       CTS_TABLE_PHONELOGS, id);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_set_phonelog_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_phonelog_get_all_records( int offset, int limit,
+               contacts_list_h* out_list )
+{
+       int ret;
+       int len;
+       cts_stmt stmt;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_list_h list;
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT id, number, person_id, log_type, log_time, data1, data2, sim_id "
+                                       "FROM "CTS_TABLE_PHONELOGS);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               __ctsvc_db_phonelog_value_set(stmt, &record);
+
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_phonelog_get_records_with_query( contacts_query_h query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_phonelog_s *phonelog;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_phone_log._uri, &record);
+               phonelog = (ctsvc_phonelog_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else
+               {
+                       field_count = s_query->projection_count;
+
+                       if( CONTACTS_ERROR_NONE != ctsvc_record_set_projection_flags(record, s_query->projection, s_query->projection_count, s_query->property_count) )
+                       {
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+                       }
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_PHONELOG_ID:
+                               phonelog->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_PHONELOG_PERSON_ID:
+                               phonelog->person_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_PHONELOG_ADDRESS:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               phonelog->address = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_PHONELOG_LOG_TIME:
+                               phonelog->log_time = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_PHONELOG_LOG_TYPE:
+                               phonelog->log_type = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_PHONELOG_EXTRA_DATA1:
+                               phonelog->extra_data1 = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_PHONELOG_EXTRA_DATA2:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               phonelog->extra_data2 = SAFE_STRDUP(temp);
+                               break;
+#ifdef ENABLE_SIM_FEATURE
+                       case CTSVC_PROPERTY_PHONELOG_SIM_SLOT_NO:
+                               phonelog->sim_slot_no = ctsvc_server_sim_get_sim_slot_no_by_info_id(ctsvc_stmt_get_int(stmt, i));
+                               break;
+#endif // ENABLE_SIM_FEATURE
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+
+       return CONTACTS_ERROR_NONE;
+}
+//static int __ctsvc_db_phonelog_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_phonelog_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_phonelog_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
+
+static int __ctsvc_db_phonelog_increase_outgoing_count(ctsvc_phonelog_s *phonelog)
+{
+       int ret;
+       int id;
+       int type = CONTACTS_USAGE_STAT_TYPE_NONE;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       if (phonelog->log_type == CONTACTS_PLOG_TYPE_VOICE_OUTGOING ||
+               phonelog->log_type == CONTACTS_PLOG_TYPE_VIDEO_OUTGOING)
+               type = CONTACTS_USAGE_STAT_TYPE_OUTGOING_CALL;
+       else if (phonelog->log_type == CONTACTS_PLOG_TYPE_MMS_OUTGOING ||
+               phonelog->log_type == CONTACTS_PLOG_TYPE_SMS_OUTGOING)
+               type = CONTACTS_USAGE_STAT_TYPE_OUTGOING_MSG;
+       else
+               return CONTACTS_ERROR_NONE;
+
+       snprintf(query, sizeof(query),
+                       "SELECT person_id FROM %s WHERE person_id = %d and usage_type = %d ",
+                       CTS_TABLE_CONTACT_STAT, phonelog->person_id, type);
+
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       if (CONTACTS_ERROR_NO_DATA == ret) {
+               snprintf(query, sizeof(query),
+                               "INSERT INTO %s(person_id, usage_type, times_used) VALUES(%d, %d, 1)",
+                               CTS_TABLE_CONTACT_STAT, phonelog->person_id, type);
+       }
+       else {
+               snprintf(query, sizeof(query),
+                               "UPDATE %s SET times_used = times_used + 1 WHERE person_id = %d and usage_type = %d",
+                               CTS_TABLE_CONTACT_STAT, phonelog->person_id, type);
+       }
+
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int  __ctsvc_db_phonelog_insert(ctsvc_phonelog_s *phonelog, int *id)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF((phonelog->log_type < CONTACTS_PLOG_TYPE_NONE
+                       || CONTACTS_PLOG_TYPE_EMAIL_SENT < phonelog->log_type)
+                       , CONTACTS_ERROR_INVALID_PARAMETER, "phonelog type(%d) is invaid", phonelog->log_type);
+
+       snprintf(query, sizeof(query), "INSERT INTO "CTS_TABLE_PHONELOGS"("
+                       "number, normal_num, minmatch, clean_num, person_id, log_type,log_time, data1, data2, sim_id) "
+                       "VALUES(?, ?, ?, ?, ?, %d, %d, %d, ?, ?)",
+                       phonelog->log_type, phonelog->log_time, phonelog->extra_data1);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       if (phonelog->address) {
+               ctsvc_stmt_bind_text(stmt, 1, phonelog->address);
+               if (phonelog->log_type < CONTACTS_PLOG_TYPE_EMAIL_RECEIVED) {
+                       char clean_num[strlen(phonelog->address) + 1];
+                       ret = ctsvc_clean_number(phonelog->address, clean_num, sizeof(clean_num), true);
+                       if (0 < ret) {
+                               char normal_num[sizeof(clean_num) + 20];
+                               ctsvc_stmt_bind_copy_text(stmt, 4, clean_num, strlen(clean_num));
+                               ret = ctsvc_normalize_number(clean_num, normal_num, sizeof(normal_num), true);
+                               if (0 < ret) {
+                                       char minmatch[sizeof(normal_num) + 1];
+                                       ctsvc_stmt_bind_copy_text(stmt, 2, normal_num, strlen(normal_num));
+                                       ret = ctsvc_get_minmatch_number(normal_num, minmatch, sizeof(minmatch), ctsvc_get_phonenumber_min_match_digit());
+                                       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_get_minmatch_number() Fail(%d)", ret);
+                                       ctsvc_stmt_bind_copy_text(stmt, 3, minmatch, strlen(minmatch));
+                               }
+                       }
+               }
+       }
+
+       if (0 < phonelog->person_id)
+               ctsvc_stmt_bind_int(stmt, 5, phonelog->person_id);
+
+       if (phonelog->extra_data2)
+               ctsvc_stmt_bind_text(stmt, 6, phonelog->extra_data2);
+
+#ifdef ENABLE_SIM_FEATURE
+       if (phonelog->sim_slot_no >= 0) {
+               int sim_info_id;
+               sim_info_id = ctsvc_server_sim_get_info_id_by_sim_slot_no(phonelog->sim_slot_no);
+               if (sim_info_id > 0)
+                       ctsvc_stmt_bind_int(stmt, 7, sim_info_id);
+       }
+       else
+#endif // ENABLE_SIM_FEATURE
+               ctsvc_stmt_bind_int(stmt, 7, -1);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+       if (id)
+               *id = ctsvc_db_get_last_insert_id();
+       ctsvc_stmt_finalize(stmt);
+
+       // update phonelog
+       ctsvc_db_phone_log_update_person_id(phonelog->address, phonelog->person_id, -1, false);
+
+       ctsvc_set_phonelog_noti();
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_phonelog_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       ctsvc_phonelog_s *phonelog = (ctsvc_phonelog_s *)record;
+
+       RETVM_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : record is null");
+       RETVM_IF(phonelog->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : The phone_log has ID(%d)", phonelog->id);
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       ret = __ctsvc_db_phonelog_insert(phonelog, id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_db_phonelog_insert() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (0 < phonelog->person_id) {
+               ret = __ctsvc_db_phonelog_increase_outgoing_count(phonelog);
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "__ctsvc_db_phonelog_increase_outgoing_count() Failed(%d)", ret);
+       }
+
+#ifdef _CONTACTS_IPC_SERVER
+       // add id for subscribe
+       ctsvc_change_subject_add_changed_phone_log_id(CONTACTS_CHANGE_INSERTED, *id);
+#endif
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE) {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/native/ctsvc_db_plugin_profile.c b/native/ctsvc_db_plugin_profile.c
new file mode 100644 (file)
index 0000000..b0d6cb7
--- /dev/null
@@ -0,0 +1,432 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_db_plugin_profile_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_list.h"
+#include "ctsvc_notification.h"
+
+static int __ctsvc_db_profile_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_profile_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_profile_update_record( contacts_record_h record );
+static int __ctsvc_db_profile_delete_record( int id );
+static int __ctsvc_db_profile_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_profile_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_profile_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_profile_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_profile_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_profile = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_profile_insert_record,
+       .get_record = __ctsvc_db_profile_get_record,
+       .update_record = __ctsvc_db_profile_update_record,
+       .delete_record = __ctsvc_db_profile_delete_record,
+       .get_all_records = __ctsvc_db_profile_get_all_records,
+       .get_records_with_query = __ctsvc_db_profile_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_profile_insert_records,
+       .update_records = NULL,//__ctsvc_db_profile_update_records,
+       .delete_records = NULL,//__ctsvc_db_profile_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_profile_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_profile_s *profile = (ctsvc_profile_s *)record;
+
+       RETVM_IF(NULL == profile->text, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : profile text is NULL");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", profile->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       CTS_ERR("No data : contact_id (%d) is not exist", profile->contact_id);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               else {
+                       CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this profile record : addressbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_profile_insert(record, profile->contact_id, false, id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(profile->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_profile_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, "
+                               "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE id = %d AND datatype = %d ",
+                               id, CTSVC_DATA_PROFILE);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ctsvc_db_profile_get_value_from_stmt(stmt, out_record, 0);
+
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_profile_update_record( contacts_record_h record )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_profile_s *profile = (ctsvc_profile_s *)record;
+       RETVM_IF(NULL == profile->text, CONTACTS_ERROR_INVALID_PARAMETER, "profile text is empty");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", profile->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : contact_id (%d) is not exist", profile->contact_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this profile record : addressbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_profile_update(record, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("Update record Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(profile->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_profile_delete_record( int id )
+{
+       int ret;
+       int contact_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt = NULL;
+       int addressbook_id;
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
+                               "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare Fail(%d", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("The id(%d) is Invalid(%d)", id, ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       contact_id = ctsvc_stmt_get_int(stmt, 0);
+       addressbook_id = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this profile record : addressbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_profile_delete(id, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_profile_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int len;
+       int ret;
+       contacts_list_h list;
+       ctsvc_profile_s *profile;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, "
+                               "data3, data4, data5, data6, data7, data8, data9, data10, data11 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE datatype = %d AND is_my_profile=0 ",
+                               CTSVC_DATA_PROFILE);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB : ctsvc_stmt_step fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_db_profile_get_value_from_stmt(stmt, (contacts_record_h*)&profile, 0);
+               ctsvc_list_prepend(list, (contacts_record_h)profile);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_profile_get_records_with_query( contacts_query_h query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_profile_s *profile;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_profile._uri, &record);
+               profile = (ctsvc_profile_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if(CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_PROFILE_ID:
+                               profile->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_PROFILE_CONTACT_ID:
+                               profile->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_PROFILE_UID:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               profile->uid = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_PROFILE_TEXT:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               profile->text = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_PROFILE_ORDER:
+                               profile->order = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_PROFILE_SERVICE_OPERATION:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               profile->service_operation = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_PROFILE_MIME:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               profile->mime = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_PROFILE_APP_ID:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               profile->app_id = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_PROFILE_URI:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               profile->uri = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_PROFILE_CATEGORY:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               profile->category = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_PROFILE_EXTRA_DATA:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               profile->extra_data = SAFE_STRDUP(temp);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_profile_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_profile_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_profile_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_profile_helper.c b/native/ctsvc_db_plugin_profile_helper.c
new file mode 100644 (file)
index 0000000..7a19f40
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_plugin_profile_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+
+
+int ctsvc_db_profile_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count)
+{
+       int ret;
+       char *temp;
+       ctsvc_profile_s *profile;
+
+       ret = contacts_record_create(_contacts_profile._uri, (contacts_record_h *)&profile);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+
+       profile->id = ctsvc_stmt_get_int(stmt, start_count++);
+       profile->contact_id = ctsvc_stmt_get_int(stmt, start_count++);
+       start_count++;
+       start_count++;
+       start_count++;
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       profile->uid = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       profile->text = SAFE_STRDUP(temp);
+       profile->order = ctsvc_stmt_get_int(stmt, start_count++);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       profile->service_operation = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       profile->mime = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       profile->app_id = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       profile->uri = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       profile->category = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       profile->extra_data = SAFE_STRDUP(temp);
+
+       *record = (contacts_record_h)profile;
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_profile_bind_stmt(cts_stmt stmt, ctsvc_profile_s *profile, int start_cnt)
+{
+       if (profile->uid)
+               ctsvc_stmt_bind_text(stmt, start_cnt, profile->uid);
+       if (profile->text)
+               ctsvc_stmt_bind_text(stmt, start_cnt+1, profile->text);
+       ctsvc_stmt_bind_int(stmt, start_cnt+2, profile->order);
+       if (profile->service_operation)
+               ctsvc_stmt_bind_text(stmt, start_cnt+3, profile->service_operation);
+       if (profile->mime)
+               ctsvc_stmt_bind_text(stmt, start_cnt+4, profile->mime);
+       if (profile->app_id)
+               ctsvc_stmt_bind_text(stmt, start_cnt+5, profile->app_id);
+       if (profile->uri)
+               ctsvc_stmt_bind_text(stmt, start_cnt+6, profile->uri);
+       if (profile->category)
+               ctsvc_stmt_bind_text(stmt, start_cnt+7, profile->category);
+       if (profile->extra_data)
+               ctsvc_stmt_bind_text(stmt, start_cnt+8, profile->extra_data);
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_profile_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_profile_s *profile = (ctsvc_profile_s *)record;
+
+       RETV_IF(NULL == profile->text, CONTACTS_ERROR_NONE);
+       RETVM_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : contact_id(%d) is mandatory field to insert profile record ", profile->contact_id);
+       RETVM_IF(0 < profile->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", profile->id);
+
+       snprintf(query, sizeof(query),
+               "INSERT INTO "CTS_TABLE_DATA"(contact_id, is_my_profile, datatype, data3, data4, data5, "
+                               "data6, data7, data8, data9, data10, data11) "
+                               "VALUES(%d, %d, %d, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+                               contact_id, is_my_profile, CTSVC_DATA_PROFILE);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       __ctsvc_profile_bind_stmt(stmt, profile, 1);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+
+       //profile->id = ctsvc_db_get_last_insert_id();
+       if (id)
+               *id = ctsvc_db_get_last_insert_id();
+       ctsvc_stmt_finalize(stmt);
+
+       if (!is_my_profile)
+               ctsvc_set_profile_noti();
+
+       return CONTACTS_ERROR_NONE;
+
+}
+
+int ctsvc_db_profile_update(contacts_record_h record, bool is_my_profile)
+{
+       int id;
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       ctsvc_profile_s *profile = (ctsvc_profile_s*)record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(!profile->id, CONTACTS_ERROR_INVALID_PARAMETER, "profile of contact has no ID.");
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE id = %d", profile->id);
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       RETV_IF(ret != CONTACTS_ERROR_NONE, ret);
+
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (profile->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_DATA, profile->id))) break;
+               if (!is_my_profile)
+                       ctsvc_set_profile_noti();
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       return ret;
+}
+
+
+int ctsvc_db_profile_delete(int id, bool is_my_profile)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE id = %d AND datatype = %d",
+                       id, CTSVC_DATA_PROFILE);
+
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_exec() Failed(%d)", ret);
+
+       if (!is_my_profile)
+               ctsvc_set_profile_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/native/ctsvc_db_plugin_profile_helper.h b/native/ctsvc_db_plugin_profile_helper.h
new file mode 100644 (file)
index 0000000..8c05e49
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_PROFILE_HELPER_H__
+#define __CTSVC_DB_PLUGIN_PROFILE_HELPER_H__
+
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
+
+int ctsvc_db_profile_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id);
+int ctsvc_db_profile_update(contacts_record_h record, bool is_my_profile);
+int ctsvc_db_profile_delete(int id, bool is_my_profile);
+int ctsvc_db_profile_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count);
+
+#endif // __CTSVC_DB_PLUGIN_PROFILE_HELPER_H__
diff --git a/native/ctsvc_db_plugin_relationship.c b/native/ctsvc_db_plugin_relationship.c
new file mode 100644 (file)
index 0000000..4684101
--- /dev/null
@@ -0,0 +1,407 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_relationship_helper.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_list.h"
+#include "ctsvc_notification.h"
+
+
+static int __ctsvc_db_relationship_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_relationship_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_relationship_update_record( contacts_record_h record );
+static int __ctsvc_db_relationship_delete_record( int id );
+static int __ctsvc_db_relationship_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_relationship_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_relationship_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_relationship_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_relationship_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_relationship = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_relationship_insert_record,
+       .get_record = __ctsvc_db_relationship_get_record,
+       .update_record = __ctsvc_db_relationship_update_record,
+       .delete_record = __ctsvc_db_relationship_delete_record,
+       .get_all_records = __ctsvc_db_relationship_get_all_records,
+       .get_records_with_query = __ctsvc_db_relationship_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_relationship_insert_records,
+       .update_records = NULL,//__ctsvc_db_relationship_update_records,
+       .delete_records = NULL,//__ctsvc_db_relationship_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_relationship_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_relationship_s *relationship = (ctsvc_relationship_s *)record;
+
+       RETVM_IF(NULL == relationship->name, CONTACTS_ERROR_INVALID_PARAMETER,
+               "Invalid parameter : relationship name is NULL");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", relationship->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       CTS_ERR("No data : contact_id (%d) is not exist", relationship->contact_id);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               else {
+                       CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this relationship record : addressbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_relationship_insert(record, relationship->contact_id, false, id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(relationship->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_relationship_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE id = %d AND datatype = %d ",
+                               id, CTSVC_DATA_RELATIONSHIP);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ctsvc_db_relationship_get_value_from_stmt(stmt, out_record, 0);
+
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_relationship_update_record( contacts_record_h record )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_relationship_s *relationship = (ctsvc_relationship_s *)record;
+       RETVM_IF(NULL == relationship->name, CONTACTS_ERROR_INVALID_PARAMETER, "name is empty");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", relationship->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : contact_id (%d) is not exist", relationship->contact_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this relationship record : addressbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_relationship_update(record, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("Update record Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(relationship->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_relationship_delete_record( int id )
+{
+       int ret;
+       int contact_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt = NULL;
+       int addressbook_id;
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
+                               "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("The id(%d) is Invalid(%d)", id, ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       contact_id = ctsvc_stmt_get_int(stmt, 0);
+       addressbook_id = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this relationship record : addressbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_relationship_delete(id, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_relationship_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int len;
+       int ret;
+       contacts_list_h list;
+       ctsvc_relationship_s *relationship;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE datatype = %d AND is_my_profile=0 ",
+                               CTSVC_DATA_RELATIONSHIP);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB : ctsvc_stmt_step fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_db_relationship_get_value_from_stmt(stmt, (contacts_record_h*)&relationship, 0);
+               ctsvc_list_prepend(list, (contacts_record_h)relationship);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_relationship_get_records_with_query( contacts_query_h query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_relationship_s *relationship;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_relationship._uri, &record);
+               relationship = (ctsvc_relationship_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if(CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_RELATIONSHIP_ID:
+                               relationship->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_RELATIONSHIP_CONTACT_ID:
+                               relationship->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_RELATIONSHIP_TYPE:
+                               relationship->type = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_RELATIONSHIP_LABEL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               relationship->label = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_RELATIONSHIP_NAME:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               relationship->name = SAFE_STRDUP(temp);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_relationship_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_relationship_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_relationship_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_relationship_helper.c b/native/ctsvc_db_plugin_relationship_helper.c
new file mode 100644 (file)
index 0000000..5be1063
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_plugin_relationship_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+
+
+int ctsvc_db_relationship_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count)
+{
+       int ret;
+       char *temp;
+       ctsvc_relationship_s *relationship;
+
+       ret = contacts_record_create(_contacts_relationship._uri, (contacts_record_h *)&relationship);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+
+       relationship->id = ctsvc_stmt_get_int(stmt, start_count++);
+       relationship->contact_id = ctsvc_stmt_get_int(stmt, start_count++);
+       start_count++;
+       relationship->type = ctsvc_stmt_get_int(stmt, start_count++);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       relationship->label = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       relationship->name = SAFE_STRDUP(temp);
+
+       *record = (contacts_record_h)relationship;
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_relationship_bind_stmt(cts_stmt stmt, ctsvc_relationship_s *relationship, int start_cnt)
+{
+       if (relationship->label)
+               ctsvc_stmt_bind_text(stmt, start_cnt, relationship->label);
+       if (relationship->name)
+               ctsvc_stmt_bind_text(stmt, 2, relationship->name);
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_relationship_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_relationship_s *relationship = (ctsvc_relationship_s *)record;
+
+       // These check should be done in client side
+       RETV_IF(NULL == relationship->name, CONTACTS_ERROR_NONE);
+       RETVM_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : contact_id(%d) is mandatory field to insert relationship record", relationship->contact_id);
+       RETVM_IF(0 < relationship->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", relationship->id);
+
+       snprintf(query, sizeof(query),
+               "INSERT INTO "CTS_TABLE_DATA"(contact_id, is_my_profile, datatype, data1, data2, data3) "
+                                                                       "VALUES(%d, %d, %d, %d, ?, ?)",
+                                       contact_id, is_my_profile, CTSVC_DATA_RELATIONSHIP, relationship->type);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       __ctsvc_relationship_bind_stmt(stmt, relationship, 1);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+
+       //relationship->id = ctsvc_db_get_last_insert_id();
+       if (id)
+               *id = ctsvc_db_get_last_insert_id();
+       ctsvc_stmt_finalize(stmt);
+
+       if (!is_my_profile)
+               ctsvc_set_relationship_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_relationship_update(contacts_record_h record, bool is_my_profile)
+{
+       int id;
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       ctsvc_relationship_s *relationship = (ctsvc_relationship_s*)record;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       RETVM_IF(!relationship->id, CONTACTS_ERROR_INVALID_PARAMETER, "relationship of contact has no ID.");
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE id = %d", relationship->id);
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       RETV_IF(ret != CONTACTS_ERROR_NONE, ret);
+
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (relationship->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_DATA, relationship->id))) break;
+               if (!is_my_profile)
+                       ctsvc_set_relationship_noti();
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       return ret;
+}
+
+
+int ctsvc_db_relationship_delete(int id, bool is_my_profile)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE id = %d AND datatype = %d",
+                       id, CTSVC_DATA_RELATIONSHIP);
+
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_exec() Failed(%d)", ret);
+
+       if (!is_my_profile)
+               ctsvc_set_relationship_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/native/ctsvc_db_plugin_relationship_helper.h b/native/ctsvc_db_plugin_relationship_helper.h
new file mode 100644 (file)
index 0000000..7063397
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_DB_PLUGIN_RELATIONSHIP_HELPER_H__
+#define __CTSVC_DB_PLUGIN_RELATIONSHIP_HELPER_H__
+
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
+
+int ctsvc_db_relationship_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id);
+int ctsvc_db_relationship_update(contacts_record_h record, bool is_my_profile);
+int ctsvc_db_relationship_delete(int id, bool is_my_profile);
+int ctsvc_db_relationship_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count);
+
+#endif // __CTSVC_DB_PLUGIN_RELATIONSHIP_HELPER_H__
diff --git a/native/ctsvc_db_plugin_sdn.c b/native/ctsvc_db_plugin_sdn.c
new file mode 100644 (file)
index 0000000..19868eb
--- /dev/null
@@ -0,0 +1,407 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_list.h"
+#include "ctsvc_db_plugin_sdn.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_server_utils.h"
+
+//static int __ctsvc_db_sdn_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_sdn_get_record( int id, contacts_record_h* record );
+//static int __ctsvc_db_sdn_update_record( contacts_record_h record );
+//static int __ctsvc_db_sdn_delete_record( int id );
+static int __ctsvc_db_sdn_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_sdn_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_sdn_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_sdn_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_sdn_delete_records(int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_sdn = {
+       .is_query_only = false,
+       .insert_record = NULL,//__ctsvc_db_sdn_insert_record,
+       .get_record = __ctsvc_db_sdn_get_record,
+       .update_record = NULL,//__ctsvc_db_sdn_update_record,
+       .delete_record = NULL,//__ctsvc_db_sdn_delete_record,
+       .get_all_records = __ctsvc_db_sdn_get_all_records,
+       .get_records_with_query = __ctsvc_db_sdn_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_sdn_insert_records,
+       .update_records = NULL,//__ctsvc_db_sdn_update_records,
+       .delete_records = NULL,//__ctsvc_db_sdn_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_sdn_value_set(cts_stmt stmt, contacts_record_h *record)
+{
+       int i;
+       int ret;
+       char *temp;
+       ctsvc_sdn_s *sdn;
+
+       ret = contacts_record_create(_contacts_sdn._uri, record);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+       sdn = (ctsvc_sdn_s*)*record;
+
+       i = 0;
+       sdn->id = ctsvc_stmt_get_int(stmt, i++);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       sdn->name = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       sdn->number = SAFE_STRDUP(temp);
+       sdn->sim_slot_no = ctsvc_stmt_get_int(stmt, i++);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_sdn_get_record( int id, contacts_record_h* out_record )
+{
+       RETVM_IF(!ctsvc_server_have_telephony_feature(), CONTACTS_ERROR_NOT_SUPPORTED, "Telephony feature disabled");
+
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_record_h record;
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                               "SELECT id, name, number, sim_slot_no FROM "CTS_TABLE_SDN" WHERE id = %d", id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ret = __ctsvc_db_sdn_value_set(stmt, &record);
+
+       ctsvc_stmt_finalize(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_db_sdn_value_set(ALL) Failed(%d)", ret);
+               return ret;
+       }
+
+       *out_record = record;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+#if 0
+static int __ctsvc_db_sdn_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       ctsvc_sdn_s *sdn = (ctsvc_sdn_s*)record;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == sdn->name, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETVM_IF(CTSVC_RECORD_SDN != sdn->base.r_type, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : record is invalid type(%d)", sdn->base.r_type);
+
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "INSERT INTO "CTS_TABLE_SDN"(name, number, sim_slot_no) VALUES(?, ?, ?)");
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ctsvc_stmt_bind_text(stmt, 1, sdn->name);
+       ctsvc_stmt_bind_text(stmt, 2, sdn->number);
+       ctsvc_stmt_bind_int(stmt, 3, sdn->sim_slot_no);
+
+       ret = ctsvc_begin_trans();
+       if( ret < CONTACTS_ERROR_NONE ) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       //sdn->id = ctsvc_db_get_last_insert_id();
+       if (id)
+               *id = ctsvc_db_get_last_insert_id();
+       ctsvc_stmt_finalize(stmt);
+
+       ctsvc_set_sdn_noti();
+       ret = ctsvc_end_trans(true);
+       if(ret < CONTACTS_ERROR_NONE ) {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_sdn_update_record( contacts_record_h record )
+{
+       int sdn_id;
+       int ret = CONTACTS_ERROR_NONE;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       ctsvc_sdn_s *sdn = (ctsvc_sdn_s*)record;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETVM_IF(CTSVC_RECORD_SDN != sdn->base.r_type, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : record is invalid type(%d)", sdn->base.r_type);
+       RETVM_IF(!sdn->id, CONTACTS_ERROR_INVALID_PARAMETER, "sdn of contact has no ID.");
+       RETV_IF(NULL == sdn->name, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (sdn->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_SDN" WHERE id = %d", sdn->id);
+       ret = ctsvc_query_get_first_int_result(query, &sdn_id);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_SDN, sdn->id))) break;
+               ctsvc_set_sdn_noti();
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       ret = ctsvc_end_trans(true);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "DB error : ctsvc_end_trans() Failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_sdn_delete_record( int sdn_id )
+{
+       int ret;
+       int id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE > ret, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_SDN" WHERE id = %d", sdn_id);
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_SDN" WHERE id = %d", sdn_id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_change();
+       if (ret <= 0) {
+               ret = CONTACTS_ERROR_NO_DATA;
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_set_sdn_noti();
+       ret = ctsvc_end_trans(true);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+#endif
+
+static int __ctsvc_db_sdn_get_all_records( int offset, int limit,
+       contacts_list_h* out_list )
+{
+       RETVM_IF(!ctsvc_server_have_telephony_feature(), CONTACTS_ERROR_NOT_SUPPORTED, "Telephony feature disabled");
+
+       int ret;
+       int len;
+       cts_stmt stmt;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_list_h list;
+
+       len = snprintf(query, sizeof(query),
+                               "SELECT id, name, number, sim_slot_no FROM "CTS_TABLE_SDN);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               __ctsvc_db_sdn_value_set(stmt, &record);
+
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_sdn_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list )
+{
+       RETVM_IF(!ctsvc_server_have_telephony_feature(), CONTACTS_ERROR_NOT_SUPPORTED, "Telephony feature disabled");
+
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_sdn_s *sdn;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_sdn._uri, &record);
+               sdn = (ctsvc_sdn_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else
+               {
+                       field_count = s_query->projection_count;
+
+                       if( CONTACTS_ERROR_NONE != ctsvc_record_set_projection_flags(record, s_query->projection, s_query->projection_count, s_query->property_count) )
+                       {
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+                       }
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_SDN_ID:
+                               sdn->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_SDN_NAME:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               sdn->name = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_SDN_NUMBER:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               sdn->number = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_SDN_SIM_SLOT_NO:
+                               sdn->sim_slot_no = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+#if 0
+static int __ctsvc_db_sdn_insert_records(const contacts_list_h in_list, int **ids)
+{
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_sdn_update_records(const contacts_list_h in_list)
+{
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_sdn_delete_records(int ids[], int count)
+{
+       return CONTACTS_ERROR_NONE;
+}
+#endif
old mode 100755 (executable)
new mode 100644 (file)
similarity index 85%
rename from include/contacts-svc-sub.head
rename to native/ctsvc_db_plugin_sdn.h
index e891d16..0b29b7d
@@ -3,8 +3,6 @@
  *
  * 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
@@ -18,6 +16,9 @@
  * limitations under the License.
  *
  */
-#ifndef __CONTACTS_SVC_SUB_H__
-#define __CONTACTS_SVC_SUB_H__
 
+#ifndef __CTSVC_DB_PLUGIN_SDN_H__
+#define __CTSVC_DB_PLUGIN_SDN_H__
+
+
+#endif // __CTSVC_DB_PLUGIN_SDN_H__
diff --git a/native/ctsvc_db_plugin_simple_contact.c b/native/ctsvc_db_plugin_simple_contact.c
new file mode 100644 (file)
index 0000000..7f1ea94
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <sys/types.h>
+#include <fcntl.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_list.h"
+#include "ctsvc_db_plugin_person_helper.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_access_control.h"
+
+static int __ctsvc_db_simple_contact_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_simple_contact_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_simple_contact_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_simple_contact = {
+       .is_query_only = false,
+       .insert_record = NULL,
+       .get_record = __ctsvc_db_simple_contact_get_record,
+       .update_record = NULL,
+       .delete_record = NULL,
+       .get_all_records = __ctsvc_db_simple_contact_get_all_records,
+       .get_records_with_query = __ctsvc_db_simple_contact_get_records_with_query,
+       .insert_records = NULL,
+       .update_records = NULL,
+       .delete_records = NULL,
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_simple_contact_value_set(cts_stmt stmt, contacts_record_h *record)
+{
+       int i;
+       int ret;
+       char *temp;
+       ctsvc_simple_contact_s *contact;
+       char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+
+       ret = contacts_record_create(_contacts_simple_contact._uri, record);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+       contact = (ctsvc_simple_contact_s*)*record;
+
+       i = 0;
+       contact->contact_id = ctsvc_stmt_get_int(stmt, i++);
+       contact->addressbook_id = ctsvc_stmt_get_int(stmt, i++);
+       contact->person_id = ctsvc_stmt_get_int(stmt, i++);
+       contact->changed_time = ctsvc_stmt_get_int(stmt, i++);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       contact->display_name = SAFE_STRDUP(temp);
+       contact->display_source_type = ctsvc_stmt_get_int(stmt, i++);
+
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       if (temp) {
+               snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
+               contact->image_thumbnail_path = strdup(full_path);
+       }
+
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       contact->ringtone_path = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       contact->vibration = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       contact->message_alert = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       contact->uid = SAFE_STRDUP(temp);
+       contact->is_favorite = ctsvc_stmt_get_int(stmt, i++);
+       contact->has_phonenumber = ctsvc_stmt_get_int(stmt, i++);
+       contact->has_email = ctsvc_stmt_get_int(stmt, i++);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_simple_contact_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_record_h record;
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                               "SELECT contact_id, addressbook_id, person_id, changed_time, %s, "
+                                       "display_name_source, image_thumbnail_path, "
+                                       "ringtone_path, vibration, message_alert, uid, is_favorite, has_phonenumber, has_email "
+                                       "FROM "CTS_TABLE_CONTACTS" WHERE contact_id = %d AND deleted = 0",
+                                       ctsvc_get_display_column(), id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ret = __ctsvc_db_simple_contact_value_set(stmt, &record);
+
+       ctsvc_stmt_finalize(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_db_simple_contact_value_set(ALL) Failed(%d)", ret);
+               return ret;
+       }
+
+       *out_record = record;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_simple_contact_get_all_records( int offset, int limit,
+       contacts_list_h* out_list )
+{
+       int ret;
+       int len;
+       cts_stmt stmt;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_list_h list;
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT contact_id, addressbook_id, person_id, changed_time, "
+                               "%s, display_name_source, image_thumbnail_path, "
+                               "ringtone_path, vibration, message_alert, uid, is_favorite, has_phonenumber, has_email "
+                               "FROM "CTS_TABLE_CONTACTS" WHERE deleted = 0", ctsvc_get_display_column());
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               __ctsvc_db_simple_contact_value_set(stmt, &record);
+
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_simple_contact_get_records_with_query( contacts_query_h query,
+       int offset, int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_simple_contact_s *contact;
+       char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_simple_contact._uri, &record);
+               contact = (ctsvc_simple_contact_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else
+               {
+                       field_count = s_query->projection_count;
+
+                       if( CONTACTS_ERROR_NONE != ctsvc_record_set_projection_flags(record, s_query->projection, s_query->projection_count, s_query->property_count) )
+                       {
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+                       }
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_CONTACT_ID:
+                               contact->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_DISPLAY_NAME:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               contact->display_name = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID:
+                               contact->display_source_type = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID:
+                               contact->addressbook_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_RINGTONE:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               contact->ringtone_path = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               if (temp && *temp) {
+                                       snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
+                                       contact->image_thumbnail_path = strdup(full_path);
+                               }
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_IS_FAVORITE:
+                               contact->is_favorite = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_HAS_PHONENUMBER:
+                               contact->has_phonenumber = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_HAS_EMAIL:
+                               contact->has_email = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_PERSON_ID:
+                               contact->person_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_UID:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               contact->uid = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_VIBRATION:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               contact->vibration = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_MESSAGE_ALERT:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               contact->message_alert = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_CONTACT_CHANGED_TIME:
+                               contact->changed_time = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_simple_contact_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_simple_contact_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_simple_contact_delete_records(int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_speeddial.c b/native/ctsvc_db_plugin_speeddial.c
new file mode 100644 (file)
index 0000000..d16b082
--- /dev/null
@@ -0,0 +1,452 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_list.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+
+static int __ctsvc_db_speeddial_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_speeddial_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_speeddial_update_record( contacts_record_h record );
+static int __ctsvc_db_speeddial_delete_record( int id );
+static int __ctsvc_db_speeddial_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_speeddial_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_speeddial_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_speeddial_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_speeddial_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_speeddial = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_speeddial_insert_record,
+       .get_record = __ctsvc_db_speeddial_get_record,
+       .update_record = __ctsvc_db_speeddial_update_record,
+       .delete_record = __ctsvc_db_speeddial_delete_record,
+       .get_all_records = __ctsvc_db_speeddial_get_all_records,
+       .get_records_with_query = __ctsvc_db_speeddial_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_speeddial_insert_records,
+       .update_records = NULL,//__ctsvc_db_speeddial_update_records,
+       .delete_records = NULL,//__ctsvc_db_speeddial_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_speeddial_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int number_id = 0;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_speeddial_s *speeddial = (ctsvc_speeddial_s*)record;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       // check number_id validation
+       snprintf(query, sizeof(query),
+                       "SELECT data.id FROM "CTS_TABLE_DATA", "CTS_TABLE_CONTACTS" "
+                                               "ON "CTS_TABLE_DATA".contact_id = "CTS_TABLE_CONTACTS".contact_id "
+                                                               "AND contacts.deleted = 0  AND is_my_profile = 0 AND datatype = %d "
+                                               "WHERE id = %d ",
+                                               CTSVC_DATA_NUMBER, speeddial->number_id);
+       ret = ctsvc_query_get_first_int_result(query, &number_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_get_first_int_result() Failed(%d) : number_id is invalid", ret);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       snprintf(query, sizeof(query),
+                       "INSERT INTO "CTS_TABLE_SPEEDDIALS"(speed_number, number_id) VALUES(%d, %d)",
+                       speeddial->dial_number, speeddial->number_id);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_change();
+       if (0 < ret) {
+               if (id)
+                       *id  = speeddial->dial_number;
+               ctsvc_set_speed_noti();
+       }
+       else {
+               CTS_ERR("already exist");
+       }
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+               return ret;
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_speeddial_value_set(cts_stmt stmt, contacts_record_h *record)
+{
+       int i;
+       int ret;
+       char *temp;
+       ctsvc_speeddial_s *speeddial;
+
+       ret = contacts_record_create(_contacts_speeddial._uri, record);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+       speeddial = (ctsvc_speeddial_s*)*record;
+
+       i = 0;
+       speeddial->person_id = ctsvc_stmt_get_int(stmt, i++);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       speeddial->display_name = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       if (temp) {
+               char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+               snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
+               speeddial->image_thumbnail_path = strdup(full_path);
+       }
+
+       speeddial->number_id = ctsvc_stmt_get_int(stmt, i++);
+       speeddial->number_type = ctsvc_stmt_get_int(stmt, i++);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       speeddial->label = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, i++);
+       speeddial->number = SAFE_STRDUP(temp);
+       speeddial->dial_number = ctsvc_stmt_get_int(stmt, i++);
+       speeddial->id = speeddial->dial_number; // dial_number is an unique key
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_speeddial_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       contacts_record_h record;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "SELECT person_id, %s, image_thumbnail_path, number_id, "
+                                       "type, label, number, speed_number  "
+                       "FROM "CTSVC_DB_VIEW_SPEEDIDAL " "
+                       "WHERE speed_number = %d",
+                       ctsvc_get_display_column(), id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ret = __ctsvc_db_speeddial_value_set(stmt, &record);
+
+       ctsvc_stmt_finalize(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_db_speeddial_value_set(ALL) Failed(%d)", ret);
+               return ret;
+       }
+
+       *out_record = record;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_speeddial_update_record( contacts_record_h record )
+{
+       int ret;
+       int number_id;
+       int speeddial_id;
+       cts_stmt stmt;
+       char query[CTS_SQL_MIN_LEN] = {0};
+       ctsvc_speeddial_s *speeddial = (ctsvc_speeddial_s *)record;
+
+       RETVM_IF (speeddial->dial_number < 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : dial number (%d)", speeddial->dial_number);
+       RETVM_IF (speeddial->number_id < 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : number id (%d)", speeddial->number_id);
+       ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, CONTACTS_ERROR_DB, "DB error : ctsvc_begin_trans() Fail(%d)", ret);
+
+       // check number_id validation
+       snprintf(query, sizeof(query),
+                       "SELECT data.id FROM "CTS_TABLE_DATA", "CTS_TABLE_CONTACTS" "
+                                               "ON "CTS_TABLE_DATA".contact_id = "CTS_TABLE_CONTACTS".contact_id "
+                                                               "AND contacts.deleted = 0  AND is_my_profile = 0 AND datatype = %d "
+                                               "WHERE id = %d ",
+                                               CTSVC_DATA_NUMBER, speeddial->number_id);
+       ret = ctsvc_query_get_first_int_result(query, &number_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_get_first_int_result() Failed(%d) : number_id is invalid", ret);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       snprintf(query, sizeof(query),
+               "SELECT speed_number FROM "CTS_TABLE_SPEEDDIALS" WHERE speed_number = %d", speeddial->dial_number);
+       ret = ctsvc_query_get_first_int_result(query, &speeddial_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_query_get_first_int_result() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query), "UPDATE "CTS_TABLE_SPEEDDIALS" "
+                       "SET number_id = %d WHERE speed_number = %d",
+                       speeddial->number_id, speeddial->dial_number);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ret = ctsvc_db_change();
+       ctsvc_stmt_finalize(stmt);
+
+       if (0 < ret) {
+               ctsvc_set_speed_noti();
+               ret = ctsvc_end_trans(true);
+       }
+       else {
+               ctsvc_end_trans(false);
+               ret = CONTACTS_ERROR_NO_DATA;
+       }
+
+       if (ret < CONTACTS_ERROR_NONE)
+               return ret;
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_speeddial_delete_record( int id )
+{
+       int ret;
+       int speeddial_id;
+       cts_stmt stmt;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, CONTACTS_ERROR_DB, "DB error : ctsvc_begin_trans() Fail(%d)", ret);
+
+       snprintf(query, sizeof(query),
+               "SELECT speed_number FROM "CTS_TABLE_SPEEDDIALS" WHERE speed_number = %d", id);
+       ret = ctsvc_query_get_first_int_result(query, &speeddial_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_query_get_first_int_result() Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE speed_number = %d",
+                       CTS_TABLE_SPEEDDIALS, id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ret = ctsvc_db_change();
+       ctsvc_stmt_finalize(stmt);
+
+       if (0 < ret) {
+               ctsvc_set_speed_noti();
+               ret = ctsvc_end_trans(true);
+       }
+       else {
+               ctsvc_end_trans(false);
+               ret = CONTACTS_ERROR_NO_DATA;
+       }
+
+       if (ret < CONTACTS_ERROR_NONE)
+               return ret;
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_speeddial_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int len;
+       cts_stmt stmt;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_list_h list;
+
+       len = snprintf(query, sizeof(query),
+                                       "SELECT person_id, %s, image_thumbnail_path, number_id, "
+                                                       "type, label, number, speed_number      "
+                                       "FROM "CTSVC_DB_VIEW_SPEEDIDAL " ",     ctsvc_get_display_column());
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               __ctsvc_db_speeddial_value_set(stmt, &record);
+
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_speeddial_get_records_with_query( contacts_query_h query,
+               int offset, int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_speeddial_s *speeddial;
+       char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0};
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt is failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_speeddial._uri, &record);
+               speeddial = (ctsvc_speeddial_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else
+               {
+                       field_count = s_query->projection_count;
+
+                       if( CONTACTS_ERROR_NONE != ctsvc_record_set_projection_flags(record, s_query->projection, s_query->projection_count, s_query->property_count) )
+                       {
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+                       }
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_SPEEDDIAL_DIAL_NUMBER:
+                               speeddial->dial_number = ctsvc_stmt_get_int(stmt, i);
+                               speeddial->id = speeddial->dial_number; // dial_number is an unique key
+                               break;
+                       case CTSVC_PROPERTY_SPEEDDIAL_NUMBER_ID:
+                               speeddial->number_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_SPEEDDIAL_NUMBER:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               speeddial->number = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_SPEEDDIAL_NUMBER_LABEL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               speeddial->label = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_SPEEDDIAL_NUMBER_TYPE:
+                               speeddial->number_type = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_SPEEDDIAL_PERSON_ID:
+                               speeddial->person_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_SPEEDDIAL_DISPLAY_NAME:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               speeddial->display_name = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_SPEEDDIAL_IMAGE_THUMBNAIL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               if (temp) {
+                                       snprintf(full_path, sizeof(full_path), "%s/%s", CTSVC_CONTACT_IMG_FULL_LOCATION, temp);
+                                       speeddial->image_thumbnail_path = strdup(full_path);
+                               }
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_speeddial_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_speeddial_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_speeddial_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_url.c b/native/ctsvc_db_plugin_url.c
new file mode 100644 (file)
index 0000000..8f6043e
--- /dev/null
@@ -0,0 +1,405 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_db_plugin_url_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_list.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_access_control.h"
+
+static int __ctsvc_db_url_insert_record( contacts_record_h record, int *id );
+static int __ctsvc_db_url_get_record( int id, contacts_record_h* out_record );
+static int __ctsvc_db_url_update_record( contacts_record_h record );
+static int __ctsvc_db_url_delete_record( int id );
+static int __ctsvc_db_url_get_all_records( int offset, int limit, contacts_list_h* out_list );
+static int __ctsvc_db_url_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* out_list );
+//static int __ctsvc_db_url_insert_records(const contacts_list_h in_list, int **ids);
+//static int __ctsvc_db_url_update_records(const contacts_list_h in_list);
+//static int __ctsvc_db_url_delete_records( int ids[], int count);
+
+ctsvc_db_plugin_info_s ctsvc_db_plugin_url = {
+       .is_query_only = false,
+       .insert_record = __ctsvc_db_url_insert_record,
+       .get_record = __ctsvc_db_url_get_record,
+       .update_record = __ctsvc_db_url_update_record,
+       .delete_record = __ctsvc_db_url_delete_record,
+       .get_all_records = __ctsvc_db_url_get_all_records,
+       .get_records_with_query = __ctsvc_db_url_get_records_with_query,
+       .insert_records = NULL,//__ctsvc_db_url_insert_records,
+       .update_records = NULL,//__ctsvc_db_url_update_records,
+       .delete_records = NULL,//__ctsvc_db_url_delete_records
+       .get_count = NULL,
+       .get_count_with_query = NULL,
+       .replace_record = NULL,
+       .replace_records = NULL,
+};
+
+static int __ctsvc_db_url_insert_record( contacts_record_h record, int *id )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_url_s *url = (ctsvc_url_s *)record;
+
+       RETVM_IF(NULL == url->url, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : url is NULL");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", url->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       CTS_ERR("No data : contact_id (%d) is not exist", url->contact_id);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               else {
+                       CTS_ERR("ctsvc_query_get_first_int_result Fail(%d)", ret);
+                       return ret;
+               }
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this url record : addressbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_url_insert(record, url->contact_id, false, id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(url->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_url_get_record( int id, contacts_record_h* out_record )
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+
+       snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE id = %d AND datatype = %d ",
+                               id, CTSVC_DATA_URL);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ctsvc_db_url_get_value_from_stmt(stmt, out_record, 0);
+
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_url_update_record( contacts_record_h record )
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_url_s *url = (ctsvc_url_s *)record;
+       RETVM_IF(NULL == url->url, CONTACTS_ERROR_INVALID_PARAMETER, "url is empty");
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", url->contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : contact_id (%d) is not exist", url->contact_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to update this url record : addressbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_url_update(record, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("Update record Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(url->contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_url_delete_record( int id )
+{
+       int ret;
+       int contact_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt = NULL;
+       int addressbook_id;
+
+       ret = ctsvc_begin_trans();
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, addressbook_id FROM "CTSVC_DB_VIEW_CONTACT " "
+                               "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare Fail(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("The id(%d) is Invalid(%d)", id, ret);
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       contact_id = ctsvc_stmt_get_int(stmt, 0);
+       addressbook_id = ctsvc_stmt_get_int(stmt, 1);
+       ctsvc_stmt_finalize(stmt);
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to delete this url record : addressbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       ret = ctsvc_db_url_delete(id, false);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_db_contact_update_changed_time(contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_url_get_all_records( int offset, int limit, contacts_list_h* out_list )
+{
+       int len;
+       int ret;
+       contacts_list_h list;
+       ctsvc_url_s *url;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT id, data.contact_id, is_default, data1, data2, data3 "
+                               "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                               "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                               "WHERE datatype = %d AND is_my_profile=0 ",
+                               CTSVC_DATA_URL);
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB : ctsvc_stmt_step fail(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+               ctsvc_db_url_get_value_from_stmt(stmt, (contacts_record_h*)&url, 0);
+               ctsvc_list_prepend(list, (contacts_record_h)url);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_url_get_records_with_query( contacts_query_h query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int field_count;
+       ctsvc_query_s *s_query;
+       cts_stmt stmt;
+       contacts_list_h list;
+       ctsvc_url_s *url;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       ret = ctsvc_db_make_get_records_query_stmt(s_query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_db_make_get_records_query_stmt fail(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 /*CTS_TRUE */ != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(_contacts_url._uri, &record);
+               url = (ctsvc_url_s*)record;
+               if (0 == s_query->projection_count)
+                       field_count = s_query->property_count;
+               else {
+                       field_count = s_query->projection_count;
+                       ret = ctsvc_record_set_projection_flags(record, s_query->projection,
+                                       s_query->projection_count, s_query->property_count);
+
+                       if(CONTACTS_ERROR_NONE != ret)
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+               }
+
+               for(i=0;i<field_count;i++) {
+                       char *temp;
+                       int property_id;
+                       if (0 == s_query->projection_count)
+                               property_id = s_query->properties[i].property_id;
+                       else
+                               property_id = s_query->projection[i];
+
+                       switch(property_id) {
+                       case CTSVC_PROPERTY_URL_ID:
+                               url->id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_URL_CONTACT_ID:
+                               url->contact_id = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_URL_TYPE:
+                               url->type = ctsvc_stmt_get_int(stmt, i);
+                               break;
+                       case CTSVC_PROPERTY_URL_LABEL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               url->label = SAFE_STRDUP(temp);
+                               break;
+                       case CTSVC_PROPERTY_URL_URL:
+                               temp = ctsvc_stmt_get_text(stmt, i);
+                               url->url = SAFE_STRDUP(temp);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+//static int __ctsvc_db_url_insert_records(const contacts_list_h in_list, int **ids) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_url_update_records(const contacts_list_h in_list) { return CONTACTS_ERROR_NONE; }
+//static int __ctsvc_db_url_delete_records( int ids[], int count) { return CONTACTS_ERROR_NONE; }
diff --git a/native/ctsvc_db_plugin_url_helper.c b/native/ctsvc_db_plugin_url_helper.c
new file mode 100644 (file)
index 0000000..77dd081
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_db_plugin_url_helper.h"
+#include "ctsvc_record.h"
+#include "ctsvc_notification.h"
+
+
+int ctsvc_db_url_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count)
+{
+       int ret;
+       char *temp;
+       ctsvc_url_s *url;
+
+       ret = contacts_record_create(_contacts_url._uri, (contacts_record_h *)&url);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret);
+
+       url->id = ctsvc_stmt_get_int(stmt, start_count++);
+       url->contact_id = ctsvc_stmt_get_int(stmt, start_count++);
+       start_count++;
+       url->type = ctsvc_stmt_get_int(stmt, start_count++);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       url->label = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, start_count++);
+       url->url = SAFE_STRDUP(temp);
+
+       *record = (contacts_record_h)url;
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_url_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       ctsvc_url_s *url = (ctsvc_url_s *)record;
+
+       RETV_IF(NULL == url->url, CONTACTS_ERROR_NONE);
+       RETVM_IF(contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : contact_id(%d) is mandatory field to insert url record ", url->contact_id);
+       RETVM_IF(0 < url->id, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : id(%d), This record is already inserted", url->id);
+
+       snprintf(query, sizeof(query),
+               "INSERT INTO "CTS_TABLE_DATA"(contact_id, is_my_profile, datatype, data1, data2, data3) "
+                                                                       "VALUES(%d, %d, %d, %d, ?, ?)",
+                                                       contact_id, is_my_profile, CTSVC_DATA_URL, url->type);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       if (url->label)
+               ctsvc_stmt_bind_text(stmt, 1, url->label);
+       if (url->url)
+               ctsvc_stmt_bind_text(stmt, 2, url->url);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+
+       //url->id = ctsvc_db_get_last_insert_id();
+       if (id)
+               *id = ctsvc_db_get_last_insert_id();
+       ctsvc_stmt_finalize(stmt);
+
+       if (!is_my_profile)
+               ctsvc_set_url_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_db_url_update(contacts_record_h record, bool is_my_profile)
+{
+       int id;
+       int ret = CONTACTS_ERROR_NONE;
+       ctsvc_url_s *url = (ctsvc_url_s*)record;
+       char* set = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(!url->id, CONTACTS_ERROR_INVALID_PARAMETER, "url of contact has no ID.");
+       RETVM_IF(CTSVC_PROPERTY_FLAG_DIRTY != (url->base.property_flag & CTSVC_PROPERTY_FLAG_DIRTY), CONTACTS_ERROR_NONE, "No update");
+
+       snprintf(query, sizeof(query),
+                       "SELECT id FROM "CTS_TABLE_DATA" WHERE id = %d", url->id);
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       RETV_IF(ret != CONTACTS_ERROR_NONE, ret);
+
+       do {
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_create_set_query(record, &set, &bind_text))) break;
+               if (CONTACTS_ERROR_NONE != (ret = ctsvc_db_update_record_with_set_query(set, bind_text, CTS_TABLE_DATA, url->id))) break;
+               if (!is_my_profile)
+                       ctsvc_set_url_noti();
+       } while (0);
+
+       CTSVC_RECORD_RESET_PROPERTY_FLAGS((ctsvc_record_s *)record);
+       CONTACTS_FREE(set);
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       CONTACTS_FREE(cursor->data);
+               g_slist_free(bind_text);
+       }
+       return ret;
+}
+
+int ctsvc_db_url_delete(int id, bool is_my_profile)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE id = %d AND datatype = %d",
+                       id, CTSVC_DATA_URL);
+
+       ret = ctsvc_query_exec(query);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_exec() Failed(%d)", ret);
+
+       if (!is_my_profile)
+               ctsvc_set_url_noti();
+
+       return CONTACTS_ERROR_NONE;
+}
+
old mode 100755 (executable)
new mode 100644 (file)
similarity index 57%
rename from test/SIMexport-test.c
rename to native/ctsvc_db_plugin_url_helper.h
index 1230226..6d06362
@@ -3,8 +3,6 @@
  *
  * 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
  * 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);
+#ifndef __CTSVC_DB_PLUGIN_URL_HELPER_H__
+#define __CTSVC_DB_PLUGIN_URL_HELPER_H__
 
-       contacts_svc_disconnect();
-       return 0;
-}
+#include "contacts.h"
+#include "ctsvc_sqlite.h"
 
+int ctsvc_db_url_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id);
+int ctsvc_db_url_update(contacts_record_h record, bool is_my_profile);
+int ctsvc_db_url_delete(int id, bool is_my_profile);
+int ctsvc_db_url_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count);
 
+#endif // __CTSVC_DB_PLUGIN_URL_HELPER_H__
diff --git a/native/ctsvc_db_query.c b/native/ctsvc_db_query.c
new file mode 100755 (executable)
index 0000000..bd8a7ec
--- /dev/null
@@ -0,0 +1,3674 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+
+#include "contacts.h"
+#include "contacts_internal.h"
+
+#include "ctsvc_internal.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_list.h"
+#include "ctsvc_record.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_number_utils.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_view.h"
+#include "ctsvc_inotify.h"
+#include "ctsvc_localize.h"
+#include "ctsvc_localize_utils.h"
+#include "ctsvc_setting.h"
+
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_db_plugin_person_helper.h"
+#include "ctsvc_db_plugin_group_helper.h"
+#include "ctsvc_db_plugin_company_helper.h"
+
+#ifdef _CONTACTS_IPC_SERVER
+#ifdef ENABLE_SIM_FEATURE
+#include "ctsvc_server_sim.h"
+#endif // ENABLE_SIM_FEATURE
+#include "ctsvc_server_change_subject.h"
+#endif
+
+// It is used to sort search results
+const char *hangul_syllable[19][3] = {
+       {"ㄱ", "가", "깋"},  // AC00, AE3B
+       {"ㄲ", "까", "낗"},  // AE3C, B097
+       {"ㄴ", "나", "닣"},  // B098, B2E3
+       {"ㄷ", "다", "딯"},  // B2E4, B52F
+       {"ㄸ", "따", "띻"},  // B530, B77B
+       {"ㄹ", "라", "맇"},  // B77C, B9C7
+       {"ㅁ", "마", "밓"},  // B9C8, BC13
+       {"ㅂ", "바", "빟"},  // BC14, BE5F
+       {"ㅃ", "빠", "삫"},  // BE60, C0AB
+       {"ㅅ", "사", "싷"},  // C0AC, C2F7
+       {"ㅆ", "싸", "앃"},  // C2F8, C543
+       {"ㅇ", "아", "잏"},  // C544, C78F
+       {"ㅈ", "자", "짛"},  // C790, C9DB
+       {"ㅉ", "짜", "찧"},  // C9DC, CC27
+       {"ㅊ", "차", "칳"},  // CC28, CE73
+       {"ㅋ", "카", "킿"},  // CE74, D0AF
+       {"ㅌ", "타", "팋"},  // D0C0, D30B
+       {"ㅍ", "파", "핗"},  // D30C, D557
+       {"ㅎ", "하", "힣"},  // D558, D7A3
+};
+
+typedef enum {
+       QUERY_SORTKEY,
+       QUERY_FILTER,
+       QUERY_PROJECTION,
+}db_query_property_type_e;
+
+static contacts_db_status_e __db_status = CONTACTS_DB_STATUS_NORMAL;
+
+static const char * __ctsvc_db_get_property_field_name(const property_info_s *properties,
+               int count, db_query_property_type_e property_type, unsigned int property_id)
+{
+       int i;
+
+       for (i=0;i<count;i++) {
+               property_info_s *p = (property_info_s*)&(properties[i]);
+               if (property_id == p->property_id) {
+                       if (p->fields) {
+                               if (property_type == QUERY_PROJECTION) {
+                                       if (p->property_type == CTSVC_SEARCH_PROPERTY_PROJECTION || p->property_type == CTSVC_SEARCH_PROPERTY_ALL)
+                                               return p->fields;
+                               }
+                               else if (property_type == QUERY_FILTER) {
+                                       if (p->property_type == CTSVC_SEARCH_PROPERTY_FILTER || p->property_type == CTSVC_SEARCH_PROPERTY_ALL)
+                                               return p->fields;
+                               }
+                               else if (property_type == QUERY_SORTKEY) {
+                                       return p->fields;
+                               }
+                               return NULL;
+                       }
+                       /*
+                       else if (property_id == CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX) {
+                               if (property_type != QUERY_PROJECTION)
+                                       return NULL;
+                               const char* temp = ctsvc_get_display_column();
+                               // snprintf(temp, sizeof(temp), "_NORMALIZE_INDEX_(%s)", ctsvc_get_display_column());
+                               return "_NORMALIZE_INDEX_"temp;
+                       }
+                       */
+                       else
+                               return ctsvc_get_display_column();
+               }
+       }
+       return NULL;
+}
+
+// return data type of the property
+// bool / int / long long int / char string / double / child record
+static inline int __ctsvc_db_get_property_type(const property_info_s *properties,
+               int count, unsigned int property_id)
+{
+       int i;
+       for (i=0;i<count;i++) {
+               property_info_s *p = (property_info_s*)&(properties[i]);
+               if (property_id == p->property_id) {
+                       return (property_id & CTSVC_VIEW_DATA_TYPE_MASK);
+               }
+       }
+       return -1;
+}
+
+static inline int __ctsvc_db_create_int_condition(ctsvc_composite_filter_s *com_filter,
+               ctsvc_attribute_filter_s *filter, char **condition )
+{
+       const char *field_name;
+       char out_cond[CTS_SQL_MAX_LEN] = {0};
+
+       field_name = __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                       com_filter->property_count, QUERY_FILTER, filter->property_id);
+       RETVM_IF(NULL == field_name, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : property id(%d)", filter->property_id);
+
+#ifdef _CONTACTS_IPC_SERVER
+#ifdef ENABLE_SIM_FEATURE
+       if (filter->property_id == CTSVC_PROPERTY_PHONELOG_SIM_SLOT_NO) {
+               // get real sim info id by SIM slot number 0/1
+               int sim_info_id = ctsvc_server_sim_get_info_id_by_sim_slot_no(filter->value.i);
+               if (sim_info_id > 0) {
+                       snprintf(out_cond, sizeof(out_cond), "%s = %d", field_name, sim_info_id);
+                       *condition = strdup(out_cond);
+                       return CONTACTS_ERROR_NONE;
+               }
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+#endif // ENABLE_SIM_FEATURE
+#endif
+
+       switch(filter->match) {
+       case CONTACTS_MATCH_EQUAL:
+               snprintf(out_cond, sizeof(out_cond), "%s = %d", field_name, filter->value.i);
+               break;
+       case CONTACTS_MATCH_GREATER_THAN:
+               snprintf(out_cond, sizeof(out_cond), "%s > %d", field_name, filter->value.i);
+               break;
+       case CONTACTS_MATCH_GREATER_THAN_OR_EQUAL:
+               snprintf(out_cond, sizeof(out_cond), "%s >= %d", field_name, filter->value.i);
+               break;
+       case CONTACTS_MATCH_LESS_THAN:
+               snprintf(out_cond, sizeof(out_cond), "%s < %d", field_name, filter->value.i);
+               break;
+       case CONTACTS_MATCH_LESS_THAN_OR_EQUAL:
+               snprintf(out_cond, sizeof(out_cond), "%s <= %d", field_name, filter->value.i);
+               break;
+       case CONTACTS_MATCH_NOT_EQUAL:
+               snprintf(out_cond, sizeof(out_cond), "%s <> %d", field_name, filter->value.i);
+               break;
+       case CONTACTS_MATCH_NONE:
+               snprintf(out_cond, sizeof(out_cond), "%s IS NULL", field_name);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : int match rule(%d) is not supported", filter->match);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       *condition = strdup(out_cond);
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_db_create_double_condition(ctsvc_composite_filter_s *com_filter,
+               ctsvc_attribute_filter_s *filter, char **condition )
+{
+       const char *field_name;
+       char out_cond[CTS_SQL_MAX_LEN] = {0};
+
+       field_name = __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                       com_filter->property_count, QUERY_FILTER, filter->property_id);
+       RETVM_IF(NULL == field_name, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : property id(%d)", filter->property_id);
+
+       switch(filter->match) {
+       case CONTACTS_MATCH_EQUAL:
+               snprintf(out_cond, sizeof(out_cond), "%s = %lf", field_name, filter->value.d);
+               break;
+       case CONTACTS_MATCH_GREATER_THAN:
+               snprintf(out_cond, sizeof(out_cond), "%s > %lf", field_name, filter->value.d);
+               break;
+       case CONTACTS_MATCH_GREATER_THAN_OR_EQUAL:
+               snprintf(out_cond, sizeof(out_cond), "%s >= %lf", field_name, filter->value.d);
+               break;
+       case CONTACTS_MATCH_LESS_THAN:
+               snprintf(out_cond, sizeof(out_cond), "%s < %lf", field_name, filter->value.d);
+               break;
+       case CONTACTS_MATCH_LESS_THAN_OR_EQUAL:
+               snprintf(out_cond, sizeof(out_cond), "%s <= %lf", field_name, filter->value.d);
+               break;
+       case CONTACTS_MATCH_NOT_EQUAL:
+               snprintf(out_cond, sizeof(out_cond), "%s <> %lf", field_name, filter->value.d);
+               break;
+       case CONTACTS_MATCH_NONE:
+               snprintf(out_cond, sizeof(out_cond), "%s IS NULL", field_name);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : int match rule(%d) is not supported", filter->match);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       *condition = strdup(out_cond);
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_db_create_lli_condition(ctsvc_composite_filter_s *com_filter,
+               ctsvc_attribute_filter_s *filter, char **condition )
+{
+       const char *field_name;
+       char out_cond[CTS_SQL_MAX_LEN] = {0};
+
+       field_name = __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                       com_filter->property_count, QUERY_FILTER, filter->property_id);
+       RETVM_IF(NULL == field_name, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : property id(%d)", filter->property_id);
+
+       switch(filter->match) {
+       case CONTACTS_MATCH_EQUAL:
+               snprintf(out_cond, sizeof(out_cond), "%s = %lld", field_name, filter->value.l);
+               break;
+       case CONTACTS_MATCH_GREATER_THAN:
+               snprintf(out_cond, sizeof(out_cond), "%s > %lld", field_name, filter->value.l);
+               break;
+       case CONTACTS_MATCH_GREATER_THAN_OR_EQUAL:
+               snprintf(out_cond, sizeof(out_cond), "%s >= %lld", field_name, filter->value.l);
+               break;
+       case CONTACTS_MATCH_LESS_THAN:
+               snprintf(out_cond, sizeof(out_cond), "%s < %lld", field_name, filter->value.l);
+               break;
+       case CONTACTS_MATCH_LESS_THAN_OR_EQUAL:
+               snprintf(out_cond, sizeof(out_cond), "%s <= %lld", field_name, filter->value.l);
+               break;
+       case CONTACTS_MATCH_NOT_EQUAL:
+               snprintf(out_cond, sizeof(out_cond), "%s <> %lld", field_name, filter->value.l);
+               break;
+       case CONTACTS_MATCH_NONE:
+               snprintf(out_cond, sizeof(out_cond), "%s IS NULL", field_name);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : int match rule(%d) is not supported", filter->match);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       *condition = strdup(out_cond);
+       return CONTACTS_ERROR_NONE;
+}
+
+#define CTSVC_DB_ESCAPE_CHAR   '\\'
+
+static char * __ctsvc_db_get_str_with_escape(char *str, int len, bool with_escape)
+{
+       int i, j = 0;
+       char temp_str[len*2+1];
+
+       if (false == with_escape)
+               return strdup(str);
+
+       for(i=0;i<len;i++) {
+               if (str[i] == '\'' || str[i] == '_' || str[i] == '%' || str[i] == '\\') {
+                       temp_str[j++] = CTSVC_DB_ESCAPE_CHAR;
+               }
+               temp_str[j++] = str[i];
+       }
+       temp_str[j] = '\0';
+
+       return strdup(temp_str);
+}
+
+static inline int __ctsvc_db_add_str_matching_rule(const char *field_name, int match, char **condition, bool *with_escape)
+{
+       int cond_len = 0;
+       char out_cond[CTS_SQL_MAX_LEN] = {0};
+
+       *with_escape = true;
+       switch(match) {
+       case CONTACTS_MATCH_EXACTLY:
+               cond_len = snprintf(out_cond, sizeof(out_cond), "%s = ?", field_name);
+               *with_escape = false;
+               break;
+       case CONTACTS_MATCH_FULLSTRING:
+               cond_len = snprintf(out_cond, sizeof(out_cond), "%s LIKE ? ESCAPE '%c'", field_name, CTSVC_DB_ESCAPE_CHAR);
+               break;
+       case CONTACTS_MATCH_CONTAINS:
+               cond_len = snprintf(out_cond, sizeof(out_cond), "%s LIKE ('%%' || ? || '%%') ESCAPE '%c'", field_name, CTSVC_DB_ESCAPE_CHAR);
+               break;
+       case CONTACTS_MATCH_STARTSWITH:
+               cond_len = snprintf(out_cond, sizeof(out_cond), "%s LIKE ( ? || '%%') ESCAPE '%c'", field_name, CTSVC_DB_ESCAPE_CHAR);
+               break;
+       case CONTACTS_MATCH_ENDSWITH:
+               cond_len = snprintf(out_cond, sizeof(out_cond), "%s LIKE ('%%' || ?) ESCAPE '%c'", field_name, CTSVC_DB_ESCAPE_CHAR);
+               break;
+       case CONTACTS_MATCH_EXISTS:
+               cond_len = snprintf(out_cond, sizeof(out_cond), "%s IS NOT NULL", field_name);
+               break;
+       default :
+               CTS_ERR("Invalid parameter : int match rule (%d) is not supported", match);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (0 < cond_len)
+               *condition = strdup(out_cond);
+
+       return cond_len;
+}
+
+static inline int __ctsvc_db_create_str_condition(ctsvc_composite_filter_s *com_filter,
+               ctsvc_attribute_filter_s *filter, char **condition, GSList **bind_text)
+{
+       int ret;
+       const char *field_name;
+       char out_cond[CTS_SQL_MAX_LEN] = {0};
+       char *temp = NULL;
+       int cond_len = 0;
+       bool with_escape = true;
+
+       *condition = NULL;
+
+       field_name = __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                       com_filter->property_count, QUERY_FILTER, filter->property_id);
+       RETVM_IF(NULL == field_name, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : property id(%d)", filter->property_id);
+
+       // number_filter condition is only used to find exactly matched number
+       // based on internal logic : _NUMBER_COMPARE_
+       if (filter->property_id == CTSVC_PROPERTY_NUMBER_NUMBER_FILTER
+                       || filter->property_id == CTSVC_PROPERTY_PHONELOG_ADDRESS_FILTER
+                       || filter->property_id == CTSVC_PROPERTY_SPEEDDIAL_NUMBER_FILTER)
+               filter->match = CONTACTS_MATCH_EXACTLY;
+
+       ret = __ctsvc_db_add_str_matching_rule(field_name, filter->match, &temp, &with_escape);
+       RETVM_IF(ret <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "__ctsvc_db_add_str_matching_rule Fail");
+       cond_len = snprintf(out_cond, sizeof(out_cond), "%s", temp);
+       free(temp);
+       temp = NULL;
+
+       if (filter->value.s) {
+               // number filter
+               if (filter->property_id == CTSVC_PROPERTY_NUMBER_NUMBER_FILTER
+                       || filter->property_id == CTSVC_PROPERTY_PHONELOG_ADDRESS_FILTER
+                       || filter->property_id == CTSVC_PROPERTY_SPEEDDIAL_NUMBER_FILTER) {
+                       // number filter is for matching number depends on internal rule _NUMBER_COMPARE_
+                       char clean_num[strlen(filter->value.s)+1+5];    // for cc
+                       char normal_num[strlen(filter->value.s)+1+5];   // for cc
+                       bool add_condition = false;
+                       ret = ctsvc_clean_number(filter->value.s, clean_num, sizeof(clean_num), false);
+                       if (0 < ret) {
+                               ret = ctsvc_normalize_number(clean_num, normal_num, sizeof(normal_num), false);
+                               if (0 < ret) {
+                                       char min_match[strlen(filter->value.s)+1+5];    // for cc
+                                       ret = ctsvc_get_minmatch_number(normal_num, min_match, sizeof(min_match), ctsvc_get_phonenumber_min_match_digit());
+                                       if (CONTACTS_ERROR_NONE == ret) {
+                                               // minmatch filter is to improve performance
+                                               *bind_text = g_slist_append(*bind_text, __ctsvc_db_get_str_with_escape(min_match, strlen(min_match), with_escape));
+
+                                               // _NUMBER_COMPARE_(noraml_num, normalized keyword)
+                                               if (strcmp(normal_num, "+") != 0) {
+                                                       const char *number_field = NULL;
+                                                       if (filter->property_id == CTSVC_PROPERTY_NUMBER_NUMBER_FILTER)
+                                                               number_field = __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                                                               com_filter->property_count, QUERY_FILTER, CTSVC_PROPERTY_NUMBER_NORMALIZED_NUMBER);
+                                                       else if (filter->property_id == CTSVC_PROPERTY_PHONELOG_ADDRESS_FILTER)
+                                                               number_field = __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                                                               com_filter->property_count, QUERY_FILTER, CTSVC_PROPERTY_PHONELOG_NORMALIZED_ADDRESS);
+                                                       else if (filter->property_id == CTSVC_PROPERTY_SPEEDDIAL_NUMBER_FILTER)
+                                                               number_field = __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                                                               com_filter->property_count, QUERY_FILTER, CTSVC_PROPERTY_SPEEDDIAL_NORMALIZED_NUMBER);
+
+                                                       if (number_field) {
+                                                               cond_len += snprintf(out_cond+cond_len, sizeof(out_cond)-cond_len, " AND _NUMBER_COMPARE_(%s, ?, NULL, NULL)", number_field);
+                                                               *bind_text = g_slist_append(*bind_text, strdup(normal_num));
+                                                               add_condition = true;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+
+                       if (add_condition == false) {
+                               // If fail to get normalized number then compare with original number
+                               const char *number_field = NULL;
+                               if (filter->property_id == CTSVC_PROPERTY_NUMBER_NUMBER_FILTER)
+                                       number_field = __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                                       com_filter->property_count, QUERY_FILTER, CTSVC_PROPERTY_NUMBER_NUMBER);
+                               else if (filter->property_id == CTSVC_PROPERTY_PHONELOG_ADDRESS_FILTER)
+                                       number_field = __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                                       com_filter->property_count, QUERY_FILTER, CTSVC_PROPERTY_PHONELOG_ADDRESS);
+                               else if (filter->property_id == CTSVC_PROPERTY_SPEEDDIAL_NUMBER_FILTER)
+                                       number_field = __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                                       com_filter->property_count, QUERY_FILTER, CTSVC_PROPERTY_SPEEDDIAL_NUMBER);
+
+
+                               if (number_field) {
+                                       snprintf(out_cond, sizeof(out_cond), "%s = ?", number_field);
+                                       *bind_text = g_slist_append(*bind_text, strdup(filter->value.s));
+                               }
+                       }
+               }
+               // normalized number
+               else if (filter->property_id == CTSVC_PROPERTY_NUMBER_NORMALIZED_NUMBER
+                               || filter->property_id == CTSVC_PROPERTY_PHONELOG_NORMALIZED_ADDRESS
+                               || filter->property_id == CTSVC_PROPERTY_SPEEDDIAL_NORMALIZED_NUMBER) {
+                       char clean_num[strlen(filter->value.s)+1+5]; // for cc
+                       ret = ctsvc_clean_number(filter->value.s, clean_num, sizeof(clean_num), false);
+                       if (0 < ret) {
+                               bool add_condition = true;
+                               const char *clean_field = NULL;
+                               // has clean number or normalized number
+                               const char *cc = ctsvc_get_network_cc(false);
+                               if (cc && cc[0] == '7' && clean_num[0] == '8') {                // Russia
+                                       char normal_num[strlen(clean_num)+1+5]; // for cc
+                                       ret = ctsvc_normalize_number(clean_num, normal_num, sizeof(normal_num), false);
+                                       if (0 < ret)
+                                               *bind_text = g_slist_append(*bind_text, __ctsvc_db_get_str_with_escape(normal_num, strlen(normal_num), with_escape));
+                                       else
+                                               *bind_text = g_slist_append(*bind_text, __ctsvc_db_get_str_with_escape(clean_num, strlen(clean_num), with_escape));
+                               }
+                               else if (strcmp(clean_num, "+") != 0) {
+                                       *bind_text = g_slist_append(*bind_text, __ctsvc_db_get_str_with_escape(clean_num, strlen(clean_num), with_escape));
+                               }
+                               else
+                                       add_condition = false;
+
+                               if (filter->property_id == CTSVC_PROPERTY_NUMBER_NORMALIZED_NUMBER)
+                                       clean_field = __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                                       com_filter->property_count, QUERY_FILTER, CTSVC_PROPERTY_NUMBER_CLEANED_NUMBER);
+                               else if (filter->property_id == CTSVC_PROPERTY_PHONELOG_NORMALIZED_ADDRESS)
+                                       clean_field =  __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                                               com_filter->property_count, QUERY_FILTER, CTSVC_PROPERTY_PHONELOG_CLEANED_ADDRESS);
+                               else if (filter->property_id == CTSVC_PROPERTY_SPEEDDIAL_NORMALIZED_NUMBER)
+                                       clean_field =  __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                                               com_filter->property_count, QUERY_FILTER, CTSVC_PROPERTY_SPEEDDIAL_CLEANED_NUMBER);
+
+                               if (clean_field) {
+                                       if (add_condition)
+                                               cond_len += snprintf(out_cond+cond_len, sizeof(out_cond)-cond_len, " OR ");
+                                       ret = __ctsvc_db_add_str_matching_rule(clean_field, filter->match, &temp, &with_escape);
+                                       RETVM_IF(ret <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                                                       "__ctsvc_db_add_str_matching_rule Fail");
+                                       cond_len += snprintf(out_cond+cond_len, sizeof(out_cond)-cond_len, "%s", temp);
+                                       free(temp);
+                                       temp = NULL;
+                                       *bind_text = g_slist_append(*bind_text, __ctsvc_db_get_str_with_escape(clean_num, strlen(clean_num), with_escape));
+                               }
+                       }
+                       else if (ret == 0) {
+                               // If fail to get cleaned number then compare with original number
+                               const char *number_field = NULL;
+                               if (filter->property_id == CTSVC_PROPERTY_NUMBER_NORMALIZED_NUMBER)
+                                       number_field = __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                                       com_filter->property_count, QUERY_FILTER, CTSVC_PROPERTY_NUMBER_NUMBER);
+                               else if (filter->property_id == CTSVC_PROPERTY_PHONELOG_NORMALIZED_ADDRESS)
+                                       number_field =  __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                                               com_filter->property_count, QUERY_FILTER, CTSVC_PROPERTY_PHONELOG_ADDRESS);
+                               else if (filter->property_id == CTSVC_PROPERTY_SPEEDDIAL_NORMALIZED_NUMBER)
+                                       number_field =  __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                                               com_filter->property_count, QUERY_FILTER, CTSVC_PROPERTY_SPEEDDIAL_NUMBER);
+
+                               if (number_field) {
+                                       ret = __ctsvc_db_add_str_matching_rule(number_field, filter->match, &temp, &with_escape);
+                                       RETVM_IF(ret <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                                                               "__ctsvc_db_add_str_matching_rule Fail");
+                                       cond_len = snprintf(out_cond, sizeof(out_cond), "%s", temp);
+                                       free(temp);
+                                       temp = NULL;
+                                       *bind_text = g_slist_append(*bind_text, __ctsvc_db_get_str_with_escape(filter->value.s, strlen(filter->value.s), with_escape));
+                               }
+                       }
+                       else
+                               return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               // cleaned number
+               else if (filter->property_id == CTSVC_PROPERTY_NUMBER_CLEANED_NUMBER
+                               || filter->property_id == CTSVC_PROPERTY_PHONELOG_CLEANED_ADDRESS
+                               || filter->property_id == CTSVC_PROPERTY_SPEEDDIAL_CLEANED_NUMBER) {
+                       char clean_num[strlen(filter->value.s)+1+5]; // for cc
+                       ret = ctsvc_clean_number(filter->value.s, clean_num, sizeof(clean_num), false);
+                       if (0 < ret) {
+                               *bind_text = g_slist_append(*bind_text, __ctsvc_db_get_str_with_escape(clean_num, strlen(clean_num), with_escape));
+                       }
+                       else if (ret == 0) {
+                               // If fail to get cleaned number then compare with original number
+                               const char *number_field = NULL;
+                               if (filter->property_id == CTSVC_PROPERTY_NUMBER_CLEANED_NUMBER)
+                                       number_field = __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                                       com_filter->property_count, QUERY_FILTER, CTSVC_PROPERTY_NUMBER_NUMBER);
+                               else if (filter->property_id == CTSVC_PROPERTY_PHONELOG_CLEANED_ADDRESS)
+                                       number_field =  __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                                               com_filter->property_count, QUERY_FILTER, CTSVC_PROPERTY_PHONELOG_ADDRESS);
+                               else if (filter->property_id == CTSVC_PROPERTY_SPEEDDIAL_CLEANED_NUMBER)
+                                       number_field =  __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                                               com_filter->property_count, QUERY_FILTER, CTSVC_PROPERTY_SPEEDDIAL_NUMBER);
+
+                               if (number_field) {
+                                       ret = __ctsvc_db_add_str_matching_rule(number_field, filter->match, &temp, &with_escape);
+                                       RETVM_IF(ret <= 0, CONTACTS_ERROR_INVALID_PARAMETER,
+                                                               "__ctsvc_db_add_str_matching_rule Fail");
+                                       cond_len = snprintf(out_cond, sizeof(out_cond), "%s", temp);
+                                       free(temp);
+                                       temp = NULL;
+                                       *bind_text = g_slist_append(*bind_text, __ctsvc_db_get_str_with_escape(filter->value.s, strlen(filter->value.s), with_escape));
+                               }
+                       }
+                       else
+                               return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               else if (filter->property_id == CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL
+                               || filter->property_id == CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL
+                               || filter->property_id == CTSVC_PROPERTY_MY_PROFILE_IMAGE_THUMBNAIL
+                               || filter->property_id == CTSVC_PROPERTY_IMAGE_PATH) {
+                       if (strncmp(filter->value.s, CTSVC_CONTACT_IMG_FULL_LOCATION, strlen(CTSVC_CONTACT_IMG_FULL_LOCATION)) == 0) {
+                               *bind_text = g_slist_append(*bind_text,
+                                                                       __ctsvc_db_get_str_with_escape(filter->value.s+strlen(CTSVC_CONTACT_IMG_FULL_LOCATION)+1,
+                                                                       strlen(filter->value.s)-strlen(CTSVC_CONTACT_IMG_FULL_LOCATION)-1, with_escape));
+                       }
+                       else
+                               *bind_text = g_slist_append(*bind_text, __ctsvc_db_get_str_with_escape(filter->value.s, strlen(filter->value.s), with_escape));
+               }
+               else if (filter->property_id == CTSVC_PROPERTY_GROUP_IMAGE) {
+                       if (strncmp(filter->value.s, CTS_GROUP_IMAGE_LOCATION, strlen(CTS_GROUP_IMAGE_LOCATION)) == 0) {
+                               *bind_text = g_slist_append(*bind_text,
+                                                                       __ctsvc_db_get_str_with_escape(filter->value.s+strlen(CTS_GROUP_IMAGE_LOCATION)+1,
+                                                                       strlen(filter->value.s)-strlen(CTS_GROUP_IMAGE_LOCATION)-1, with_escape));
+                       }
+                       else
+                               *bind_text = g_slist_append(*bind_text, __ctsvc_db_get_str_with_escape(filter->value.s, strlen(filter->value.s), with_escape));
+               }
+               else if (filter->property_id == CTSVC_PROPERTY_COMPANY_LOGO) {
+                       if (strncmp(filter->value.s, CTS_LOGO_IMAGE_LOCATION, strlen(CTS_LOGO_IMAGE_LOCATION)) == 0) {
+                               *bind_text = g_slist_append(*bind_text,
+                                                                       __ctsvc_db_get_str_with_escape(filter->value.s+strlen(CTS_LOGO_IMAGE_LOCATION)+1,
+                                                                       strlen(filter->value.s)-strlen(CTS_LOGO_IMAGE_LOCATION)-1, with_escape));
+                       }
+                       else
+                               *bind_text = g_slist_append(*bind_text, __ctsvc_db_get_str_with_escape(filter->value.s, strlen(filter->value.s), with_escape));
+
+               }
+               else
+                       *bind_text = g_slist_append(*bind_text, __ctsvc_db_get_str_with_escape(filter->value.s, strlen(filter->value.s), with_escape));
+       }
+
+       *condition = strdup(out_cond);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_db_create_bool_condition(ctsvc_composite_filter_s *com_filter,
+               ctsvc_attribute_filter_s *filter, char **condition )
+{
+       const char *field_name;
+       char out_cond[CTS_SQL_MAX_LEN] = {0};
+
+       field_name = __ctsvc_db_get_property_field_name(com_filter->properties,
+                                                       com_filter->property_count, QUERY_FILTER, filter->property_id);
+       RETVM_IF(NULL == field_name, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : property id(%d)", filter->property_id);
+
+       snprintf(out_cond, sizeof(out_cond), "%s = %d", field_name, filter->value.b?1:0);
+       *condition = strdup(out_cond);
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_create_attribute_condition(ctsvc_composite_filter_s *com_filter,
+               ctsvc_attribute_filter_s *filter, char **condition, GSList **bind_text)
+{
+       int ret;
+       char *cond = NULL;
+
+       RETV_IF(NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       switch (filter->filter_type) {
+       case CTSVC_FILTER_INT:
+               ret = __ctsvc_db_create_int_condition(com_filter, filter, &cond);
+               break;
+       case CTSVC_FILTER_BOOL:
+               ret = __ctsvc_db_create_bool_condition(com_filter, filter, &cond);
+               break;
+       case CTSVC_FILTER_STR:
+               ret = __ctsvc_db_create_str_condition(com_filter, filter, &cond, bind_text);
+               break;
+       case CTSVC_FILTER_LLI:
+               ret = __ctsvc_db_create_lli_condition(com_filter, filter, &cond);
+               break;
+       case CTSVC_FILTER_DOUBLE:
+               ret = __ctsvc_db_create_double_condition(com_filter, filter, &cond);
+               break;
+       default :
+               CTS_ERR("The filter type is not supported (%d)", filter->filter_type);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (CONTACTS_ERROR_NONE == ret)
+               *condition = cond;
+
+       return ret;
+}
+
+#define CTSVC_FILTER_LENGTH    100
+
+// If there are too many condition, sqlite return fail SQLITE_ERROR(1).
+// Expression tree is too large (maximum depth 1000).
+// It is related to SQLITE_LIMIT_EXPR_DEPTH.
+static inline int __ctsvc_db_create_composite_condition(ctsvc_composite_filter_s *com_filter,
+               char **condition, GSList **bind_text)
+{
+       RETV_IF(NULL == com_filter, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       int len;
+       int temp_len;
+       int buf_size;
+       char *cond;
+       char *out_cond = NULL;
+       GSList *cursor_filter;
+       GSList *cursor_ops;
+       ctsvc_filter_s *filter;
+       contacts_filter_operator_e op;
+       GSList *bind;
+       GSList *filters = com_filter->filters;
+       GSList *ops = com_filter->filter_ops;
+
+       *condition = NULL;
+       // the case : did not set filter condition after calling contacts_filter_create()
+       RETV_IF(NULL == filters, CONTACTS_ERROR_NONE);
+
+       cond = NULL;
+       bind = NULL;
+
+       filter = (ctsvc_filter_s *)filters->data;
+       if (filter->filter_type == CTSVC_FILTER_COMPOSITE)
+               __ctsvc_db_create_composite_condition((ctsvc_composite_filter_s *)filter, &cond, bind_text);
+       else
+               __ctsvc_db_create_attribute_condition(com_filter, (ctsvc_attribute_filter_s*)filter, &cond, bind_text);
+
+       buf_size = CTSVC_FILTER_LENGTH;
+       out_cond = calloc(1, buf_size);
+       RETVM_IF(NULL == out_cond, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+       len = 0;
+       if (cond) {
+               temp_len = SAFE_SNPRINTF(&out_cond, &buf_size, len, "(");
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&out_cond, &buf_size, len, cond);
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&out_cond, &buf_size, len, ")");
+               if (temp_len >= 0) len+= temp_len;
+               free(cond);
+       }
+
+       cursor_filter = filters->next;
+       for(cursor_ops=ops; cursor_ops && cursor_filter; cursor_filter=cursor_filter->next, cursor_ops=cursor_ops->next) {
+               cond = NULL;
+               bind = NULL;
+
+               filter = (ctsvc_filter_s *)cursor_filter->data;
+               if (filter->filter_type == CTSVC_FILTER_COMPOSITE)
+                       __ctsvc_db_create_composite_condition((ctsvc_composite_filter_s *)filter, &cond, &bind);
+               else
+                       __ctsvc_db_create_attribute_condition(com_filter, (ctsvc_attribute_filter_s*)filter, &cond, &bind);
+
+               if (cond) {
+                       op = (contacts_filter_operator_e)cursor_ops->data;
+                       if (op == CONTACTS_FILTER_OPERATOR_AND)
+                               temp_len = SAFE_SNPRINTF(&out_cond, &buf_size, len, " AND (");
+                       else
+                               temp_len = SAFE_SNPRINTF(&out_cond, &buf_size, len, " OR (");
+                       if (temp_len >= 0) len+= temp_len;
+
+                       temp_len = SAFE_SNPRINTF(&out_cond, &buf_size, len, cond);
+                       if (temp_len >= 0) len+= temp_len;
+                       temp_len = SAFE_SNPRINTF(&out_cond, &buf_size, len, ")");
+                       if (temp_len >= 0) len+= temp_len;
+
+                       if (bind)
+                               *bind_text = g_slist_concat(*bind_text, bind);
+                       free(cond);
+               }
+       }
+
+       *condition = out_cond;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+// Make and execute 'UPDATE' sqlite statement to update record
+int ctsvc_db_update_record_with_set_query(const char *set, GSList *bind_text, const char *table, int id)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       sqlite3_stmt *stmt = NULL;
+       GSList *cursor = NULL;
+
+       snprintf(query, sizeof(query), "UPDATE %s SET %s WHERE id = %d", table, set, id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       if (bind_text) {
+               int i = 0;
+               for (cursor=bind_text,i=1;cursor;cursor=cursor->next,i++) {
+                       const char *text = cursor->data;
+                       if (text && *text)
+                               ctsvc_stmt_bind_text(stmt, i, text);
+               }
+       }
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+       ctsvc_stmt_finalize(stmt);
+       return ret;
+}
+
+// make 'SET' sqlite statement to update record
+int ctsvc_db_create_set_query(contacts_record_h record, char **set, GSList **bind_text)
+{
+       ctsvc_record_s *s_record;
+       int i = 0;
+       const property_info_s* property_info = NULL;
+       unsigned int property_info_count = 0;
+       char out_set[CTS_SQL_MAX_LEN] = {0};
+       int len = 0;
+       const char *field_name;
+       int ret = CONTACTS_ERROR_NONE;
+
+       RETV_IF(record == NULL, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       s_record = (ctsvc_record_s *)record;
+       if (0 == s_record->property_max_count || NULL == s_record->properties_flags) {
+               CTS_ERR("record don't have properties");
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       property_info = ctsvc_view_get_all_property_infos(s_record->view_uri, &property_info_count);
+
+       for(i=0;i<property_info_count;i++) {
+               if (ctsvc_record_check_property_flag(s_record, property_info[i].property_id, CTSVC_PROPERTY_FLAG_DIRTY)) {
+                       field_name = property_info[i].fields;
+                       if (NULL == field_name)
+                               continue;
+
+                       if (CTSVC_VIEW_CHECK_DATA_TYPE(property_info[i].property_id, CTSVC_VIEW_DATA_TYPE_BOOL)) {
+                               bool tmp = false;
+                               ret = contacts_record_get_bool(record,property_info[i].property_id, &tmp);
+                               if (ret != CONTACTS_ERROR_NONE)
+                                       continue;
+                               if (len != 0)
+                                       len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                               len += snprintf(out_set+len, sizeof(out_set)-len, "%s=%d", field_name, tmp);
+                       }
+                       else if (CTSVC_VIEW_CHECK_DATA_TYPE(property_info[i].property_id, CTSVC_VIEW_DATA_TYPE_INT)) {
+                               int tmp = 0;
+                               ret = contacts_record_get_int(record,property_info[i].property_id, &tmp);
+                               if (ret != CONTACTS_ERROR_NONE)
+                                       continue;
+                               if (len != 0)
+                                       len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                               len += snprintf(out_set+len, sizeof(out_set)-len, "%s=%d", field_name, tmp);
+                       }
+                       else if (CTSVC_VIEW_CHECK_DATA_TYPE(property_info[i].property_id, CTSVC_VIEW_DATA_TYPE_LLI)) {
+                               long long int tmp = 0;
+                               ret = contacts_record_get_lli(record, property_info[i].property_id, &tmp);
+                               if (ret != CONTACTS_ERROR_NONE)
+                                       continue;
+                               if (len != 0)
+                                       len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                               len += snprintf(out_set+len, sizeof(out_set)-len, "%s=%lld", field_name,tmp);
+                       }
+                       else if (CTSVC_VIEW_CHECK_DATA_TYPE(property_info[i].property_id, CTSVC_VIEW_DATA_TYPE_STR)) {
+                               char *tmp = NULL;
+                               ret = contacts_record_get_str_p(record,property_info[i].property_id, &tmp);
+                               if (ret != CONTACTS_ERROR_NONE)
+                                       continue;
+                               if (len != 0)
+                                       len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                               len += snprintf(out_set+len, sizeof(out_set)-len, "%s=?", field_name);
+                               *bind_text = g_slist_append(*bind_text, strdup(SAFE_STR(tmp)));
+                       }
+                       else if (CTSVC_VIEW_CHECK_DATA_TYPE(property_info[i].property_id, CTSVC_VIEW_DATA_TYPE_DOUBLE)) {
+                               double tmp = 0;
+                               ret = contacts_record_get_double(record, property_info[i].property_id, &tmp);
+                               if (ret != CONTACTS_ERROR_NONE)
+                                       continue;
+                               if (len != 0)
+                                       len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                               len += snprintf(out_set+len, sizeof(out_set)-len, "%s=%lf", field_name, tmp);
+                       }
+               }
+       }
+       *set = strdup(out_set);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_create_projection(const char *view_uri, const property_info_s *properties, int ids_count,
+               unsigned int *projections, int pro_count, char **projection)
+{
+       bool first;
+       int i;
+       int len;
+       const char *field_name = NULL;
+       char out_projection[CTS_SQL_MAX_LEN] = {0};
+       char temp[CTS_SQL_MAX_LEN] = {0};
+
+       len = 0;
+       first = true;
+       if (0 < pro_count) {
+               for (i=0;i<pro_count;i++) {
+                       if (projections[i] == CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX) {
+                               snprintf(temp, sizeof(temp), "_NORMALIZE_INDEX_(%s)", ctsvc_get_sort_name_column());
+                               field_name = temp;
+                       }
+                       else
+                               field_name = __ctsvc_db_get_property_field_name(properties, ids_count, QUERY_PROJECTION, projections[i]);
+
+                       if (field_name) {
+                               if (first) {
+                                       len += snprintf(out_projection+len, sizeof(out_projection)-len, "%s", field_name);
+                                       first = false;
+                               }
+                               else
+                                       len += snprintf(out_projection+len, sizeof(out_projection)-len, ", %s", field_name);
+                       }
+               }
+       }
+       else {
+               // add all properties
+               for (i=0;i<ids_count;i++) {
+                       if (CTSVC_VIEW_DATA_TYPE_REC == (properties[i].property_id & CTSVC_VIEW_DATA_TYPE_MASK))
+                               continue;
+
+                       if (properties[i].fields)
+                               field_name = properties[i].fields;
+                       else if (properties[i].property_id == CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX) {
+                               snprintf(temp, sizeof(temp), "_NORMALIZE_INDEX_(%s)", ctsvc_get_sort_name_column());
+                               field_name = temp;
+                       }
+                       else
+                               field_name = ctsvc_get_display_column();
+
+                       if (first) {
+                               len += snprintf(out_projection+len, sizeof(out_projection)-len, "%s", field_name);
+                               first = false;
+                       }
+                       else
+                               len += snprintf(out_projection+len, sizeof(out_projection)-len, ", %s", field_name);
+               }
+       }
+
+       *projection = strdup(out_projection);
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline bool __ctsvc_db_view_has_display_name(const char *view_uri,
+               const property_info_s *properties, int count)
+{
+       int i;
+#ifdef ENABLE_LOG_FEATURE
+       if (0 == strcmp(view_uri, _contacts_person_phone_log._uri))
+               return false;
+#endif // ENABLE_LOG_FEATURE
+
+       for (i=0;i<count;i++) {
+               property_info_s *p = (property_info_s*)&(properties[i]);
+               switch (p->property_id) {
+               case CTSVC_PROPERTY_PERSON_DISPLAY_NAME:
+               case CTSVC_PROPERTY_CONTACT_DISPLAY_NAME:
+                       return true;
+               default:
+                       break;
+               }
+       }
+       return false;
+}
+
+#define SORT_CHECK_LEN 7
+
+int ctsvc_db_make_get_records_query_stmt(ctsvc_query_s *s_query, int offset, int limit, cts_stmt *stmt)
+{
+       char *query = NULL;
+       char temp_str[100] = {0};
+       int query_size = 0;
+       int temp_len = 0;
+       int len;
+       int ret;
+       int i;
+       const char *table;
+       const char *sortkey = NULL;
+       char *condition = NULL;
+       char *projection = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor;
+
+       ret = ctsvc_db_get_table_name(s_query->view_uri, &table);
+       RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "Invalid parameter : view uri (%s)", s_query->view_uri);
+
+       ret = __ctsvc_db_create_projection(s_query->view_uri, s_query->properties, s_query->property_count,
+                                                               s_query->projection, s_query->projection_count, &projection);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_db_create_projection is failed(%d)", ret);
+               return ret;
+       }
+
+       query_size = CTS_SQL_MAX_LEN;
+       query = calloc(1, query_size);
+       RETVM_IF(NULL == query, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+
+       len = 0;
+       if (s_query->distinct)
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, "SELECT DISTINCT ");
+       else
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, "SELECT ");
+       if (temp_len >= 0) len+= temp_len;
+       temp_len = SAFE_SNPRINTF(&query, &query_size, len, projection);
+       if (temp_len >= 0) len+= temp_len;
+       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " FROM ");
+       if (temp_len >= 0) len+= temp_len;
+
+       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " (");
+       if (temp_len >= 0) len+= temp_len;
+       temp_len = SAFE_SNPRINTF(&query, &query_size, len, table);
+       if (temp_len >= 0) len+= temp_len;
+       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " )");
+       if (temp_len >= 0) len+= temp_len;
+
+       if (s_query->filter) {
+               ret = __ctsvc_db_create_composite_condition(s_query->filter, &condition, &bind_text);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("__ctsvc_db_create_composite_condition is failed(%d)", ret);
+                       free(projection);
+                       return ret;
+               }
+               if (condition && *condition) {
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " WHERE (");
+                       if (temp_len >= 0) len+= temp_len;
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, condition);
+                       if (temp_len >= 0) len+= temp_len;
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " )");
+                       if (temp_len >= 0) len+= temp_len;
+               }
+       }
+
+       // If the view_uri has display_name, default sortkey is display_name
+       if (__ctsvc_db_view_has_display_name(s_query->view_uri, s_query->properties, s_query->property_count))
+               sortkey = ctsvc_get_sort_column();
+
+       if (s_query->sort_property_id) {
+               const char *field_name;
+
+               switch(s_query->sort_property_id) {
+               case CTSVC_PROPERTY_PERSON_DISPLAY_NAME:
+               case CTSVC_PROPERTY_CONTACT_DISPLAY_NAME:
+                       if (sortkey) {
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " ORDER BY ");
+                               if (temp_len >= 0) len+= temp_len;
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, sortkey);
+                               if (temp_len >= 0) len+= temp_len;
+                               if (false == s_query->sort_asc) {
+                                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " DESC ");
+                                       if (temp_len >= 0) len+= temp_len;
+                               }
+                       }
+                       break;
+               default :
+                       field_name = __ctsvc_db_get_property_field_name(s_query->properties,
+                                                               s_query->property_count, QUERY_SORTKEY, s_query->sort_property_id);
+                       if (field_name) {
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " ORDER BY ");
+                               if (temp_len >= 0) len+= temp_len;
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, field_name);
+                               if (temp_len >= 0) len+= temp_len;
+
+//                             if (sortkey)
+//                                     len += snprintf(query+len, sizeof(query)-len, ", %s", sortkey);
+                               if (false == s_query->sort_asc) {
+                                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " DESC ");
+                                       if (temp_len >= 0) len+= temp_len;
+                               }
+                       }
+                       else if (sortkey) {
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " ORDER BY ");
+                               if (temp_len >= 0) len+= temp_len;
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, sortkey);
+                               if (temp_len >= 0) len+= temp_len;
+                       }
+                       break;
+               }
+       }
+       else if (sortkey) {
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " ORDER BY ");
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, sortkey);
+               if (temp_len >= 0) len+= temp_len;
+       }
+       else if (0 == strcmp(s_query->view_uri, CTSVC_VIEW_URI_GROUP)) {
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " ORDER BY group_prio");
+               if (temp_len >= 0) len+= temp_len;
+       }
+
+       if (0 != limit) {
+               snprintf(temp_str, sizeof(temp_str), " LIMIT %d", limit);
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, temp_str);
+               if (temp_len >= 0) len+= temp_len;
+               if (0 < offset) {
+                       snprintf(temp_str, sizeof(temp_str), " OFFSET %d", offset);
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, temp_str);
+                       if (temp_len >= 0) len+= temp_len;
+               }
+       }
+
+       free(condition);
+       free(projection);
+
+       ret = ctsvc_query_prepare(query, stmt);
+       free(query);
+       if(NULL == *stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       free(cursor->data);
+               g_slist_free(bind_text);
+               return ret;
+       }
+
+       for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
+               ctsvc_stmt_bind_copy_text(*stmt, i, cursor->data, strlen(cursor->data));
+
+       for (cursor=bind_text;cursor;cursor=cursor->next)
+               free(cursor->data);
+       g_slist_free(bind_text);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_get_records_with_query_exec(ctsvc_query_s *query, int offset,
+               int limit, contacts_list_h* out_list )
+{
+       int ret;
+       int i;
+       int type;
+       cts_stmt stmt = NULL;
+       contacts_list_h list = NULL;
+
+       ret = ctsvc_db_make_get_records_query_stmt(query, offset, limit, &stmt);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_db_make_get_records_query_stmt(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               int field_count;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(query->view_uri, (contacts_record_h*)&record);
+
+               if (0 == query->projection_count)
+                       field_count = query->property_count;
+               else {
+                       field_count = query->projection_count;
+
+                       if( CONTACTS_ERROR_NONE != ctsvc_record_set_projection_flags(record, query->projection, query->projection_count, query->property_count) )
+                       {
+                               ASSERT_NOT_REACHED("To set projection is failed.\n");
+                       }
+               }
+
+               for(i=0;i<field_count;i++) {
+                       int property_id;
+                       if (0 == query->projection_count)
+                               property_id = query->properties[i].property_id;
+                       else {
+                               property_id = query->projection[i];
+                       }
+                       type = __ctsvc_db_get_property_type(query->properties, query->property_count, property_id);
+                       if (type == CTSVC_VIEW_DATA_TYPE_INT)
+                               ctsvc_record_set_int(record, property_id, ctsvc_stmt_get_int(stmt, i));
+                       else if (type == CTSVC_VIEW_DATA_TYPE_STR)
+                               ctsvc_record_set_str(record, property_id, ctsvc_stmt_get_text(stmt, i));
+                       else if (type == CTSVC_VIEW_DATA_TYPE_BOOL)
+                               ctsvc_record_set_bool(record, property_id, (ctsvc_stmt_get_int(stmt, i)?true:false));
+                       else if (type == CTSVC_VIEW_DATA_TYPE_LLI)
+                               ctsvc_record_set_lli(record, property_id, ctsvc_stmt_get_int64(stmt, i));
+                       else if (type == CTSVC_VIEW_DATA_TYPE_DOUBLE)
+                               ctsvc_record_set_double(record, property_id, ctsvc_stmt_get_dbl(stmt, i));
+                       else
+                               CTS_ERR("DB error : unknown type (%d)", type);
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_get_all_records_exec(const char *view_uri, const property_info_s* properties, int ids_count,
+               const char *projection, int offset,     int limit, contacts_list_h* out_list )
+{
+       char query[CTS_SQL_MAX_LEN] = {0};
+       const char *table;
+       int len;
+       int ret;
+       int i;
+       int type;
+       cts_stmt stmt = NULL;
+       contacts_list_h list = NULL;
+       const char *sortkey;
+
+       ret = ctsvc_db_get_table_name(view_uri, &table);
+       RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "Invalid parameter : view uri (%s)", view_uri);
+
+       len = snprintf(query, sizeof(query), "SELECT %s FROM ", projection);
+
+       len += snprintf(query+len, sizeof(query)-len, " (%s)", table);
+
+       if (__ctsvc_db_view_has_display_name(view_uri, properties, ids_count)) {
+               sortkey = ctsvc_get_sort_column();
+               len += snprintf(query+len, sizeof(query)-len, " ORDER BY %s", sortkey);
+       } else if (0 == strcmp(view_uri, CTSVC_VIEW_URI_GROUP))
+               len += snprintf(query+len, sizeof(query)-len, " ORDER BY group_prio");
+
+       if (0 != limit) {
+               len += snprintf(query+len, sizeof(query)-len, " LIMIT %d", limit);
+               if (0 < offset)
+                       len += snprintf(query+len, sizeof(query)-len, " OFFSET %d", offset);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               contacts_record_create(view_uri, &record);
+               for(i=0;i<ids_count;i++) {
+                       type = (properties[i].property_id & CTSVC_VIEW_DATA_TYPE_MASK);
+                       if (type == CTSVC_VIEW_DATA_TYPE_INT)
+                               ctsvc_record_set_int(record, properties[i].property_id, ctsvc_stmt_get_int(stmt, i));
+                       else if (type == CTSVC_VIEW_DATA_TYPE_STR)
+                               ctsvc_record_set_str(record, properties[i].property_id, ctsvc_stmt_get_text(stmt, i));
+                       else if (type == CTSVC_VIEW_DATA_TYPE_BOOL)
+                               ctsvc_record_set_bool(record, properties[i].property_id, (ctsvc_stmt_get_int(stmt, i)?true:false));
+                       else if (type == CTSVC_VIEW_DATA_TYPE_LLI)
+                               ctsvc_record_set_lli(record, properties[i].property_id, ctsvc_stmt_get_int64(stmt, i));
+                       else if (type == CTSVC_VIEW_DATA_TYPE_DOUBLE)
+                               ctsvc_record_set_double(record, properties[i].property_id, ctsvc_stmt_get_dbl(stmt, i));
+                       else
+                               CTS_ERR("DB error : unknown type (%d)", type);
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = (contacts_list_h)list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_get_all_records( const char* view_uri, int offset, int limit, contacts_list_h* out_list )
+{
+       int ret;
+       unsigned int count;
+       char *projection;
+
+       const property_info_s *p = ctsvc_view_get_all_property_infos(view_uri, &count);
+       ret = __ctsvc_db_create_projection(view_uri, p, count, NULL, 0, &projection);
+       RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_db_create_projection is failed(%d)", ret);
+
+       ret = __ctsvc_db_get_all_records_exec(view_uri, p, count, projection, offset, limit, out_list);
+       free(projection);
+
+       return ret;
+}
+
+static inline bool __ctsvc_db_view_can_keyword_search(const char *view_uri)
+{
+       RETV_IF(NULL == view_uri, false);
+
+       if (0 == strcmp(view_uri, CTSVC_VIEW_URI_PERSON)
+               || 0 == strcmp(view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_CONTACT)
+               || 0 == strcmp(view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_NUMBER)
+               || 0 == strcmp(view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_EMAIL)
+               || 0 == strcmp(view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP)
+               || 0 == strcmp(view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP_ASSIGNED)
+               || 0 == strcmp(view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP_NOT_ASSIGNED)) {
+               return true;
+       }
+       return false;
+}
+
+static char* __ctsvc_db_make_search_keyword(const char *keyword)
+{
+       int size;
+       if (keyword == NULL)
+               return NULL;
+
+       size = strlen(keyword);
+       if (strstr(keyword, " ") != NULL) {
+               int i = 0;
+               int j = 0;
+               char search_keyword[size * 2+1];
+               for(i=0;i<size;i++) {
+                       if (j>0 && keyword[i] == ' ') {
+                               if (search_keyword[j-1] != ' ' )
+                                       search_keyword[j++] = '*';
+                       }
+                       search_keyword[j++] = keyword[i];
+               }
+               if (j > 0 && search_keyword[j-1] != ' ')
+                       search_keyword[j++] = '*';
+               search_keyword[j] = '\0';
+               return strdup(search_keyword);
+       }
+       else {
+               char search_keyword[size+2];
+               snprintf(search_keyword, sizeof(search_keyword), "%s*", keyword);
+               return strdup(search_keyword);
+       }
+}
+
+static int __ctsvc_db_append_search_query_range(char **query, int *query_size, int len, int range, char *name, char *number, char *data)
+{
+       bool first = true;
+       int temp_len;
+
+       temp_len = SAFE_SNPRINTF(query, query_size, len, " '");
+       if (temp_len >= 0) len += temp_len;
+       if (range & CONTACTS_SEARCH_RANGE_NAME) {
+               temp_len = SAFE_SNPRINTF(query, query_size, len, "name:");
+               if (temp_len >= 0) len += temp_len;
+               temp_len = SAFE_SNPRINTF(query, query_size, len, name);
+               if (temp_len >= 0) len += temp_len;
+               first = false;
+       }
+
+       if (range & CONTACTS_SEARCH_RANGE_NUMBER) {
+               if (first == false) {
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, " OR ");
+                       if (temp_len >= 0) len += temp_len;
+               }
+               temp_len = SAFE_SNPRINTF(query, query_size, len, "number:");
+               if (temp_len >= 0) len += temp_len;
+               temp_len = SAFE_SNPRINTF(query, query_size, len, number);
+               if (temp_len >= 0) len += temp_len;
+               first = false;
+       }
+
+       if (range & CONTACTS_SEARCH_RANGE_DATA) {
+               if (first == false) {
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, " OR ");
+                       if (temp_len >= 0) len += temp_len;
+               }
+               temp_len = SAFE_SNPRINTF(query, query_size, len, "data:");
+               if (temp_len >= 0) len += temp_len;
+               temp_len = SAFE_SNPRINTF(query, query_size, len, data);
+               if (temp_len >= 0) len += temp_len;
+               first = false;
+       }
+
+       temp_len = SAFE_SNPRINTF(query, query_size, len, "' ");
+       if (temp_len >= 0) len += temp_len;
+       return len;
+}
+
+static int __ctsvc_db_append_search_query(const char *src, char **query, int *query_size, int len, int range)
+{
+       bool phonenumber = true;
+       int i = 0;
+       int keyword_temp_len = 0;
+       int temp_len;
+
+       if( ctsvc_is_phonenumber(src) == false || strcmp(src, "+") == 0)
+       {
+               phonenumber = false;
+       }
+
+       if (strstr(src, "@")) {
+               // If the search key is email address format, DO NOT search it from NAME
+               range &= ~CONTACTS_SEARCH_RANGE_NAME;
+       }
+
+       if (strcmp(src, "+") == 0) {
+               range &= ~CONTACTS_SEARCH_RANGE_NUMBER;
+       }
+
+       char* keyword = NULL;
+       int keyword_size = 0;
+       bool use_replaced_keyword = true;
+       // full width characters -> half width characters (apply to only FW ASCII & some symbols)
+       if ( ctsvc_get_halfwidth_string(src, &keyword, &keyword_size) != CONTACTS_ERROR_NONE ) {
+               CTS_ERR("UChar converting error : ctsvc_get_halfwidth_string() Failed");
+               keyword = (char*)src;
+               use_replaced_keyword = false;
+       }
+
+       char *search_keyword = NULL;
+       search_keyword = __ctsvc_db_make_search_keyword(keyword);
+       RETVM_IF(NULL == search_keyword, CONTACTS_ERROR_OUT_OF_MEMORY, "__ctsvc_db_make_search_keyword() return NULL");
+
+       if (phonenumber) {
+               temp_len = SAFE_SNPRINTF(query, query_size, len, "(SELECT contact_id FROM ");
+               if (temp_len >=0) len += temp_len;
+               temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_SEARCH_INDEX);
+               if (temp_len >=0) len += temp_len;
+               temp_len = SAFE_SNPRINTF(query, query_size, len, " WHERE ");
+               if (temp_len >=0) len += temp_len;
+               temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_SEARCH_INDEX);
+               if (temp_len >=0) len += temp_len;
+               temp_len = SAFE_SNPRINTF(query, query_size, len, " MATCH ");
+               if (temp_len >=0) len += temp_len;
+
+               temp_len = __ctsvc_db_append_search_query_range(query, query_size, len,
+                                                               range, search_keyword, search_keyword, search_keyword);
+               if (temp_len >=0) len = temp_len;
+
+               if (range & CONTACTS_SEARCH_RANGE_NUMBER) {
+                       // to find contact which has number including keyword
+                       // FTS can only startwiths search
+                       char clean_number[SAFE_STRLEN(keyword)+1];
+                       int err = ctsvc_clean_number(keyword, clean_number, sizeof(clean_number), false);
+                       if (0 < err) {
+                               const char *cc = ctsvc_get_network_cc(false);
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, " UNION SELECT contact_id FROM ");
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_PHONE_LOOKUP);
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, " WHERE number LIKE '%%");
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, clean_number);
+                               if (temp_len >=0) len += temp_len;
+
+                               if (cc && cc[0] == '7' && clean_number[0] == '8') {             // Russia
+                                       char normal_num[strlen(clean_number)+1+5];      // for cc
+                                       int ret;
+                                       ret = ctsvc_normalize_number(clean_number, normal_num, sizeof(normal_num), false);
+                                       if (0 < ret) {
+                                               temp_len = SAFE_SNPRINTF(query, query_size, len, "%%' OR number LIKE '%%");
+                                               if (temp_len >= 0) len+= temp_len;
+                                               temp_len = SAFE_SNPRINTF(query, query_size, len, normal_num);
+                                               if (temp_len >= 0) len+= temp_len;
+                                       }
+                               }
+
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, "%%' ");
+                               if (temp_len >=0) len += temp_len;
+                       }
+               }
+               temp_len = SAFE_SNPRINTF(query, query_size, len, ")");
+               if (temp_len >=0) len += temp_len;
+       }
+       else {
+               char *normalized_name = NULL;
+               int lang = CTSVC_LANG_OTHERS;
+               bool add_brace = false;
+               char *hiragana = NULL;
+               char *search_hiragana = NULL;
+               bool need_union = false;
+
+               lang = ctsvc_normalize_str(keyword, &normalized_name);
+               temp_len = SAFE_SNPRINTF(query, query_size, len, "( ");
+               if (temp_len >=0) len += temp_len;
+
+               if (CTSVC_LANG_JAPANESE == lang) {
+                       ctsvc_convert_japanese_to_hiragana(keyword, &hiragana);
+                       search_hiragana = __ctsvc_db_make_search_keyword(hiragana);
+               }
+
+               if (range & CONTACTS_SEARCH_RANGE_NUMBER) {
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, "SELECT contact_id FROM ");
+                       if (temp_len >=0) len += temp_len;
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_SEARCH_INDEX);
+                       if (temp_len >=0) len += temp_len;
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, " WHERE ");
+                       if (temp_len >=0) len += temp_len;
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_SEARCH_INDEX);
+                       if (temp_len >=0) len += temp_len;
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, " MATCH ");
+                       if (temp_len >=0) len += temp_len;
+
+                       if (CTSVC_LANG_JAPANESE == lang) {
+                               temp_len = __ctsvc_db_append_search_query_range(query, query_size, len,
+                                                                       CONTACTS_SEARCH_RANGE_NUMBER, NULL, search_hiragana, NULL);
+                               if (temp_len >=0) len = temp_len;
+                       }
+                       else {
+                               temp_len = __ctsvc_db_append_search_query_range(query, query_size, len,
+                                                                       CONTACTS_SEARCH_RANGE_NUMBER, NULL, search_keyword, NULL);
+                               if (temp_len >=0) len = temp_len;
+                       }
+                       need_union = true;
+               }
+
+               if (range & CONTACTS_SEARCH_RANGE_DATA) {
+                       if (need_union) {
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, " UNION SELECT contact_id FROM (");
+                               if (temp_len >=0) len += temp_len;
+                               add_brace = true;
+                       }
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, " SELECT contact_id FROM ");
+                       if (temp_len >=0) len += temp_len;
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_SEARCH_INDEX);
+                       if (temp_len >=0) len += temp_len;
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, " WHERE ");
+                       if (temp_len >=0) len += temp_len;
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_SEARCH_INDEX);
+                       if (temp_len >=0) len += temp_len;
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, " MATCH ");
+                       if (temp_len >=0) len += temp_len;
+
+                       if (CTSVC_LANG_JAPANESE == lang) {
+                               temp_len = __ctsvc_db_append_search_query_range(query, query_size, len,
+                                                                       CONTACTS_SEARCH_RANGE_DATA, NULL, NULL, search_hiragana);
+                               if (temp_len >=0) len = temp_len;
+                       }
+                       else {
+                               keyword_temp_len = strlen(search_keyword);
+                               // replace '-' -> '_' because FTS does not support search '-'
+                               char temp_str[keyword_temp_len+1];
+                               for(i=0;i<keyword_temp_len;i++) {
+                                       if (search_keyword[i] == '-') {
+                                               temp_str[i] = '_';
+                                       }
+                                       else
+                                               temp_str[i] = search_keyword[i];
+                               }
+                               temp_str[i] = '\0';
+                               temp_len = __ctsvc_db_append_search_query_range(query, query_size, len,
+                                                                       CONTACTS_SEARCH_RANGE_DATA, NULL, NULL, temp_str);
+                               if (temp_len >=0) len = temp_len;
+                       }
+                       if (add_brace) {
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, ") ");
+                               if (temp_len >=0) len += temp_len;
+                               add_brace = false;
+                       }
+                       need_union = true;
+               }
+
+               if (range & CONTACTS_SEARCH_RANGE_NAME) {
+                       if (need_union) {
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, " UNION SELECT contact_id FROM ");
+                               if (temp_len >=0) len += temp_len;
+                       }
+
+                       if (CTSVC_LANG_KOREAN == lang) {                // chosung search
+                               char *chosung = calloc(1, strlen(keyword) * 5);
+                               char *korean_pattern = calloc(1, strlen(keyword) * 5);
+                               char *search_chosung = NULL;
+                               int count = 0;
+
+                               // If try to find '홍길동' by 'ㄱ동'
+                               // search by 'ㄱㄷ' in search_index table
+                               // intersect
+                               // search by '*ㄱ*동*' in name_lookup table
+
+                               count = ctsvc_get_chosung(keyword, chosung, strlen(keyword) * 5 );
+                               ctsvc_get_korean_search_pattern(keyword, korean_pattern, strlen(keyword) * 5 );
+
+                               if (count > 0)
+                                       search_chosung = __ctsvc_db_make_search_keyword(chosung);
+                               else
+                                       search_chosung = __ctsvc_db_make_search_keyword(keyword);
+
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, " (SELECT contact_id FROM ");
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_SEARCH_INDEX);
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, " WHERE ");
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_SEARCH_INDEX);
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, " MATCH ");
+                               if (temp_len >=0) len += temp_len;
+
+                               temp_len = __ctsvc_db_append_search_query_range(query, query_size, len,
+                                                                       CONTACTS_SEARCH_RANGE_NAME, search_chosung, NULL, NULL);
+                               if (temp_len >=0) len = temp_len;
+
+                               temp_len = SAFE_SNPRINTF(query, query_size, len,  " INTERSECT SELECT contact_id FROM ");
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_NAME_LOOKUP);
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, " WHERE name GLOB '*");
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, korean_pattern);
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, "*' " );
+                               if (temp_len >=0) len += temp_len;
+
+                               free(chosung);
+                               free(korean_pattern);
+                               free(search_chosung);
+                       }
+                       else if (CTSVC_LANG_JAPANESE == lang) { // hiragana search
+                               temp_len = SAFE_SNPRINTF(query, query_size, len,  " (SELECT contact_id FROM ");
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_SEARCH_INDEX);
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, " WHERE ");
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_SEARCH_INDEX);
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, " MATCH ");
+                               if (temp_len >=0) len += temp_len;
+
+                               temp_len = __ctsvc_db_append_search_query_range(query, query_size, len,
+                                                                       CONTACTS_SEARCH_RANGE_NAME, search_hiragana, NULL, NULL);
+                               if (temp_len >=0) len = temp_len;
+                       }
+                       else if (CONTACTS_ERROR_NONE <= lang) { // normalized string search
+                               char *search_normal_name = NULL;
+                               search_normal_name = __ctsvc_db_make_search_keyword(normalized_name);
+                               temp_len = SAFE_SNPRINTF(query, query_size, len,  " (SELECT contact_id FROM ");
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_SEARCH_INDEX);
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, " WHERE ");
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_SEARCH_INDEX);
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, " MATCH ");
+                               if (temp_len >=0) len += temp_len;
+
+                               temp_len = __ctsvc_db_append_search_query_range(query, query_size, len,
+                                                                       CONTACTS_SEARCH_RANGE_NAME, search_normal_name, NULL, NULL);
+                               if (temp_len >=0) len = temp_len;
+                               free(search_normal_name);
+                       }
+                       else {          // original keyword search
+                               temp_len = SAFE_SNPRINTF(query, query_size, len,  " (SELECT contact_id FROM ");
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_SEARCH_INDEX);
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, " WHERE ");
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_SEARCH_INDEX);
+                               if (temp_len >=0) len += temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, " MATCH ");
+                               if (temp_len >=0) len += temp_len;
+
+                               temp_len = __ctsvc_db_append_search_query_range(query, query_size, len,
+                                                                       CONTACTS_SEARCH_RANGE_NAME, search_keyword, NULL, NULL);
+                               if (temp_len >=0) len = temp_len;
+                       }
+
+                       int j = 0;
+                       keyword_temp_len = strlen(keyword);
+                       char temp_str[keyword_temp_len*2+1];
+                       for(i=0;i<keyword_temp_len;i++) {
+                               if (keyword[i] == '\'' || keyword[i] == '_' || keyword[i] == '%' || keyword[i] == '\\') {
+                                       temp_str[j++] = CTSVC_DB_ESCAPE_CHAR;
+                               }
+                               temp_str[j++] = keyword[i];
+                       }
+                       temp_str[j] = '\0';
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, " UNION SELECT contact_id FROM ");
+                       if (temp_len >=0) len += temp_len;
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, CTS_TABLE_NAME_LOOKUP);
+                       if (temp_len >=0) len += temp_len;
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, " WHERE name LIKE '");
+                       if (temp_len >=0) len += temp_len;
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, temp_str);
+                       if (temp_len >=0) len += temp_len;
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, "%%' ESCAPE '\\') ");  //CTSVC_DB_ESCAPE_CHAR
+                       if (temp_len >=0) len += temp_len;
+               }
+
+               free(normalized_name);
+               free(hiragana);
+               free(search_hiragana);
+
+               temp_len = SAFE_SNPRINTF(query, query_size, len, " ) ");
+               if (temp_len >=0) len += temp_len;
+       }
+
+       free(search_keyword);
+
+       if( use_replaced_keyword )
+               free(keyword);
+
+       return len;
+}
+
+static int __ctsvc_db_search_records_character_count(const char *keyword)
+{
+       int char_len = 0;
+       int str_len = strlen(keyword);
+       int i;
+       int count = 0;
+       bool after_space = true;
+
+       for (i=0;i<str_len; i+=char_len) {
+               char_len = ctsvc_check_utf8(keyword[i]);
+               if (char_len == 1 && keyword[i] == ' ') {
+                       after_space = true;
+                       continue;
+               }
+               if (after_space == true) {
+                       count++;
+                       after_space = false;
+               }
+       }
+       return count;
+}
+
+static int __ctsvc_db_search_records_append_sort(const char *view_uri,
+               const char *sortkey, const char *keyword, int len, char **query, int *query_size)
+{
+       int i;
+       int temp_len;
+
+       if (ctsvc_get_primary_sort() == CTSVC_SORT_KOREAN) {
+               contacts_name_sorting_order_e order;
+               const char *field = NULL;
+               char *temp_keyword = NULL;
+               contacts_setting_get_name_sorting_order(&order);
+
+               if (CONTACTS_NAME_SORTING_ORDER_FIRSTLAST == order)
+                       field = "display_name";
+               else
+                       field = "reverse_display_name";
+
+               if (ctsvc_has_chosung(keyword)) {
+                       if (__ctsvc_db_search_records_character_count(keyword) == 1) {
+                               int j;
+                               int m;
+                               int char_len = 0;
+                               int keyword_len = strlen(keyword);
+                               bool first = true;
+                               char temp_str[((250*keyword_len) + 30) * SORT_CHECK_LEN + 50];
+                               int temp_str_len = 0;
+
+                               temp_str_len = snprintf(temp_str+temp_str_len, sizeof(temp_str)-temp_str_len,
+                                                               " ORDER BY CASE ");
+
+                               for (j=1;j<=SORT_CHECK_LEN;j++) {
+                                       temp_str_len += snprintf(temp_str+temp_str_len, sizeof(temp_str)-temp_str_len,
+                                                                                       " WHEN ");
+                                       for (i=0, m=0;i<keyword_len;i+=char_len, m++) {
+                                               char temp[10] = {0};
+                                               int k = -1;
+                                               char_len = ctsvc_check_utf8(keyword[i]);
+                                               if (char_len <= 0) {
+                                                       char_len = 1;
+                                                       continue;
+                                               }
+                                               memcpy(temp, &keyword[i], char_len);
+                                               temp[char_len] = '\0';
+
+                                               if (char_len == 1 && temp[0] == ' ')
+                                                       continue;
+                                               if (first == false && i != 0)
+                                                       temp_str_len += snprintf(temp_str+temp_str_len, sizeof(temp_str)-temp_str_len, " AND ");
+                                               if (ctsvc_is_chosung(temp)) {
+                                                       for(k=0;k<19;k++) {
+                                                               if (strcmp(hangul_syllable[k][0], temp) == 0)
+                                                                       break;
+                                                       }
+                                               }
+
+                                               if (0<=k && k<=18) {
+                                                       temp_str_len += snprintf(temp_str+temp_str_len, sizeof(temp_str)-temp_str_len,
+                                                                                       " ((substr(%s, %d, 1) BETWEEN '%s' AND '%s') OR (substr(%s, %d, 1) = '%s'))  ",
+                                                                                       field, j+m, hangul_syllable[k][1], hangul_syllable[k][2],
+                                                                                       field, j+m, temp);
+                                               }
+                                               else
+                                                       temp_str_len += snprintf(temp_str+temp_str_len, sizeof(temp_str)-temp_str_len,
+                                                                                       " (substr(%s, %d, 1) = '%s')  ",
+                                                                                       field, j+m, temp);
+                                               if (first)
+                                                       first = false;
+                                       }
+                                       temp_str_len += snprintf(temp_str+temp_str_len, sizeof(temp_str)-temp_str_len,
+                                                               " THEN %d ", j);
+                               }
+                               temp_str_len = snprintf(temp_str+temp_str_len, sizeof(temp_str)-temp_str_len,
+                                                               " ELSE %d END ", j);
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, temp_str);
+                               if (temp_len >= 0) len+= temp_len;
+                       }
+                       else {
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, " ORDER BY ");
+                               if (temp_len >= 0) len+= temp_len;
+                               temp_len = SAFE_SNPRINTF(query, query_size, len, sortkey);
+                               if (temp_len >= 0) len+= temp_len;
+                       }
+               }
+               else {
+                       temp_keyword = __ctsvc_db_get_str_with_escape((char*)keyword, strlen((char*)keyword), true);
+                       RETVM_IF(NULL == temp_keyword, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+                       char temp_str[CTS_SQL_MIN_LEN + (strlen(field) + strlen(temp_keyword)) * SORT_CHECK_LEN];
+                       snprintf(temp_str, sizeof(temp_str),
+                                                       " ORDER BY "
+                                                       "       CASE "
+                                                       "               WHEN %s LIKE '%s%%' THEN 1 "
+                                                       "               WHEN %s LIKE '_%s%%' THEN 2 "
+                                                       "               WHEN %s LIKE '__%s%%' THEN 3 "
+                                                       "               WHEN %s LIKE '___%s%%' THEN 4 "
+                                                       "               WHEN %s LIKE '____%s%%' THEN 5 "
+                                                       "               WHEN %s LIKE '_____%s%%' THEN 6 "
+                                                       "               WHEN %s LIKE '______%s%%' THEN 7 "
+                                                       "               ELSE 8 "
+                                                       "       END ",
+                                                       field, temp_keyword, field, temp_keyword,
+                                                       field, temp_keyword, field, temp_keyword,
+                                                       field, temp_keyword, field, temp_keyword,
+                                                               field, temp_keyword);
+                       temp_len = SAFE_SNPRINTF(query, query_size, len, temp_str);
+                       if (temp_len >= 0) len+= temp_len;
+                               free(temp_keyword);
+               }
+               temp_len = SAFE_SNPRINTF(query, query_size, len, " , ");
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(query, query_size, len, sortkey);
+               if (temp_len >= 0) len+= temp_len;
+       }
+       else {
+               temp_len = SAFE_SNPRINTF(query, query_size, len, " ORDER BY ");
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(query, query_size, len, sortkey);
+               if (temp_len >= 0) len+= temp_len;
+       }
+       return len;
+}
+
+static int __ctsvc_db_search_records_exec(const char *view_uri, const property_info_s* properties,
+               int ids_count, const char *projection, const char *keyword, int offset, int limit, int range, contacts_list_h* out_list )
+{
+       char *query = NULL;
+       char temp_query[CTS_SQL_MAX_LEN];
+       int query_size;
+       int temp_len;
+       const char *table;
+       int len = 0;
+       int ret;
+       int i;
+       int type;
+       cts_stmt stmt = NULL;
+       contacts_list_h list = NULL;
+       ctsvc_record_type_e r_type;
+       const char *sortkey = NULL;
+
+       ret = ctsvc_db_get_table_name(view_uri, &table);
+       RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "Invalid parameter : view uri (%s)", view_uri);
+
+       query_size = CTS_SQL_MAX_LEN;
+       query = calloc(1, query_size);
+       RETVM_IF(NULL == query, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+
+       len = 0;
+
+       if (strcmp(keyword, "+") == 0) {
+               range &= ~CONTACTS_SEARCH_RANGE_NUMBER;
+       }
+
+       if (0 == strcmp(view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_CONTACT)
+                       || 0 == strcmp(view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP)
+                       || 0 == strcmp(view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP_ASSIGNED)
+                       || 0 == strcmp(view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP_NOT_ASSIGNED)) {
+               if (range & CONTACTS_SEARCH_RANGE_EMAIL) {
+                       free(query);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, "SELECT ");
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, projection);
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " FROM ");
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, table);
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " WHERE contact_id IN ");
+               if (temp_len >= 0) len+= temp_len;
+
+               temp_len = __ctsvc_db_append_search_query(keyword, &query, &query_size, len, range);
+               if (temp_len >= 0) len = temp_len;
+       }
+       else if (0 == strcmp(view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_NUMBER)) {
+               bool need_union = false;
+               if (range & CONTACTS_SEARCH_RANGE_DATA || range & CONTACTS_SEARCH_RANGE_EMAIL) {
+                       free(query);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, "SELECT ");
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, projection);
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " FROM (");
+               if (temp_len >= 0) len+= temp_len;
+
+               if (range & CONTACTS_SEARCH_RANGE_NUMBER) {
+                       char clean_num[strlen(keyword)+1+5]; // for cc
+                       // Original number can include '-' or special character. So search by cleaned_number
+                       // If contact has 010 1234 5678 (normalized number is +cc 10 1234 5678),
+                       //      then the contack should be searched by keyword +cc 10 1234 5678
+                       ret = ctsvc_clean_number(keyword, clean_num, sizeof(clean_num), false);
+                       if (0 < ret) {
+                               const char *cc = ctsvc_get_network_cc(false);
+
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " SELECT * FROM ");
+                               if (temp_len >= 0) len+= temp_len;
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, table);
+                               if (temp_len >= 0) len+= temp_len;
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " WHERE normalized_number LIKE '%%");
+                               if (temp_len >= 0) len+= temp_len;
+
+                               if (cc && cc[0] == '7' && clean_num[0] == '8') {                // Russia
+                                       char normal_num[strlen(clean_num)+1+5]; // for cc
+                                       ret = ctsvc_normalize_number(clean_num, normal_num, sizeof(normal_num), false);
+                                       if (0 < ret) {
+                                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, normal_num);
+                                       }
+                                       else
+                                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, clean_num);
+                               }
+                               else
+                                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, clean_num);
+                               if (temp_len >= 0) len+= temp_len;
+
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, "%%' OR cleaned_number LIKE '%%");
+                               if (temp_len >= 0) len+= temp_len;
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, clean_num);
+                               if (temp_len >= 0) len+= temp_len;
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, "%%' ");
+                               if (temp_len >= 0) len+= temp_len;
+                       }
+                       else {
+                               char *temp_keyword = __ctsvc_db_get_str_with_escape((char*)keyword, strlen((char*)keyword), true);
+                               if (NULL == temp_keyword) {
+                                       CTS_ERR("__ctsvc_db_get_str_with_escape() return NULL");
+                                       free(query);
+                                       return CONTACTS_ERROR_OUT_OF_MEMORY;
+                               }
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " SELECT * FROM ");
+                               if (temp_len >= 0) len+= temp_len;
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, table);
+                               if (temp_len >= 0) len+= temp_len;
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " WHERE number LIKE '%%");
+                               if (temp_len >= 0) len+= temp_len;
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, temp_keyword);
+                               if (temp_len >= 0) len+= temp_len;
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, "%%' ESCAPE '\\'");
+                               if (temp_len >= 0) len+= temp_len;
+                               free(temp_keyword);
+                       }
+                       need_union = true;
+               }
+
+               if (range & CONTACTS_SEARCH_RANGE_NAME) {
+                       if (need_union) {
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " UNION ");
+                               if (temp_len >= 0) len+= temp_len;
+                       }
+                       snprintf(temp_query, sizeof(temp_query),
+                                               "SELECT "CTSVC_DB_VIEW_PERSON_CONTACT".*, "
+                                                                       "temp_data.* "
+                                                       "FROM "CTSVC_DB_VIEW_PERSON_CONTACT" "
+                                                       "JOIN (SELECT id number_id, "
+                                                                       "contact_id, "
+                                                                       "data1 type, "
+                                                                       "is_primary_default, "
+                                                                       "data2 label, "
+                                                                       "data3 number, "
+                                                                       "data4 minmatch, "
+                                                                       "data5 normalized_number, "
+                                                                       "data6 cleaned_number "
+                                               "FROM "CTS_TABLE_DATA" WHERE datatype = %d AND is_my_profile = 0) temp_data "
+                                               "ON temp_data.contact_id = "CTSVC_DB_VIEW_PERSON_CONTACT".contact_id ",
+                                                       CTSVC_DATA_NUMBER);
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, temp_query);
+                       if (temp_len >= 0) len+= temp_len;
+
+                       // search contact from search_index table by name and join the results
+                       // FTS can support to serach with multiple words
+                       // If contact display_name is 'abc def', then the contact should be searched by 'def'
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " JOIN ");
+                       if (temp_len >= 0) len+= temp_len;
+                       temp_len = __ctsvc_db_append_search_query(keyword, &query, &query_size, len, CONTACTS_SEARCH_RANGE_NAME);
+                       if (temp_len >= 0) len = temp_len;
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " temp_search_index ON ");
+                       if (temp_len >= 0) len+= temp_len;
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, CTSVC_DB_VIEW_PERSON_CONTACT);
+                       if (temp_len >= 0) len+= temp_len;
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, ".name_contact_id = temp_search_index.contact_id ");
+                       if (temp_len >= 0) len+= temp_len;
+               }
+
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " ) ");
+               if (temp_len >= 0) len+= temp_len;
+       }
+       else if (0 == strcmp(view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_EMAIL)) {
+               bool need_union = false;
+               if (range & CONTACTS_SEARCH_RANGE_NUMBER || range & CONTACTS_SEARCH_RANGE_DATA) {
+                       free(query);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, "SELECT ");
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, projection);
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " FROM (");
+               if (temp_len >= 0) len+= temp_len;
+               if (range & CONTACTS_SEARCH_RANGE_EMAIL) {
+                       // search contact which has email address started with keyword
+                       char *temp_keyword = __ctsvc_db_get_str_with_escape((char*)keyword, strlen((char*)keyword), true);
+                       if (NULL == temp_keyword) {
+                               CTS_ERR("__ctsvc_db_get_str_with_escape() return NULL");
+                               free(query);
+                               return CONTACTS_ERROR_OUT_OF_MEMORY;
+                       }
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, "SELECT * FROM ");
+                       if (temp_len >= 0) len+= temp_len;
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, table);
+                       if (temp_len >= 0) len+= temp_len;
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " WHERE email LIKE '");
+                       if (temp_len >= 0) len+= temp_len;
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, temp_keyword);
+                       if (temp_len >= 0) len+= temp_len;
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, "%%' ESCAPE '\\'");
+                       if (temp_len >= 0) len+= temp_len;
+                       free(temp_keyword);
+                       need_union = true;
+               }
+
+               if (range & CONTACTS_SEARCH_RANGE_NAME) {
+                       if (need_union) {
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " UNION ");
+                               if (temp_len >= 0) len+= temp_len;
+                       }
+
+                       snprintf(temp_query, sizeof(temp_query),
+                                               "SELECT "CTSVC_DB_VIEW_PERSON_CONTACT".*, "
+                                                                       "temp_data.* "
+                                                       "FROM "CTSVC_DB_VIEW_PERSON_CONTACT" "
+                                               "JOIN (SELECT id email_id, "
+                                                                       "contact_id, "
+                                                                       "data1 type, "
+                                                                       "is_primary_default, "
+                                                                       "data2 label, "
+                                                                       "data3 email "
+                                       "FROM "CTS_TABLE_DATA" WHERE datatype = %d AND is_my_profile = 0) temp_data "
+                       "ON temp_data.contact_id = "CTSVC_DB_VIEW_PERSON_CONTACT".contact_id",
+                                                       CTSVC_DATA_EMAIL);
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, temp_query);
+                       if (temp_len >= 0) len+= temp_len;
+
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " JOIN ");
+                       if (temp_len >= 0) len+= temp_len;
+                       temp_len = __ctsvc_db_append_search_query(keyword, &query, &query_size, len, CONTACTS_SEARCH_RANGE_NAME);
+                       if (temp_len >= 0) len = temp_len;
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " temp_search_index ON ");
+                       if (temp_len >= 0) len+= temp_len;
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, CTSVC_DB_VIEW_PERSON_CONTACT);
+                       if (temp_len >= 0) len+= temp_len;
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, ".name_contact_id = temp_search_index.contact_id ");
+                       if (temp_len >= 0) len+= temp_len;
+               }
+
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " ) ");
+               if (temp_len >= 0) len+= temp_len;
+       }
+       else {          // CTSVC_VIEW_URI_PERSON
+               if (range & CONTACTS_SEARCH_RANGE_EMAIL) {
+                       free(query);
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+
+               snprintf(temp_query, sizeof(temp_query), "SELECT %s FROM %s, "
+                                       "(SELECT person_id person_id_in_contact, addressbook_id "
+                                                       "FROM "CTS_TABLE_CONTACTS " "
+                                                       "WHERE deleted = 0 AND contact_id IN ",
+                                                       projection, table);
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, temp_query);
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = __ctsvc_db_append_search_query(keyword, &query, &query_size, len, range);
+               if (temp_len >= 0) len = temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, "GROUP BY person_id_in_contact) temp_contacts ON ");
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, table);
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, ".person_id = temp_contacts.person_id_in_contact");
+               if (temp_len >= 0) len+= temp_len;
+       }
+
+       if (__ctsvc_db_view_has_display_name(view_uri, properties, ids_count))
+               sortkey = ctsvc_get_sort_column();
+
+       if (sortkey) {
+               len = __ctsvc_db_search_records_append_sort(view_uri, sortkey, keyword, len , &query, &query_size);
+       }
+       else if (0 == strcmp(view_uri, CTSVC_VIEW_URI_GROUP)) {
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " ORDER BY group_prio");
+               if (temp_len >= 0) len+= temp_len;
+       }
+
+       if (0 != limit) {
+               snprintf(temp_query, sizeof(temp_query), " LIMIT %d", limit);
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, temp_query);
+               if (temp_len >= 0) len+= temp_len;
+
+               if (0 < offset) {
+                       snprintf(temp_query, sizeof(temp_query), " OFFSET %d", offset);
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, temp_query);
+                       if (temp_len >= 0) len+= temp_len;
+               }
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       free(query);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       r_type = ctsvc_view_get_record_type(view_uri);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               if( r_type == CTSVC_RECORD_PERSON )
+               {
+                       unsigned int *project = malloc(sizeof(unsigned int)*ids_count);
+                       for(i=0;i<ids_count;i++)
+                       {
+                               project[i] = properties[i].property_id;
+                       }
+
+                       int ret = ctsvc_db_person_create_record_from_stmt_with_projection(stmt, project, ids_count, &record);
+
+                       free(project);
+
+                       if( CONTACTS_ERROR_NONE != ret )
+                       {
+                               CTS_ERR("DB error : make record Failed(%d)", ret);
+                       }
+               }
+               else {
+                       contacts_record_create(view_uri, &record);
+
+                       for(i=0;i<ids_count;i++) {
+                               type = (properties[i].property_id & CTSVC_VIEW_DATA_TYPE_MASK);
+                               if (type == CTSVC_VIEW_DATA_TYPE_INT)
+                                       ctsvc_record_set_int(record, properties[i].property_id, ctsvc_stmt_get_int(stmt, i));
+                               else if (type == CTSVC_VIEW_DATA_TYPE_STR)
+                                       ctsvc_record_set_str(record, properties[i].property_id, ctsvc_stmt_get_text(stmt, i));
+                               else if (type == CTSVC_VIEW_DATA_TYPE_BOOL)
+                                       ctsvc_record_set_bool(record, properties[i].property_id, (ctsvc_stmt_get_int(stmt, i)?true:false));
+                               else if (type == CTSVC_VIEW_DATA_TYPE_LLI)
+                                       ctsvc_record_set_lli(record, properties[i].property_id, ctsvc_stmt_get_int64(stmt, i));
+                               else if (type == CTSVC_VIEW_DATA_TYPE_DOUBLE)
+                                       ctsvc_record_set_double(record, properties[i].property_id, ctsvc_stmt_get_dbl(stmt, i));
+                               else
+                                       CTS_ERR("DB error : unknown type (%d)", type);
+                       }
+               }
+
+               ctsvc_list_prepend(list, record);
+       }
+
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_search_records(const char* view_uri, const char *keyword,
+               int offset, int limit, contacts_list_h* out_list)
+{
+       int ret;
+       unsigned int count;
+       char *projection;
+       const property_info_s *p;
+       bool can_keyword_search = false;
+       int range = CONTACTS_SEARCH_RANGE_NAME | CONTACTS_SEARCH_RANGE_NUMBER | CONTACTS_SEARCH_RANGE_DATA;
+
+       RETVM_IF(NULL == keyword, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : keyword is NULL");
+
+       can_keyword_search = __ctsvc_db_view_can_keyword_search(view_uri);
+       RETVM_IF(false == can_keyword_search, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : can not keyword search");
+
+       p = ctsvc_view_get_all_property_infos(view_uri, &count);
+       ret = __ctsvc_db_create_projection(view_uri, p, count, NULL, 0, &projection);
+       RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_db_create_projection is failed(%d)", ret);
+
+       ret = __ctsvc_db_search_records_exec(view_uri, p, count, projection, keyword, offset, limit, range, out_list);
+       free(projection);
+
+       return ret;
+}
+
+static int __ctsvc_db_search_records_with_range(const char* view_uri, const char *keyword,
+               int offset, int limit, int range, contacts_list_h* out_list)
+{
+       int ret;
+       unsigned int count;
+       char *projection;
+       const property_info_s *p;
+       bool can_keyword_search = false;
+
+       RETVM_IF(NULL == keyword, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : keyword is NULL");
+
+       can_keyword_search = __ctsvc_db_view_can_keyword_search(view_uri);
+       RETVM_IF(false == can_keyword_search, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : can not keyword search");
+
+       p = ctsvc_view_get_all_property_infos(view_uri, &count);
+       ret = __ctsvc_db_create_projection(view_uri, p, count, NULL, 0, &projection);
+       RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_db_create_projection is failed(%d)", ret);
+
+       ret = __ctsvc_db_search_records_exec(view_uri, p, count, projection, keyword, offset, limit, range, out_list);
+       free(projection);
+
+       return ret;
+}
+
+static inline int __ctsvc_db_search_records_with_query_exec(ctsvc_query_s *s_query, const char *projection,
+       const char *condition, GSList *bind, const char *keyword, int offset, int limit, contacts_list_h * out_list )
+{
+       char *query = NULL;
+       int query_size;
+       int temp_len;
+       int len;
+       int ret;
+       int i;
+       int type;
+       GSList *cursor;
+       cts_stmt stmt = NULL;
+       contacts_list_h list = NULL;
+       const char *table;
+       const char *sortkey = NULL;
+       int range = CONTACTS_SEARCH_RANGE_NAME | CONTACTS_SEARCH_RANGE_NUMBER | CONTACTS_SEARCH_RANGE_DATA;
+
+       RETV_IF(NULL == projection || '\0' == *projection, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       ret = ctsvc_db_get_table_name(s_query->view_uri, &table);
+       RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "Invalid parameter : view uri (%s)", s_query->view_uri);
+
+       query_size = CTS_SQL_MAX_LEN;
+       query = calloc(1, query_size);
+       RETVM_IF(NULL == query, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NULL");
+       len = 0;
+
+       if (s_query->distinct)
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, "SELECT DISTINCT ");
+       else
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, "SELECT ");
+       if (temp_len >= 0) len+= temp_len;
+       temp_len = SAFE_SNPRINTF(&query, &query_size, len, projection);
+       if (temp_len >= 0) len+= temp_len;
+       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " FROM ");
+       if (temp_len >= 0) len+= temp_len;
+
+       if (0 == strcmp(s_query->view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_CONTACT)
+                       || 0 == strcmp(s_query->view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP)
+                       || 0 == strcmp(s_query->view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP_ASSIGNED)
+                       || 0 == strcmp(s_query->view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP_NOT_ASSIGNED)) {
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, table);
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " WHERE ");
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, table);
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, ".contact_id IN ");
+               if (temp_len >= 0) len+= temp_len;
+       }
+       else if (0 == strcmp(s_query->view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_NUMBER)
+                       || 0 == strcmp(s_query->view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_EMAIL)) {
+               free(query);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       else {          // CTSVC_VIEW_URI_PERSON
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, table);
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, ", "
+                                               "(SELECT contact_id, person_id person_id_in_contact, addressbook_id FROM ");
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, CTS_TABLE_CONTACTS);
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " WHERE deleted = 0) temp_contacts ON ");
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, table);
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, ".person_id = temp_contacts.person_id_in_contact WHERE temp_contacts.contact_id IN ");
+               if (temp_len >= 0) len+= temp_len;
+       }
+
+       temp_len = __ctsvc_db_append_search_query(keyword, &query, &query_size, len, range);
+       if (temp_len >= 0) len = temp_len;
+
+       if (condition && *condition) {
+               len += snprintf(query+len, sizeof(query)-len, " AND (%s)", condition);
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " AND (");
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, condition);
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " )");
+               if (temp_len >= 0) len+= temp_len;
+       }
+
+       if (__ctsvc_db_view_has_display_name(s_query->view_uri, s_query->properties, s_query->property_count))
+               sortkey = ctsvc_get_sort_column();
+
+       if (s_query->sort_property_id) {
+               const char *field_name;
+
+               switch(s_query->sort_property_id) {
+               case CTSVC_PROPERTY_PERSON_DISPLAY_NAME:
+               case CTSVC_PROPERTY_CONTACT_DISPLAY_NAME:
+                       if (sortkey) {
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " ORDER BY ");
+                               if (temp_len >= 0) len+= temp_len;
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, sortkey);
+                               if (temp_len >= 0) len+= temp_len;
+                               if (false == s_query->sort_asc) {
+                                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " DESC ");
+                                       if (temp_len >= 0) len+= temp_len;
+                               }
+                       }
+                       break;
+               default :
+                       field_name = __ctsvc_db_get_property_field_name(s_query->properties,
+                                                               s_query->property_count, QUERY_SORTKEY, s_query->sort_property_id);
+                       if (field_name) {
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " ORDER BY ");
+                               if (temp_len >= 0) len+= temp_len;
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, field_name);
+                               if (temp_len >= 0) len+= temp_len;
+//                             if (sortkey)
+//                                     len += snprintf(query+len, sizeof(query)-len, ", %s", sortkey);
+                               if (false == s_query->sort_asc) {
+                                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " DESC ");
+                                       if (temp_len >= 0) len+= temp_len;
+                               }
+                       }
+                       else if (sortkey) {
+                               len += snprintf(query+len, sizeof(query)-len, " ORDER BY %s", sortkey);
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " ORDER BY ");
+                               if (temp_len >= 0) len+= temp_len;
+                               temp_len = SAFE_SNPRINTF(&query, &query_size, len, sortkey);
+                               if (temp_len >= 0) len+= temp_len;
+                       }
+                       break;
+               }
+       }
+       else if (sortkey) {
+               len = __ctsvc_db_search_records_append_sort(s_query->view_uri, sortkey, keyword, len, &query, &query_size);
+       }
+       else if (0 == strcmp(s_query->view_uri, CTSVC_VIEW_URI_GROUP)) {
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " ORDER BY group_prio");
+               if (temp_len >= 0) len+= temp_len;
+       }
+
+       if (0 != limit) {
+               char temp_str[20] = {0};
+               snprintf(temp_str, sizeof(temp_str), " LIMIT %d", limit);
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, temp_str);
+               if (temp_len >= 0) len+= temp_len;
+
+               if (0 < offset) {
+                       snprintf(temp_str, sizeof(temp_str), " OFFSET %d", offset);
+                       temp_len = SAFE_SNPRINTF(&query, &query_size, len, temp_str);
+                       if (temp_len >= 0) len+= temp_len;
+               }
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       free(query);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       i = 1;
+       len = g_slist_length(bind);
+       for (cursor=bind; cursor;cursor=cursor->next, i++)
+               ctsvc_stmt_bind_text(stmt, i, cursor->data);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               if( ctsvc_view_get_record_type(s_query->view_uri) == CTSVC_RECORD_PERSON ) {
+                       unsigned int ids_count;
+                       unsigned int *project;
+                       if (0 == s_query->projection_count)
+                               ids_count = s_query->property_count;
+                       else
+                               ids_count = s_query->projection_count;
+
+                       project = malloc(sizeof(unsigned int)*ids_count);
+
+                       for(i=0;i<ids_count;i++) {
+                               if (0 == s_query->projection_count)
+                                       project[i] = s_query->properties[i].property_id;
+                               else
+                                       project[i] = s_query->projection[i];
+                       }
+
+                       ret = ctsvc_db_person_create_record_from_stmt_with_projection(stmt, project, ids_count, &record);
+                       free(project);
+
+                       if( CONTACTS_ERROR_NONE != ret )
+                               CTS_ERR("DB error : make record Failed(%d)", ret);
+               }
+               else {
+                       contacts_record_create(s_query->view_uri, (contacts_record_h*)&record);
+                       int field_count;
+                       if (0 == s_query->projection_count)
+                               field_count = s_query->property_count;
+                       else
+                       {
+                               field_count = s_query->projection_count;
+
+                               if( CONTACTS_ERROR_NONE != ctsvc_record_set_projection_flags(record, s_query->projection, s_query->projection_count, s_query->property_count) )
+                               {
+                                       ASSERT_NOT_REACHED("To set projection is failed.\n");
+                               }
+                       }
+
+                       for(i=0;i<field_count;i++) {
+                               int property_id;
+
+                               if (0 == s_query->projection_count)
+                                       property_id = s_query->properties[i].property_id;
+                               else
+                                       property_id = s_query->projection[i];
+
+                               type = __ctsvc_db_get_property_type(s_query->properties, s_query->property_count, s_query->projection[i]);
+                               if (type == CTSVC_VIEW_DATA_TYPE_INT)
+                                       ctsvc_record_set_int(record,property_id, ctsvc_stmt_get_int(stmt, i));
+                               else if (type == CTSVC_VIEW_DATA_TYPE_STR)
+                                       ctsvc_record_set_str(record, property_id, ctsvc_stmt_get_text(stmt, i));
+                               else if (type == CTSVC_VIEW_DATA_TYPE_BOOL)
+                                       ctsvc_record_set_bool(record, property_id, (ctsvc_stmt_get_int(stmt, i)?true:false));
+                               else if (type == CTSVC_VIEW_DATA_TYPE_LLI)
+                                       ctsvc_record_set_lli(record, property_id, ctsvc_stmt_get_int64(stmt, i));
+                               else if (type == CTSVC_VIEW_DATA_TYPE_DOUBLE)
+                                       ctsvc_record_set_double(record, property_id, ctsvc_stmt_get_dbl(stmt, i));
+                               else
+                                       CTS_ERR("DB error : unknown type (%d)", type);
+                       }
+               }
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       *out_list = list;
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_search_records_with_query( contacts_query_h query, const char *keyword,
+               int offset, int limit, contacts_list_h* out_list)
+{
+       int ret;
+       char *condition = NULL;
+       char *projection;
+       ctsvc_query_s *s_query;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       bool can_keyword_search;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETVM_IF(NULL == keyword, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : keyword is NULL");
+       s_query = (ctsvc_query_s *)query;
+
+       can_keyword_search = __ctsvc_db_view_can_keyword_search(s_query->view_uri);
+       RETVM_IF(false == can_keyword_search, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : can not keyword search");
+
+       ret = __ctsvc_db_create_projection(s_query->view_uri, s_query->properties, s_query->property_count,
+                                                               s_query->projection, s_query->projection_count, &projection);
+       RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_db_create_projection is failed(%d)", ret);
+
+       if (s_query->filter) {
+               ret = __ctsvc_db_create_composite_condition(s_query->filter, &condition, &bind_text);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("__ctsvc_db_create_composite_condition is failed(%d)", ret);
+                       free(projection);
+                       return ret;
+               }
+       }
+
+       ret = __ctsvc_db_search_records_with_query_exec(s_query, projection, condition, bind_text, keyword, offset, limit, out_list);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_db_search_records_with_query_exec is failed(%d)", ret);
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       free(cursor->data);
+               g_slist_free(bind_text);
+
+               free(condition);
+               free(projection);
+               return ret;
+       }
+
+       for (cursor=bind_text;cursor;cursor=cursor->next)
+               free(cursor->data);
+       g_slist_free(bind_text);
+
+       free(condition);
+       free(projection);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+typedef struct {
+       contacts_list_h list;
+       int *ids;
+       int count;
+       unsigned int index;
+       const char *view_uri;
+       void *cb;
+       void *user_data;
+}ctsvc_bulk_info_s;
+
+static int __ctsvc_db_insert_records(contacts_list_h list, int **ids)
+{
+       int ret;
+       int index;
+       int *id = NULL;
+       int count;
+       contacts_record_h record = NULL;
+
+       ret = contacts_list_get_count(list, &count);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("contacts_list_get_count() failed(%d)", ret);
+               return ret;
+       }
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_begin_trans is failed(%d)", ret);
+
+       id = calloc(count, sizeof(int));
+
+       contacts_list_first(list);
+       index = 0;
+       do {
+               ret = contacts_list_get_current_record_p(list, &record);
+               if( CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("contacts_list_get_current_record_p is faild(%d)", ret);
+                       ctsvc_end_trans(false);
+                       free(id);
+                       return ret;
+               }
+
+               ret = contacts_db_insert_record(record, &id[index++]);
+               if( ret != CONTACTS_ERROR_NONE ) {
+                       CTS_ERR("contacts_db_insert_record is faild(%d)", ret);
+                       ctsvc_end_trans(false);
+                       free(id);
+                       return ret;
+               }
+       }while (CONTACTS_ERROR_NONE  == contacts_list_next(list));
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               free(id);
+               return ret;
+       }
+
+       if (ids)
+               *ids = id;
+       else
+               free(id);
+       return CONTACTS_ERROR_NONE;
+}
+
+#ifdef _CONTACTS_NATIVE
+static gboolean __ctsvc_db_insert_idler(void *data)
+{
+       int ret;
+       ctsvc_bulk_info_s *info = data;
+       contacts_db_insert_result_cb cb;
+
+       ret = __ctsvc_db_insert_records(info->list, &info->ids);
+
+       if (info->cb) {
+               cb = info->cb;
+               if( CONTACTS_ERROR_NONE != ret) {
+                       cb(ret, NULL, 0, info->user_data);
+               }
+               else {
+                       int count = 0;
+                       contacts_list_get_count(info->list, &count);
+                       cb(ret, info->ids, count, info->user_data);
+               }
+       }
+       contacts_list_destroy(info->list, true);
+       free(info->ids);
+       free(info);
+       return false;
+}
+#endif
+
+static int __ctsvc_db_delete_records(const char* view_uri, int ids[], int count)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int index;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_begin_trans is failed(%d)", ret);
+
+       index = 0;
+       do {
+               ret = contacts_db_delete_record(view_uri, ids[index++]);
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       CTS_DBG("the record is not exist : %d", ret);
+                       continue;
+               }
+               else if( ret != CONTACTS_ERROR_NONE ) {
+                       CTS_ERR("contacts_db_delete_record is faild(%d)", ret);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+       } while(index < count);
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+#ifdef _CONTACTS_NATIVE
+static gboolean __ctsvc_db_delete_idler(void *data)
+{
+       int ret;
+       ctsvc_bulk_info_s *info = data;
+       contacts_db_result_cb cb;
+
+       ret = __ctsvc_db_delete_records(info->view_uri, info->ids, info->count);
+
+       if (info->cb) {
+               cb = info->cb;
+               cb(ret, info->user_data);
+       }
+       free(info->ids);
+       free(info);
+       return false;
+}
+#endif
+
+static int __ctsvc_db_update_records( contacts_list_h list)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int count;
+       contacts_record_h record;
+
+       ret = contacts_list_get_count(list, &count);
+       RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "contacts_list_get_count is falied(%d)", ret);
+       RETVM_IF(count <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : count is 0");
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_begin_trans is failed(%d)", ret);
+
+       contacts_list_first(list);
+       do {
+               ret = contacts_list_get_current_record_p(list, &record);
+               if( CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("contacts_list_get_current_record_p is faild(%d)", ret);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+
+               ret = contacts_db_update_record(record);
+               if( ret != CONTACTS_ERROR_NONE ) {
+                       CTS_ERR("contacts_db_update_record is faild(%d)", ret);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(list));
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+#ifdef _CONTACTS_NATIVE
+static gboolean __ctsvc_db_update_idler(void *data)
+{
+       int ret;
+       ctsvc_bulk_info_s *info = data;
+       contacts_db_result_cb cb;
+
+       ret = __ctsvc_db_update_records(info->list);
+
+       if (info->cb) {
+               cb = info->cb;
+               cb(ret, info->user_data);
+       }
+       contacts_list_destroy(info->list, true);
+       free(info);
+       return false;
+}
+#endif
+
+static int __ctsvc_db_get_count_exec(const char *view_uri, const property_info_s* properties, int ids_count,
+               const char *projection, int *out_count )
+{
+       char query[CTS_SQL_MAX_LEN] = {0};
+       const char *table;
+       int len;
+       int ret;
+
+       ret = ctsvc_db_get_table_name(view_uri, &table);
+       RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "Invalid parameter : view uri (%s)", view_uri);
+
+       len = snprintf(query, sizeof(query), "SELECT COUNT(*) FROM (SELECT %s FROM ", projection);
+
+       len += snprintf(query+len, sizeof(query)-len, "  (%s)", table);
+
+       len += snprintf(query+len, sizeof(query)-len, " ) ");
+
+       ret = ctsvc_query_get_first_int_result(query, out_count);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret , "DB error : ctsvc_query_get_first_int_result() Failed(%d)", ret);
+
+       return ret;
+}
+
+static int __ctsvc_db_get_count( const char* view_uri, int *out_count)
+{
+       int ret;
+       unsigned int count;
+       char *projection;
+
+       const property_info_s *p = ctsvc_view_get_all_property_infos(view_uri, &count);
+       ret = __ctsvc_db_create_projection(view_uri, p, count, NULL, 0, &projection);
+       RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_db_create_projection is failed(%d)", ret);
+
+       __ctsvc_db_get_count_exec(view_uri, p, count, projection, out_count);
+       free(projection);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_get_count_with_query_exec(ctsvc_query_s *s_query, const char *projection,
+       const char *condition, GSList *bind_text, int *out_count )
+{
+       char *query = NULL;
+       int query_size;
+       int temp_len;
+       int len;
+       int ret;
+       const char *table;
+
+       RETV_IF(NULL == projection || '\0' == *projection, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       ret = ctsvc_db_get_table_name(s_query->view_uri, &table);
+       RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "Invalid parameter : view uri (%s)", s_query->view_uri);
+
+       query_size = CTS_SQL_MAX_LEN;
+       query = calloc(1, query_size);
+       RETVM_IF(NULL == query, CONTACTS_ERROR_OUT_OF_MEMORY, "calloc() return NUL");
+       len = 0;
+       if (s_query->distinct) {
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, "SELECT COUNT(*) FROM (SELECT DISTINCT ");
+       }
+       else {
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, "SELECT COUNT(*) FROM (SELECT ");
+       }
+       if (temp_len >= 0) len+= temp_len;
+       temp_len = SAFE_SNPRINTF(&query, &query_size, len, projection);
+       if (temp_len >= 0) len+= temp_len;
+       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " FROM ");
+       if (temp_len >= 0) len+= temp_len;
+
+       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " ( ");
+       if (temp_len >= 0) len+= temp_len;
+       temp_len = SAFE_SNPRINTF(&query, &query_size, len,  table);
+       if (temp_len >= 0) len+= temp_len;
+
+       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " ) ");
+       if (temp_len >= 0) len+= temp_len;
+
+       if (condition && *condition) {
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " WHERE ( ");
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, condition);
+               if (temp_len >= 0) len+= temp_len;
+               temp_len = SAFE_SNPRINTF(&query, &query_size, len, " ) ");
+               if (temp_len >= 0) len+= temp_len;
+       }
+
+       temp_len = SAFE_SNPRINTF(&query, &query_size, len, " ) ");
+       if (temp_len >= 0) len+= temp_len;
+
+       if (bind_text) {
+               cts_stmt stmt;
+               GSList *cursor;
+               int i;
+               ret = ctsvc_query_prepare(query, &stmt);
+               free(query);
+               RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+               for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
+                       ctsvc_stmt_bind_copy_text(stmt, i, cursor->data, strlen(cursor->data));
+               ret = ctsvc_stmt_get_first_int_result(stmt, out_count);
+               RETVM_IF(CONTACTS_ERROR_NONE != ret, ret , "DB error : ctsvc_stmt_get_first_int_result() Failed(%d)", ret);
+       }
+       else {
+               ret = ctsvc_query_get_first_int_result(query, out_count);
+               free(query);
+               RETVM_IF(CONTACTS_ERROR_NONE != ret, ret , "DB error : ctsvc_query_get_first_int_result() Failed(%d)", ret);
+       }
+       return ret;
+}
+
+static int __ctsvc_db_get_count_with_query( contacts_query_h query, int *out_count)
+{
+       int ret;
+       char *condition = NULL;
+       char *projection = NULL;
+       ctsvc_query_s *s_query;
+       GSList *bind_text = NULL;
+       GSList *cursor;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s *)query;
+
+       if (s_query->filter) {
+               ret = __ctsvc_db_create_composite_condition(s_query->filter, &condition, &bind_text);
+               RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_db_create_composite_condition is failed(%d)", ret);
+       }
+
+       ret = __ctsvc_db_create_projection(s_query->view_uri, s_query->properties, s_query->property_count,
+                                                               s_query->projection, s_query->projection_count, &projection);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("__ctsvc_db_create_projection is failed(%d)", ret);
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       free(cursor->data);
+               g_slist_free(bind_text);
+               free(condition);
+               return ret;
+       }
+
+       ret = __ctsvc_db_get_count_with_query_exec(s_query, projection, condition, bind_text, out_count);
+       for (cursor=bind_text;cursor;cursor=cursor->next)
+               free(cursor->data);
+       g_slist_free(bind_text);
+
+       free(condition);
+       free(projection);
+
+       return ret;
+}
+
+API int contacts_db_get_records_with_query( contacts_query_h query, int offset, int limit,
+       contacts_list_h* out_list )
+{
+       int ret = CONTACTS_ERROR_NONE;
+       ctsvc_db_plugin_info_s* plugin_info = NULL;
+       ctsvc_query_s *s_query;
+
+       RETV_IF(NULL == out_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_list = NULL;
+
+       RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER);
+       s_query = (ctsvc_query_s*)query;
+       RETVM_IF(!ctsvc_have_permission(ctsvc_required_read_permission(s_query->view_uri)),
+                               CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied : read(%s)", s_query->view_uri);
+
+       if (( plugin_info = ctsvc_db_get_plugin_info(ctsvc_view_get_record_type(s_query->view_uri)))){
+               if( plugin_info->get_records_with_query ) {
+                       ret = plugin_info->get_records_with_query( query, offset, limit, out_list );
+                       return ret;
+               }
+       }
+
+       return __ctsvc_db_get_records_with_query_exec(s_query, offset, limit, out_list);
+}
+
+static int __ctsvc_db_get_contact_changes(const char* view_uri, int addressbook_id,
+               int version, contacts_list_h* out_list, int* out_current_version)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_list_h list;
+       cts_stmt stmt;
+
+       if (0 <= addressbook_id) {
+               snprintf(query, sizeof(query),
+                       "SELECT %d, contact_id, changed_ver, created_ver, addressbook_id, image_changed_ver "
+                                       "FROM "CTS_TABLE_CONTACTS" "
+                                       "WHERE changed_ver > %d AND addressbook_id = %d AND deleted = 0 "
+                       "UNION "
+                       "SELECT %d, contact_id, deleted_ver, -1, addressbook_id, 0 "
+                                       "FROM "CTS_TABLE_DELETEDS" "
+                                       "WHERE deleted_ver > %d AND created_ver <= %d AND addressbook_id = %d "
+                       "UNION "
+                       "SELECT %d, contact_id, changed_ver, -1, addressbook_id, 0 "
+                                       "FROM "CTS_TABLE_CONTACTS" "
+                                       "WHERE changed_ver > %d AND created_ver <= %d AND addressbook_id = %d AND deleted = 1 "
+                                               "AND addressbook_id = (SELECT addressbook_id FROM "CTS_TABLE_ADDRESSBOOKS" WHERE addressbook_id = %d)",
+                       CONTACTS_CHANGE_UPDATED, version, addressbook_id,
+                       CONTACTS_CHANGE_DELETED, version, version, addressbook_id,
+                       CONTACTS_CHANGE_DELETED, version, version, addressbook_id, addressbook_id);
+       }
+       else {
+               snprintf(query, sizeof(query),
+                       "SELECT %d, contact_id, changed_ver, created_ver, addressbook_id, image_changed_ver "
+                                       "FROM "CTS_TABLE_CONTACTS" "
+                                       "WHERE changed_ver > %d AND deleted = 0 "
+                       "UNION "
+                       "SELECT %d, contact_id, deleted_ver, -1, addressbook_id, 0 "
+                                       "FROM "CTS_TABLE_DELETEDS" "
+                                       "WHERE deleted_ver > %d AND created_ver <= %d "
+                       "UNION "
+                       "SELECT %d, contact_id, changed_ver, -1, "CTS_TABLE_CONTACTS".addressbook_id, 0 "
+                                       "FROM "CTS_TABLE_CONTACTS",  "CTS_TABLE_ADDRESSBOOKS" "
+                                       "WHERE changed_ver > %d AND created_ver <= %d AND deleted = 1 "
+                                               "AND "CTS_TABLE_CONTACTS".addressbook_id = "CTS_TABLE_ADDRESSBOOKS".addressbook_id",
+                       CONTACTS_CHANGE_UPDATED, version,
+                       CONTACTS_CHANGE_DELETED, version, version,
+                       CONTACTS_CHANGE_DELETED, version ,version);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               ctsvc_updated_info_s *update_info;
+
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               ret = contacts_record_create(_contacts_contact_updated_info._uri, &record);
+               update_info = (ctsvc_updated_info_s *)record;
+               update_info->changed_type = ctsvc_stmt_get_int(stmt, 0);
+               update_info->id = ctsvc_stmt_get_int(stmt, 1);
+               update_info->changed_ver = ctsvc_stmt_get_int(stmt, 2);
+
+               if (ctsvc_stmt_get_int(stmt, 3) == update_info->changed_ver || version < ctsvc_stmt_get_int(stmt, 3))
+                       update_info->changed_type = CONTACTS_CHANGE_INSERTED;
+
+               update_info->addressbook_id = ctsvc_stmt_get_int(stmt, 4);
+
+               if (version < ctsvc_stmt_get_int(stmt, 5))
+                       update_info->image_changed = true;
+
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       snprintf(query, sizeof(query), "SELECT ver FROM "CTS_TABLE_VERSION);
+       ret = ctsvc_query_get_first_int_result(query, out_current_version);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret , "DB error : ctsvc_query_get_first_int_result() Failed(%d)", ret);
+       *out_list = list;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_get_group_changes(const char* view_uri, int addressbook_id,
+               int version, contacts_list_h* out_list, int* out_current_version)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_list_h list;
+       cts_stmt stmt;
+
+       if (0 <= addressbook_id) {
+               snprintf(query, sizeof(query),
+                       "SELECT %d, group_id, changed_ver, created_ver, addressbook_id FROM %s "
+                       "WHERE changed_ver > %d AND addressbook_id = %d "
+                       "UNION "
+                       "SELECT %d, group_id, deleted_ver, -1, addressbook_id FROM %s "
+                       "WHERE deleted_ver > %d AND created_ver <= %d AND addressbook_id = %d",
+                       CONTACTS_CHANGE_UPDATED, CTS_TABLE_GROUPS, version, addressbook_id,
+                       CONTACTS_CHANGE_DELETED, CTS_TABLE_GROUP_DELETEDS, version, version, addressbook_id);
+       }
+       else {
+               snprintf(query, sizeof(query),
+                       "SELECT %d, group_id, changed_ver, created_ver, addressbook_id FROM %s "
+                       "WHERE changed_ver > %d "
+                       "UNION "
+                       "SELECT %d, group_id, deleted_ver, -1, addressbook_id FROM %s "
+                       "WHERE deleted_ver > %d AND created_ver <= %d",
+                       CONTACTS_CHANGE_UPDATED, CTS_TABLE_GROUPS, version,
+                       CONTACTS_CHANGE_DELETED, CTS_TABLE_GROUP_DELETEDS, version, version);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               ctsvc_updated_info_s *update_info;
+
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               ret = contacts_record_create(_contacts_group_updated_info._uri, &record);
+               update_info = (ctsvc_updated_info_s *)record;
+               update_info->changed_type = ctsvc_stmt_get_int(stmt, 0);
+               update_info->id = ctsvc_stmt_get_int(stmt, 1);
+               update_info->changed_ver = ctsvc_stmt_get_int(stmt, 2);
+
+               if (ctsvc_stmt_get_int(stmt, 3) == update_info->changed_ver || version < ctsvc_stmt_get_int(stmt, 3))
+                       update_info->changed_type = CONTACTS_CHANGE_INSERTED;
+
+               update_info->addressbook_id = ctsvc_stmt_get_int(stmt, 4);
+
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       snprintf(query, sizeof(query), "SELECT ver FROM "CTS_TABLE_VERSION);
+       ret = ctsvc_query_get_first_int_result(query, out_current_version);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret , "DB error : ctsvc_query_get_first_int_result() Failed(%d)", ret);
+       *out_list = list;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_get_group_relations_changes(const char* view_uri, int addressbook_id,
+               int version, contacts_list_h* out_list, int* out_current_version)
+{
+       int len;
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       char temp_query[CTS_SQL_MAX_LEN] = {0};
+       contacts_list_h list;
+       cts_stmt stmt;
+
+       len = snprintf(temp_query, sizeof(temp_query),
+                       "SELECT %d, group_id, contact_id, addressbook_id, ver "
+                               "FROM "CTS_TABLE_GROUP_RELATIONS", "CTS_TABLE_GROUPS" USING (group_id) "
+                               "WHERE ver > %d AND deleted = 0 "
+                       "UNION SELECT %d, group_id, contact_id, addressbook_id, ver "
+                               "FROM "CTS_TABLE_GROUP_RELATIONS", "CTS_TABLE_GROUPS" USING (group_id) "
+                               "WHERE ver > %d AND deleted = 1 ",
+                               CONTACTS_CHANGE_INSERTED, version,
+                               CONTACTS_CHANGE_DELETED, version);
+
+       if (0 <= addressbook_id) {
+               len += snprintf(query, sizeof(query),
+                                       "SELECT * FROM (%s) WHERE addressbook_id = %d ", temp_query, addressbook_id);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               ret = contacts_record_create(view_uri, &record);
+               ctsvc_record_set_int(record, _contacts_grouprel_updated_info.type, ctsvc_stmt_get_int(stmt, 0));
+               ctsvc_record_set_int(record, _contacts_grouprel_updated_info.group_id, ctsvc_stmt_get_int(stmt, 1));
+               ctsvc_record_set_int(record, _contacts_grouprel_updated_info.contact_id, ctsvc_stmt_get_int(stmt, 2));
+               ctsvc_record_set_int(record, _contacts_grouprel_updated_info.address_book_id, ctsvc_stmt_get_int(stmt, 3));
+               ctsvc_record_set_int(record, _contacts_grouprel_updated_info.version, ctsvc_stmt_get_int(stmt, 4));
+
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       snprintf(query, sizeof(query), "SELECT ver FROM "CTS_TABLE_VERSION);
+       ret = ctsvc_query_get_first_int_result(query, out_current_version);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret , "DB error : ctsvc_query_get_first_int_result() Failed(%d)", ret);
+       *out_list = list;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_get_group_member_changes(const char* view_uri, int addressbook_id,
+               int version, contacts_list_h* out_list, int* out_current_version)
+{
+       int len;
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_list_h list;
+       cts_stmt stmt;
+
+       len = snprintf(query, sizeof(query),
+                       "SELECT group_id, member_changed_ver, addressbook_id "
+                               "FROM "CTS_TABLE_GROUPS" WHERE member_changed_ver > %d", version);
+
+       if (0 <= addressbook_id)
+               len += snprintf(query+len, sizeof(query)-len, " AND addressbook_id = %d ", addressbook_id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               ret = contacts_record_create(view_uri, &record);
+               ctsvc_record_set_int(record, _contacts_group_member_updated_info.group_id, ctsvc_stmt_get_int(stmt, 0));
+               ctsvc_record_set_int(record, _contacts_group_member_updated_info.version, ctsvc_stmt_get_int(stmt, 1));
+               ctsvc_record_set_int(record, _contacts_group_member_updated_info.address_book_id, ctsvc_stmt_get_int(stmt, 2));
+
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       snprintf(query, sizeof(query), "SELECT ver FROM "CTS_TABLE_VERSION);
+       ret = ctsvc_query_get_first_int_result(query, out_current_version);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret , "DB error : ctsvc_query_get_first_int_result() Failed(%d)", ret);
+       *out_list = list;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_db_get_my_profile_changes(const char* view_uri, int addressbook_id,
+               int version, contacts_list_h* out_list, int* out_current_version)
+{
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       contacts_list_h list;
+       cts_stmt stmt;
+
+       if (0 <= addressbook_id) {
+               snprintf(query, sizeof(query),
+                       "SELECT changed_ver, addressbook_id, %d FROM %s "
+                       "WHERE changed_ver > %d AND changed_ver == created_ver AND deleted = 0 AND addressbook_id = %d "
+                       "UNION "
+                       "SELECT changed_ver, addressbook_id, %d FROM %s "
+                       "WHERE changed_ver > %d AND changed_ver != created_ver AND deleted = 0 AND addressbook_id = %d "
+                       "UNION "
+                       "SELECT changed_ver, addressbook_id, %d FROM %s "
+                       "WHERE changed_ver > %d AND deleted = 1 AND addressbook_id = %d",
+                       CONTACTS_CHANGE_INSERTED, CTS_TABLE_MY_PROFILES, version, addressbook_id,
+                       CONTACTS_CHANGE_UPDATED, CTS_TABLE_MY_PROFILES, version, addressbook_id,
+                       CONTACTS_CHANGE_DELETED, CTS_TABLE_MY_PROFILES, version, addressbook_id);
+       }
+       else {
+               snprintf(query, sizeof(query),
+                       "SELECT changed_ver, addressbook_id, %d FROM %s "
+                       "WHERE changed_ver > %d AND changed_ver == created_ver AND deleted = 0 "
+                       "UNION "
+                       "SELECT changed_ver, addressbook_id, %d FROM %s "
+                       "WHERE changed_ver > %d AND changed_ver != created_ver AND deleted = 0 "
+                       "UNION "
+                       "SELECT changed_ver, addressbook_id, %d FROM %s "
+                       "WHERE changed_ver > %d AND deleted = 1",
+                       CONTACTS_CHANGE_INSERTED, CTS_TABLE_MY_PROFILES, version,
+                       CONTACTS_CHANGE_UPDATED, CTS_TABLE_MY_PROFILES, version,
+                       CONTACTS_CHANGE_DELETED, CTS_TABLE_MY_PROFILES, version);
+       }
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       contacts_list_create(&list);
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               contacts_record_h record;
+               if (1 != ret) {
+                       CTS_ERR("DB error : ctsvc_stmt_step() Failed(%d)", ret);
+                       ctsvc_stmt_finalize(stmt);
+                       contacts_list_destroy(list, true);
+                       return ret;
+               }
+
+               ret = contacts_record_create(view_uri, &record);
+               ctsvc_record_set_int(record, _contacts_my_profile_updated_info.version, ctsvc_stmt_get_int(stmt, 0));
+               ctsvc_record_set_int(record, _contacts_my_profile_updated_info.address_book_id, ctsvc_stmt_get_int(stmt, 1));
+               ctsvc_record_set_int(record, _contacts_my_profile_updated_info.last_changed_type, ctsvc_stmt_get_int(stmt, 2));
+               ctsvc_list_prepend(list, record);
+       }
+       ctsvc_stmt_finalize(stmt);
+       ctsvc_list_reverse(list);
+
+       snprintf(query, sizeof(query), "SELECT ver FROM "CTS_TABLE_VERSION);
+       ret = ctsvc_query_get_first_int_result(query, out_current_version);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret , "DB error : ctsvc_query_get_first_int_result() Failed(%d)", ret);
+       *out_list = list;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_db_get_changes_by_version( const char* view_uri, int addressbook_id,
+               int version, contacts_list_h* out_list, int* out_current_version )
+{
+       int ret;
+       RETV_IF(version < 0, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == out_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_list = NULL;
+       RETV_IF(NULL == out_current_version, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_current_version = 0;
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_READ),
+                               CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied : read (%s)", view_uri);
+
+       if (0 == strcmp(view_uri, _contacts_contact_updated_info._uri)) {
+               ret = __ctsvc_db_get_contact_changes(view_uri, addressbook_id,
+                                       version, out_list, out_current_version);
+               return ret;
+       }
+       else if (0 == strcmp(view_uri, _contacts_group_updated_info._uri)) {
+               ret = __ctsvc_db_get_group_changes(view_uri, addressbook_id,
+                                       version, out_list, out_current_version);
+               return ret;
+       }
+       else if (0 == strcmp(view_uri, _contacts_group_member_updated_info._uri)) {
+               ret = __ctsvc_db_get_group_member_changes(view_uri, addressbook_id,
+                                       version, out_list, out_current_version);
+               return ret;
+       }
+       else if (0 == strcmp(view_uri, _contacts_grouprel_updated_info._uri)) {
+               ret = __ctsvc_db_get_group_relations_changes(view_uri, addressbook_id,
+                                       version, out_list, out_current_version);
+               return ret;
+       }
+       else if (0 == strcmp(view_uri, _contacts_my_profile_updated_info._uri)) {
+               ret = __ctsvc_db_get_my_profile_changes(view_uri, addressbook_id,
+                                       version, out_list, out_current_version);
+               return ret;
+       }
+
+       CTS_ERR("Invalid parameter : this API does not support uri(%s)", view_uri);
+       return CONTACTS_ERROR_INVALID_PARAMETER;
+}
+
+API int contacts_db_get_current_version( int* out_current_version )
+{
+       RETVM_IF(NULL == out_current_version, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_READ) && !ctsvc_have_permission(CTSVC_PERMISSION_PHONELOG_READ),
+                               CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied : read (contact)");
+
+       return ctsvc_get_current_version(out_current_version);
+}
+
+API int contacts_db_search_records(const char* view_uri, const char *keyword,
+               int offset, int limit, contacts_list_h* out_list)
+{
+       RETV_IF(NULL == out_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_list = NULL;
+       RETVM_IF(NULL == view_uri, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(!ctsvc_have_permission(ctsvc_required_read_permission(view_uri)),
+                               CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied : read(%s)", view_uri);
+
+       return __ctsvc_db_search_records(view_uri, keyword, offset, limit, out_list);
+}
+
+API int contacts_db_search_records_with_range(const char* view_uri, const char *keyword,
+               int offset, int limit, int range, contacts_list_h* out_list)
+{
+       RETV_IF(NULL == out_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_list = NULL;
+       RETVM_IF(range == 0, CONTACTS_ERROR_INVALID_PARAMETER, "range is 0");
+       RETVM_IF(NULL == view_uri, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(!ctsvc_have_permission(ctsvc_required_read_permission(view_uri)),
+                               CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied : read(%s)", view_uri);
+
+       return __ctsvc_db_search_records_with_range(view_uri, keyword, offset, limit, range, out_list);
+}
+
+API int contacts_db_search_records_with_query( contacts_query_h query, const char *keyword,
+               int offset, int limit, contacts_list_h* out_list)
+{
+       RETV_IF(NULL == out_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_list = NULL;
+       RETVM_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(!ctsvc_have_permission(ctsvc_required_read_permission(((ctsvc_query_s*)query)->view_uri)),
+                               CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied : read (%s)", ((ctsvc_query_s*)query)->view_uri);
+
+       return __ctsvc_db_search_records_with_query(query, keyword, offset, limit, out_list);
+}
+
+API int contacts_db_get_count( const char* view_uri, int *out_count)
+{
+       int ret;
+       ctsvc_db_plugin_info_s* plugin_info = NULL;
+
+       RETV_IF(NULL == out_count, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_count = 0;
+       RETVM_IF(NULL == view_uri, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(!ctsvc_have_permission(ctsvc_required_read_permission(view_uri)),
+                               CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied : read (%s)", view_uri);
+
+       if (( plugin_info = ctsvc_db_get_plugin_info(ctsvc_view_get_record_type(view_uri)))){
+               if( plugin_info->get_count ) {
+                       ret = plugin_info->get_count(out_count);
+                       return ret;
+               }
+       }
+
+       return __ctsvc_db_get_count( view_uri, out_count );
+}
+
+API int contacts_db_get_count_with_query( contacts_query_h query, int *out_count)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       ctsvc_record_type_e type = CTSVC_RECORD_INVALID;
+       ctsvc_db_plugin_info_s* plugin_info = NULL;
+       ctsvc_query_s *s_query;
+
+       RETV_IF(NULL == out_count, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_count = 0;
+
+       RETVM_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       s_query = (ctsvc_query_s*)query;
+       RETVM_IF(!ctsvc_have_permission(ctsvc_required_read_permission(s_query->view_uri)),
+                               CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied : read (%s)", s_query->view_uri);
+
+       type = ctsvc_view_get_record_type(s_query->view_uri);
+       plugin_info = ctsvc_db_get_plugin_info(type);
+
+       if (plugin_info){
+               if(plugin_info->get_count_with_query ) {
+                       ret = plugin_info->get_count_with_query( query, out_count );
+                       return ret;
+               }
+       }
+
+       return __ctsvc_db_get_count_with_query( query, out_count );
+}
+
+API int contacts_db_insert_record(contacts_record_h record, int *id )
+{
+       ctsvc_db_plugin_info_s* plugin_info = NULL;
+
+       if (id)
+               *id = 0;
+
+       RETVM_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       plugin_info = ctsvc_db_get_plugin_info(((ctsvc_record_s*)record)->r_type);
+       RETVM_IF(NULL == plugin_info, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(NULL == plugin_info->insert_record, CONTACTS_ERROR_INVALID_PARAMETER, "Not permitted");
+       RETVM_IF(!ctsvc_have_permission(ctsvc_required_write_permission(((ctsvc_record_s*)record)->view_uri)),
+                               CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied : write (%s)", ((ctsvc_record_s*)record)->view_uri);
+
+       return plugin_info->insert_record(record, id);
+}
+
+API int contacts_db_update_record(contacts_record_h record)
+{
+       ctsvc_db_plugin_info_s* plugin_info = NULL;
+
+       RETVM_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       plugin_info = ctsvc_db_get_plugin_info(((ctsvc_record_s*)record)->r_type);
+       RETVM_IF(NULL == plugin_info, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(NULL == plugin_info->update_record, CONTACTS_ERROR_INVALID_PARAMETER, "Not permitted");
+       RETVM_IF(!ctsvc_have_permission(ctsvc_required_write_permission(((ctsvc_record_s*)record)->view_uri)),
+                               CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied : write (%s)", ((ctsvc_record_s*)record)->view_uri);
+
+       return plugin_info->update_record(record);
+}
+
+API int contacts_db_delete_record(const char* view_uri, int id)
+{
+       ctsvc_record_type_e type = CTSVC_RECORD_INVALID;
+       ctsvc_db_plugin_info_s* plugin_info = NULL;
+
+       RETVM_IF(NULL == view_uri, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       type = ctsvc_view_get_record_type(view_uri);
+       plugin_info = ctsvc_db_get_plugin_info(type);
+       RETVM_IF(NULL == plugin_info, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(NULL == plugin_info->delete_record, CONTACTS_ERROR_INVALID_PARAMETER, "Not permitted");
+       RETVM_IF(!ctsvc_have_permission(ctsvc_required_write_permission(view_uri)),
+                               CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied : write (%s)", view_uri);
+
+       return plugin_info->delete_record(id);
+}
+
+API int contacts_db_get_record(const char* view_uri, int id, contacts_record_h* out_record )
+{
+       ctsvc_record_type_e type = CTSVC_RECORD_INVALID;
+       ctsvc_db_plugin_info_s* plugin_info = NULL;
+
+       RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_record = NULL;
+       RETVM_IF(NULL == view_uri, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       type = ctsvc_view_get_record_type(view_uri);
+       plugin_info = ctsvc_db_get_plugin_info(type);
+
+       RETVM_IF(NULL == plugin_info, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(NULL == plugin_info->get_record, CONTACTS_ERROR_INVALID_PARAMETER, "Not permitted");
+       RETVM_IF(!ctsvc_have_permission(ctsvc_required_read_permission(view_uri)),
+                               CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied : read (%s)", view_uri);
+
+       return plugin_info->get_record(id, out_record);
+}
+
+API int contacts_db_replace_record( contacts_record_h record, int id )
+{
+       ctsvc_db_plugin_info_s* plugin_info = NULL;
+
+       RETVM_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : record is NULL");
+
+       plugin_info = ctsvc_db_get_plugin_info(((ctsvc_record_s*)record)->r_type);
+       RETVM_IF(NULL == plugin_info, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(NULL == plugin_info->replace_record, CONTACTS_ERROR_INVALID_PARAMETER, "Not permitted");
+       RETVM_IF(!ctsvc_have_permission(ctsvc_required_write_permission(((ctsvc_record_s*)record)->view_uri)),
+                               CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied : write (%s)", ((ctsvc_record_s*)record)->view_uri);
+
+       return plugin_info->replace_record(record, id);
+}
+
+API int contacts_db_get_all_records(const char* view_uri, int offset, int limit, contacts_list_h* out_list )
+{
+       int ret = CONTACTS_ERROR_NONE;
+       ctsvc_record_type_e type = CTSVC_RECORD_INVALID;
+       ctsvc_db_plugin_info_s* plugin_info = NULL;
+
+       RETV_IF(NULL == out_list, CONTACTS_ERROR_INVALID_PARAMETER);
+       *out_list = NULL;
+       RETVM_IF(NULL == view_uri, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(!ctsvc_have_permission(ctsvc_required_read_permission(view_uri)),
+                               CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied : read (%s)", view_uri);
+
+       type = ctsvc_view_get_record_type(view_uri);
+       plugin_info = ctsvc_db_get_plugin_info(type);
+
+       if (plugin_info){
+               if( plugin_info->get_all_records ) {
+                       ret = plugin_info->get_all_records(offset, limit, out_list);
+                       return ret;
+               }
+       }
+
+       return __ctsvc_db_get_all_records( view_uri, offset, limit, out_list );
+}
+
+int ctsvc_db_insert_records(contacts_list_h list, int **ids, int *count)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       ctsvc_db_plugin_info_s* plugin_info = NULL;
+
+       RETVM_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       if (count)
+               contacts_list_get_count(list, count);
+       if (( plugin_info = ctsvc_db_get_plugin_info(((ctsvc_list_s*)list)->l_type))) {
+               if( plugin_info->insert_records ) {
+                       ret = plugin_info->insert_records( list, ids );
+                       return ret;
+               }
+       }
+
+       return __ctsvc_db_insert_records(list, ids);
+}
+
+API int contacts_db_insert_records_async( contacts_list_h list,
+               contacts_db_insert_result_cb callback, void *user_data)
+{
+       RETVM_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+#ifdef _CONTACTS_NATIVE
+       if (callback) {
+               ctsvc_bulk_info_s *info;
+               info = (ctsvc_bulk_info_s *)calloc(1, sizeof(ctsvc_bulk_info_s));
+               ctsvc_list_clone(list, &info->list);
+               info->cb = callback;
+               info->user_data = user_data;
+               g_idle_add(__ctsvc_db_insert_idler, info);              // should be changed after ipc implementation
+               return CONTACTS_ERROR_NONE;
+       }
+#endif
+       return ctsvc_db_insert_records(list, NULL, NULL);
+}
+
+int ctsvc_db_update_records(contacts_list_h list)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       ctsvc_db_plugin_info_s* plugin_info = NULL;
+
+       RETVM_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       if (( plugin_info = ctsvc_db_get_plugin_info(((ctsvc_list_s*)list)->l_type))){
+               if( plugin_info->update_records ) {
+                       ret = plugin_info->update_records( list );
+                       return ret;
+               }
+       }
+
+       return __ctsvc_db_update_records(list);
+}
+
+API int contacts_db_update_records_async( contacts_list_h list,
+               contacts_db_result_cb callback, void *user_data)
+{
+       RETVM_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+#ifdef _CONTACTS_NATIVE
+       if (callback) {
+               ctsvc_bulk_info_s *info;
+               info = (ctsvc_bulk_info_s *)calloc(1, sizeof(ctsvc_bulk_info_s));
+               ctsvc_list_clone(list, &info->list);
+               info->cb = callback;
+               info->user_data = user_data;
+               g_idle_add(__ctsvc_db_update_idler, info);              // should be changed after ipc implementation
+               return CONTACTS_ERROR_NONE;
+       }
+#endif
+       return ctsvc_db_update_records(list);
+}
+
+int ctsvc_db_delete_records(const char* view_uri, int* ids, int count)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       ctsvc_db_plugin_info_s* plugin_info = NULL;
+
+       RETV_IF(NULL == ids, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       if (( plugin_info = ctsvc_db_get_plugin_info(ctsvc_view_get_record_type(view_uri)))){
+               if( plugin_info->delete_records ) {
+                       ret = plugin_info->delete_records( ids, count );
+                       return ret;
+               }
+       }
+
+       return __ctsvc_db_delete_records(view_uri, ids, count);
+}
+
+API int contacts_db_delete_records_async( const char* view_uri, int* ids, int count,
+               contacts_db_result_cb callback, void *user_data)
+{
+       RETVM_IF(NULL == view_uri, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(NULL == ids, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+#ifdef _CONTACTS_NATIVE
+       if (callback) {
+               ctsvc_bulk_info_s *info;
+               info = (ctsvc_bulk_info_s *)calloc(1, sizeof(ctsvc_bulk_info_s));
+               info->ids = calloc(count, sizeof(int));
+               memcpy(info->ids, ids, sizeof(int)*count);
+               info->view_uri = view_uri;
+               info->count = count;
+               info->cb = callback;
+               info->user_data = user_data;
+               g_idle_add(__ctsvc_db_delete_idler, info);              // should be changed after ipc implementation
+               return CONTACTS_ERROR_NONE;
+       }
+#endif
+       return ctsvc_db_delete_records(view_uri, ids, count);
+}
+
+static int __ctsvc_db_replace_records( contacts_list_h list, int ids[], int count)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int record_count;
+       contacts_record_h record;
+       int i;
+
+       ret = contacts_list_get_count(list, &record_count);
+       RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "contacts_list_get_count is falied(%d)", ret);
+       RETVM_IF(record_count <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : count is 0");
+       RETVM_IF(record_count != count, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter : list count and ids count are not matched");
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_begin_trans is failed(%d)", ret);
+
+       contacts_list_first(list);
+       i = 0;
+       do {
+               ret = contacts_list_get_current_record_p(list, &record);
+               if( CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("contacts_list_get_current_record_p is faild(%d)", ret);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+
+               ret = contacts_db_replace_record(record, ids[i++]);
+               if( ret != CONTACTS_ERROR_NONE ) {
+                       CTS_ERR("contacts_db_replace_record is faild(%d)", ret);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+       }while(CONTACTS_ERROR_NONE == contacts_list_next(list));
+
+       ret = ctsvc_end_trans(true);
+
+       return ret;
+}
+
+
+#ifdef _CONTACTS_NATIVE
+static gboolean __ctsvc_db_replace_idler(void *data)
+{
+       int ret;
+       ctsvc_bulk_info_s *info = data;
+       contacts_db_result_cb cb;
+
+       ret = __ctsvc_db_replace_records(info->list, info->ids, info->count);
+
+       if (info->cb) {
+               cb = info->cb;
+               cb(ret, info->user_data);
+       }
+       contacts_list_destroy(info->list, true);
+       free(info->ids);
+       free(info);
+       return false;
+}
+#endif
+
+int ctsvc_db_replace_records(contacts_list_h list, int ids[], unsigned int count)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       ctsvc_db_plugin_info_s* plugin_info = NULL;
+
+       RETVM_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(NULL == ids, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       if (( plugin_info = ctsvc_db_get_plugin_info(((ctsvc_list_s*)list)->l_type))){
+               if( plugin_info->replace_records ) {
+                       ret = plugin_info->replace_records( list, ids, count );
+                       return ret;
+               }
+       }
+
+       return __ctsvc_db_replace_records(list, ids, count);
+}
+
+API int contacts_db_replace_records_async( contacts_list_h list, int ids[], int count,
+               contacts_db_result_cb callback, void *user_data )
+{
+       RETVM_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(NULL == ids, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+#ifdef _CONTACTS_NATIVE
+       if (callback) {
+               ctsvc_bulk_info_s *info;
+               info = (ctsvc_bulk_info_s *)calloc(1, sizeof(ctsvc_bulk_info_s));
+               ctsvc_list_clone(list, &info->list);
+               info->ids = calloc(count, sizeof(int));
+               memcpy(info->ids, ids, sizeof(int)*count);
+               info->count = count;
+               info->cb = callback;
+               info->user_data = user_data;
+               g_idle_add(__ctsvc_db_replace_idler, info);             // should be changed after ipc implementation
+               return CONTACTS_ERROR_NONE;
+       }
+#endif
+       return ctsvc_db_replace_records(list, ids, count);
+}
+
+API int contacts_db_insert_records( contacts_list_h record_list, int **ids, int *count)
+{
+       return ctsvc_db_insert_records(record_list, ids, count);
+}
+
+API int contacts_db_update_records( contacts_list_h record_list)
+{
+       return ctsvc_db_update_records(record_list);
+}
+
+API int contacts_db_delete_records(const char* view_uri, int record_id_array[], int count)
+{
+       return ctsvc_db_delete_records(view_uri, record_id_array, count);
+}
+
+API int contacts_db_replace_records( contacts_list_h list, int record_id_array[], int count )
+{
+       return ctsvc_db_replace_records(list, record_id_array, count);
+}
+
+API int contacts_db_get_last_change_version(int* last_version)
+{
+       int ret = CONTACTS_ERROR_NONE;
+
+       RETVM_IF(NULL == last_version, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_READ) && !ctsvc_have_permission(CTSVC_PERMISSION_PHONELOG_READ),
+                               CONTACTS_ERROR_PERMISSION_DENIED, "Permission denied : read (contact)");
+       *last_version = ctsvc_get_transaction_ver();
+       return ret;
+}
+
+API int contacts_db_get_status(contacts_db_status_e *status)
+{
+       *status = __db_status;
+       return CONTACTS_ERROR_NONE;
+}
+
+void ctsvc_db_set_status(contacts_db_status_e status)
+{
+       __db_status = status;
+
+#ifdef _CONTACTS_IPC_SERVER
+       ctsvc_change_subject_publish_status(status);
+#endif
+       return;
+}
+
diff --git a/native/ctsvc_db_query.h b/native/ctsvc_db_query.h
new file mode 100644 (file)
index 0000000..797174d
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 __TIZEN_SOCIAL_CTSVC_DB_QUERY_H__
+#define __TIZEN_SOCIAL_CTSVC_DB_QUERY_H__
+
+#include "contacts.h"
+#include "contacts_db_status.h"
+#include "ctsvc_struct.h"
+#include "ctsvc_sqlite.h"
+
+int ctsvc_db_insert_records(contacts_list_h list, int **ids, unsigned int *count);
+int ctsvc_db_update_records(contacts_list_h list);
+int ctsvc_db_delete_records(const char* view_uri, int *ids, int count);
+int ctsvc_db_replace_records(contacts_list_h list, int ids[], unsigned int count);
+
+int ctsvc_db_make_get_records_query_stmt(ctsvc_query_s *s_query, int offset, int limit, cts_stmt *stmt);
+int ctsvc_db_create_set_query(contacts_record_h record, char **set, GSList **bind_text);
+int ctsvc_db_update_record_with_set_query(const char *set, GSList *bind_text, const char *table, int id);
+
+void ctsvc_db_set_status(contacts_db_status_e status);
+
+#endif /*  __TIZEN_SOCIAL_CTSVC_DB_QUERY_H__ */
+
diff --git a/native/ctsvc_group.c b/native/ctsvc_group.c
new file mode 100644 (file)
index 0000000..360a227
--- /dev/null
@@ -0,0 +1,362 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_group.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_access_control.h"
+
+int ctsvc_group_add_contact_in_transaction(int group_id, int contact_id)
+{
+       int ret;
+       int version;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+       int rel_changed = 0;
+       int grp_acc = -1;
+       int contact_acc = -1;
+       int exist = 0;
+
+       snprintf(query, sizeof(query),
+                       "SELECT COUNT(*) FROM %s WHERE group_id = %d AND contact_id=%d AND deleted = 0",
+                       CTS_TABLE_GROUP_RELATIONS, group_id, contact_id);
+
+       ret = ctsvc_query_get_first_int_result(query, &exist);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_DBG("ctsvc_query_get_first_int_result fail(%d)");
+               return ret;
+       }
+       if (1 == exist) {
+               CTS_DBG("group relation already exist (group_id:%d, contac_id:%d)", group_id, contact_id);
+               return CONTACTS_ERROR_NONE;
+       }
+
+       version = ctsvc_get_next_ver();
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM %s WHERE group_id = %d",
+                       CTS_TABLE_GROUPS, group_id);
+       ret = ctsvc_query_get_first_int_result(query, &grp_acc);
+       RETVM_IF(CONTACTS_ERROR_NO_DATA == ret, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid Parameter: group_id(%d) is Invalid", group_id);
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id FROM %s WHERE contact_id = %d AND deleted = 0",
+                       CTS_TABLE_CONTACTS, contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &contact_acc);
+       RETVM_IF(CONTACTS_ERROR_NO_DATA == ret, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid Parameter: contact_id(%d) is Invalid", contact_id);
+       RETVM_IF( contact_acc != grp_acc, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "Invalid Parameter: group_acc(%d) is differ from contact_acc(%d) Invalid", grp_acc, contact_acc);
+
+       snprintf(query, sizeof(query), "INSERT OR REPLACE INTO %s VALUES(%d, %d, %d, 0)",
+                       CTS_TABLE_GROUP_RELATIONS, group_id, contact_id, version);
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_stmt_step() Failed(%d)", ret);
+
+       rel_changed = ctsvc_db_change();
+       ctsvc_stmt_finalize(stmt);
+
+       if (0 < rel_changed) {
+               snprintf(query, sizeof(query),
+                               "UPDATE "CTS_TABLE_GROUPS" SET member_changed_ver=%d WHERE group_id=%d",
+                               version, group_id);
+               ret = ctsvc_query_exec(query);
+               RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_set_group_rel_noti();
+               return rel_changed;
+       }
+
+       return ret;
+}
+
+API int contacts_group_add_contact(int group_id, int contact_id)
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_WRITE), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact write (group)");
+       RETVM_IF( group_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid Parameter: group_id should be greater than 0");
+       RETVM_IF( contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid Parameter: contact_id should be greater than 0");
+
+       /* BEGIN_TRANSACTION */
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id from "CTSVC_DB_VIEW_CONTACT"  WHERE contact_id = %d", contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : contact_id (%d) is not exist", contact_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to get this group record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       /* DOING JOB */
+       do {
+               int changed = ctsvc_group_add_contact_in_transaction(group_id, contact_id);
+               if (changed < CONTACTS_ERROR_NONE) {
+                       CTS_ERR("DB error : ctsvc_group_add_contact_in_transaction() Failed(%d)", changed);
+                       ret = changed;
+                       break;
+               }
+
+               ret = ctsvc_db_contact_update_changed_time(contact_id);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+                       ret = CONTACTS_ERROR_DB;
+                       break;
+               }
+               ctsvc_set_person_noti();
+
+               ret = ctsvc_end_trans(true);
+               if(ret < CONTACTS_ERROR_NONE )
+               {
+                       CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+                       return ret;
+               }
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       /* ROLLBACK TRANSACTION */
+       ctsvc_end_trans(false);
+
+       return ret;
+}
+
+int ctsvc_group_remove_contact_in_transaction(int group_id, int contact_id)
+{
+       int ret;
+       int version;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       version = ctsvc_get_next_ver();
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET deleted=1, ver = %d WHERE group_id = %d AND contact_id = %d",
+                       CTS_TABLE_GROUP_RELATIONS, version, group_id, contact_id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "DB Error: ctsvc_stmt_step() Failed(%d)", ret);
+
+       int rel_changed = ctsvc_db_change();
+       ctsvc_stmt_finalize(stmt);
+
+       if (0 <= rel_changed) {
+               snprintf(query, sizeof(query),
+                               "UPDATE "CTS_TABLE_GROUPS" SET member_changed_ver=%d WHERE group_id=%d",
+                               version, group_id);
+               ret = ctsvc_query_exec(query);
+               RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_set_group_rel_noti();
+               return rel_changed;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_group_remove_contact(int group_id, int contact_id)
+{
+       int ret;
+       int addressbook_id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_WRITE), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact write (group)");
+       RETVM_IF( group_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid Parameter: group_id should be greater than 0");
+       RETVM_IF( contact_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid Parameter: contact_id should be greater than 0");
+
+       /* BEGIN_TRANSACTION */
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id from "CTSVC_DB_VIEW_CONTACT"  WHERE contact_id = %d", contact_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : contact_id (%d) is not exist", contact_id);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to get this group record : addresbook_id(%d)", addressbook_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       /* DOING JOB */
+       do {
+               int changed = ctsvc_group_remove_contact_in_transaction(group_id, contact_id);
+               if (changed < CONTACTS_ERROR_NONE) {
+                       CTS_ERR("DB error : ctsvc_group_remove_contact_in_transaction() Failed(%d)", changed);
+                       ret = changed;
+                       break;
+               }
+
+               ret = ctsvc_db_contact_update_changed_time(contact_id);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : ctsvc_db_contact_update_changed_time() Failed(%d)", ret);
+                       ret = CONTACTS_ERROR_DB;
+                       break;
+               }
+               ctsvc_set_person_noti();
+
+               ret = ctsvc_end_trans(true);
+               if(ret < CONTACTS_ERROR_NONE )
+               {
+                       CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+                       return ret;
+               }
+
+               return CONTACTS_ERROR_NONE;
+
+       } while(0);
+
+       /* ROLLBACK TRANSACTION */
+       ctsvc_end_trans(false);
+
+       return ret;
+}
+
+
+API int contacts_group_set_group_order(int group_id, int previous_group_id, int next_group_id)
+{
+       int ret;
+       double previous_prio = 0.0;
+       double next_prio = 0.0;
+       int previous_addressbook_id = -1, next_addressbook_id = -1, addressbook_id = -1;
+       double prio;
+       cts_stmt stmt;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_WRITE), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact write (group)");
+
+       snprintf(query, sizeof(query),
+                       "SELECT addressbook_id from "CTS_TABLE_GROUPS"  WHERE group_id = %d", group_id);
+       ret = ctsvc_query_get_first_int_result(query, &addressbook_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("No data : group_id (%d) is not exist", group_id);
+               return ret;
+       }
+
+       if (false == ctsvc_have_ab_write_permission(addressbook_id)) {
+               CTS_ERR("Does not have permission to get this group record : addresbook_id(%d)", addressbook_id);
+               return CONTACTS_ERROR_PERMISSION_DENIED;
+       }
+
+       snprintf(query, sizeof(query), "SELECT group_prio, addressbook_id FROM "CTS_TABLE_GROUPS" WHERE group_id = ?");
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ctsvc_stmt_bind_int(stmt, 1, previous_group_id);
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/  == ret) {
+               previous_prio = ctsvc_stmt_get_dbl(stmt, 0);
+               previous_addressbook_id = ctsvc_stmt_get_int(stmt, 1);
+       }
+       ctsvc_stmt_reset(stmt);
+       ctsvc_stmt_bind_int(stmt, 1, next_group_id);
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ == ret) {
+               next_prio = ctsvc_stmt_get_dbl(stmt, 0);
+               next_addressbook_id = ctsvc_stmt_get_int(stmt, 1);
+       }
+       ctsvc_stmt_reset(stmt);
+       ctsvc_stmt_bind_int(stmt, 1, group_id);
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ == ret) {
+               addressbook_id = ctsvc_stmt_get_int(stmt, 1);
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       RETVM_IF(0.0 == previous_prio && 0.0 == next_prio, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "The indexes for previous and next are invalid.");
+       RETVM_IF(previous_group_id && previous_addressbook_id != addressbook_id , CONTACTS_ERROR_INVALID_PARAMETER,
+                               "previous group(%d) and group(%d) are not the same addressbook(%d, %d) groups",
+                               previous_group_id, group_id, previous_addressbook_id, addressbook_id);
+       RETVM_IF(next_group_id && next_addressbook_id != addressbook_id , CONTACTS_ERROR_INVALID_PARAMETER,
+                               "next group(%d) and group(%d) are not the same addressbook(%d, %d) groups",
+                               next_group_id, group_id, next_addressbook_id, addressbook_id);
+
+       if (0.0 == next_prio)
+               prio = previous_prio + 1;
+       else
+               prio = (previous_prio + next_prio) / 2;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET group_prio = %f WHERE group_id = %d",
+                       CTS_TABLE_GROUPS, prio, group_id);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_set_group_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+/*
+API int contacts_group_add_person(int group_id, int person_id)
+{
+       return CONTACTS_ERROR_NONE;
+}
+API int contacts_group_remove_person(int group_id, int person_id)
+{
+       return CONTACTS_ERROR_NONE;
+}
+*/
+
diff --git a/native/ctsvc_group.h b/native/ctsvc_group.h
new file mode 100644 (file)
index 0000000..9b1bcf1
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_GROUP_H__
+#define __CTSVC_GROUP_H__
+
+int ctsvc_group_add_contact_in_transaction(int group_id, int contact_id);
+
+int ctsvc_group_remove_contact_in_transaction(int group_id, int contact_id);
+/*
+int ctsvc_group_add_contacts_in_person(int group_id, int person_id);
+int ctsvc_group_remove_contacts_in_person(int group_id, int person_id);
+*/
+
+#endif // __CTSVC_GROUP_H__
diff --git a/native/ctsvc_localize.c b/native/ctsvc_localize.c
new file mode 100755 (executable)
index 0000000..a58fe31
--- /dev/null
@@ -0,0 +1,501 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <unicode/ustring.h>
+#include <unicode/unorm.h>
+#include <unicode/ucol.h>
+#include <unicode/uset.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+
+#include "ctsvc_internal.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_localize.h"
+#include "ctsvc_localize_utils.h"
+
+#include "ctsvc_localize_kor.h"
+#include "ctsvc_localize_jp.h"
+
+int ctsvc_get_sort_type_from_language(int language)
+{
+       switch(language) {
+       case CTSVC_LANG_CHINESE:
+               return CTSVC_SORT_CJK;
+       case CTSVC_LANG_JAPANESE:
+               return CTSVC_SORT_JAPANESE;
+       case CTSVC_LANG_KOREAN:
+               return CTSVC_SORT_KOREAN;
+       case CTSVC_LANG_ENGLISH:
+               return CTSVC_SORT_WESTERN;
+       case CTSVC_LANG_NUMBER:
+               return CTSVC_SORT_NUMBER;
+       case CTSVC_LANG_RUSSIAN:
+       case CTSVC_LANG_BULGARIAN:
+       case CTSVC_LANG_MACEDONIA:
+       case CTSVC_LANG_KAZAKHSTAN:
+       case CTSVC_LANG_SERBIAN:
+       case CTSVC_LANG_UKRAINE:
+               return CTSVC_SORT_CYRILLIC;
+       case CTSVC_LANG_ARMENIAN:
+               return CTSVC_SORT_ARMENIAN;
+       case CTSVC_LANG_GREEK:
+               return CTSVC_SORT_GREEK;
+       case CTSVC_LANG_ARABIC:
+       case CTSVC_LANG_PERSIAN:
+       case CTSVC_LANG_URDU:
+               return CTSVC_SORT_ARABIC;
+       case CTSVC_LANG_HINDI:
+               return CTSVC_SORT_DEVANAGARI;
+       case CTSVC_LANG_GEORGIAN:
+               return CTSVC_SORT_GEORGIAN;
+       case CTSVC_LANG_TURKISH:
+               return CTSVC_SORT_TURKISH;
+       case CTSVC_LANG_THAI:
+               return CTSVC_SORT_THAI;
+       case CTSVC_LANG_BENGALI:
+               return CTSVC_SORT_BENGALI;
+       case CTSVC_LANG_PUNJABI:
+               return CTSVC_SORT_PUNJABI;
+       case CTSVC_LANG_MALAYALAM:
+               return CTSVC_SORT_MALAYALAM;
+       case CTSVC_LANG_TELUGU:
+               return CTSVC_SORT_TELUGU;
+       case CTSVC_LANG_TAMIL:
+               return CTSVC_SORT_TAMIL;
+       case CTSVC_LANG_ORIYA:
+               return CTSVC_SORT_ORIYA;
+       case CTSVC_LANG_SINHALA:
+               return CTSVC_SORT_SINHALA;
+       case CTSVC_LANG_GUJARATI:
+               return CTSVC_SORT_GUJARATI;
+       case CTSVC_LANG_KANNADA:
+               return CTSVC_SORT_KANNADA;
+       case CTSVC_LANG_LAO:
+               return CTSVC_SORT_LAO;
+       case CTSVC_LANG_HEBREW:
+               return CTSVC_SORT_HEBREW;
+       case CTSVC_LANG_BURMESE:
+               return CTSVC_SORT_BURMESE;
+       case CTSVC_LANG_KHMER:
+               return CTSVC_SORT_KHMER;
+       case CTSVC_LANG_OTHERS:
+               return CTSVC_SORT_OTHERS;
+       default:
+               return CTSVC_SORT_WESTERN;
+       }
+}
+
+int ctsvc_get_name_sort_type(const char *src)
+{
+       UErrorCode status = 0;
+       UChar tmp_result[10];
+       int ret = CTSVC_SORT_OTHERS;
+       int char_len = 0;
+       int language_type;
+       char char_src[10];
+
+       char_len = ctsvc_check_utf8(src[0]);
+       RETVM_IF(char_len <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "check_utf8 failed");
+
+       memcpy(char_src, &src[0], char_len);
+       char_src[char_len] = '\0';
+
+       u_strFromUTF8(tmp_result, array_sizeof(tmp_result), NULL, char_src, -1, &status);
+       RETVM_IF(U_FAILURE(status), CONTACTS_ERROR_SYSTEM,
+                       "u_strFromUTF8() Failed(%s)", u_errorName(status));
+
+       language_type = ctsvc_check_language(tmp_result);
+       ret = ctsvc_get_sort_type_from_language(language_type);
+
+       return ret;
+}
+
+void ctsvc_extra_normalize(UChar *word, int32_t word_size)
+{
+       int i;
+       for (i=0;i<word_size;i++) {
+               // FF00 ~ FF60, FFE0~FFE6 : fullwidth -> halfwidth
+               if (CTSVC_COMPARE_BETWEEN((UChar)0xFF00, word[i], (UChar)0xFF60)) {
+                       int unicode_value1 = 0;
+                       int unicode_value2 = 0;
+                       unicode_value1 = 0x0;
+                       unicode_value2 = (0xFF & word[i]) + 0x20;
+                       word[i] = unicode_value1 << 8 | unicode_value2;
+               }
+               else if (ctsvc_is_hangul(word[i])) {
+                       ctsvc_hangul_compatibility2jamo(&word[i]);
+               }
+       }
+}
+
+const char *ctsvc_get_language_locale(int lang)
+{
+       char *langset = ctsvc_get_langset();
+
+       switch(lang)
+       {
+       case CTSVC_LANG_AZERBAIJAN: // az, Azerbaijan
+               return "az";
+       case CTSVC_LANG_ARABIC: // ar, Bahrain - Arabic
+               return "ar";
+       case CTSVC_LANG_BULGARIAN: // bg, Bulgaria - Bulgarian
+               return "bg";
+       case CTSVC_LANG_CATALAN: // ca, Spain - Catalan
+               return "ca";
+       case CTSVC_LANG_CZECH: // cs, Czech Republic - Czech
+               return "cs";
+       case CTSVC_LANG_DANISH: // da, Denmark - Danish
+               return "da";
+       case CTSVC_LANG_GERMAN: // de, Germany - German
+               return "de";
+       case CTSVC_LANG_GREEK: // el, Greece - Greek
+               return "el";
+       case CTSVC_LANG_ENGLISH: // en, en_PH, en_US
+               return "en";
+       case CTSVC_LANG_SPANISH: // es_ES, es_US, El Salvador - Spanish
+               return "es";
+       case CTSVC_LANG_ESTONIAN: // et, Estonia - Estonian
+               return "et";
+       case CTSVC_LANG_BASQUE: // eu, Spain - Basque
+               return "eu";
+       case CTSVC_LANG_FINNISH: // fi, Finland - Finnish
+               return "fi";
+       case CTSVC_LANG_FRENCH: // fr_CA, fr_FR
+               return "fr";
+       case CTSVC_LANG_IRISH: // ga, Ireland - Irish
+               return "ga";
+       case CTSVC_LANG_GALICIAN: // gl, Spain - Galician
+               return "gl";
+       case CTSVC_LANG_HINDI: // hi, India - Hindi, Marathi, Nepali
+               if (!strncmp(langset, "hi", strlen("hi"))){
+                       return "hi";
+               }
+               else if (!strncmp(langset, "mr", strlen("mr"))) {
+                       return "mr";
+               }
+               else if (!strncmp(langset, "ne", strlen("ne"))) {
+                       return "ne";
+               }
+               return "hi";
+       case CTSVC_LANG_CROATIAN: // hr, Bosnia and Herzegovina - Croatian
+               return "hr";
+       case CTSVC_LANG_HUNGARIAN: // hu, Hungary - Hungarian
+               return "hu";
+       case CTSVC_LANG_ARMENIAN: // hy, Armenia - Armenian
+               return "hy";
+       case CTSVC_LANG_ICELANDIC: // is, Iceland - Icelandic
+               return "is";
+       case CTSVC_LANG_ITALIAN: // it_IT, Italy - Italian
+               return "it";
+       case CTSVC_LANG_JAPANESE: // ja_JP, japan
+               return "ja";
+       case CTSVC_LANG_GEORGIAN: // ka, Georgia - Georgian
+               return "ka";
+       case CTSVC_LANG_KAZAKHSTAN: // kk, Kazakhstan
+               return "kk";
+       case CTSVC_LANG_KOREAN: // ko, ko_KR
+               return "ko";
+       case CTSVC_LANG_LITHUANIAN: // lt, Lithuania - Lithuanian
+               return "lt";
+       case CTSVC_LANG_LATVIAN: // lv, Latvia - Latvian
+               return "lv";
+       case CTSVC_LANG_MACEDONIA: // mk, Macedonia
+               return "mk";
+       case CTSVC_LANG_NORWAY: // nb, Norway
+               return "nb";
+       case CTSVC_LANG_DUTCH: // nl_Nl, Netherlands Dutch
+               return "nl";
+       case CTSVC_LANG_POLISH: // pl, Polish
+               return "pl";
+       case CTSVC_LANG_PORTUGUESE: // pt_BR, pt_PT, Portugal
+               return "pt";
+       case CTSVC_LANG_ROMANIA: // ro, Romania
+               return "ro";
+       case CTSVC_LANG_RUSSIAN: // ru_RU, Russia
+               return "ru";
+       case CTSVC_LANG_SLOVAK: // sk, Slovakia - Slovak
+               return "sk";
+       case CTSVC_LANG_SLOVENIAN: // sl, Slovenia - Slovenian
+               return "sl";
+       case CTSVC_LANG_SERBIAN: // sr, Serbia - Serbian
+               return "sr";
+       case CTSVC_LANG_SWEDISH: // sv, Finland - Swedish
+               return "sv";
+       case CTSVC_LANG_TURKISH: // tr_TR, Turkey - Turkish
+               return "tr";
+       case CTSVC_LANG_UKRAINE: // uk, Ukraine
+               return "uk";
+       case CTSVC_LANG_CHINESE: // zh_CN, zh_HK, zh_SG, zh_TW
+               return "zh";
+       case CTSVC_LANG_THAI: // th_TH, Thai
+               return "th";
+       case CTSVC_LANG_BENGALI: // as, bn
+               if (!strncmp(langset, "as", strlen("as"))){
+                       return "as";
+               }
+               return "bn";
+       case CTSVC_LANG_PUNJABI: // pa
+                       return "pa";
+       case CTSVC_LANG_MALAYALAM:
+                       return "ml";
+       case CTSVC_LANG_TELUGU:
+                       return "te";
+       case CTSVC_LANG_TAMIL:
+                       return "ta";
+       case CTSVC_LANG_ORIYA:
+                       return "or";
+       case CTSVC_LANG_SINHALA:
+                       return "si";
+       case CTSVC_LANG_GUJARATI:
+                       return "gu";
+       case CTSVC_LANG_KANNADA:
+                       return "kn";
+       case CTSVC_LANG_LAO:
+                       return "lo";
+       case CTSVC_LANG_HEBREW:
+                       return "he";
+       case CTSVC_LANG_VIETNAMESE://latin
+                       return "vi";
+       case CTSVC_LANG_PERSIAN:
+                       return "fa";
+       case CTSVC_LANG_UZBEK:
+                       return "uz";
+       case CTSVC_LANG_URDU: //arabic
+                       return "ur";
+       case CTSVC_LANG_ALBANIAN:
+                       return "sq";
+       case CTSVC_LANG_BURMESE:
+                       return "my";
+       case CTSVC_LANG_MALAY:
+                       return "ms";
+       case CTSVC_LANG_KHMER:
+                       return "km";
+       case CTSVC_LANG_INDONESIAN:
+                       return "id";
+       case CTSVC_LANG_TAGALOG:
+                       return "tl";
+       }
+
+       return "";
+}
+
+int ctsvc_get_language_type(const char *system_lang)
+{
+       // refer to the VCONFKEY_LANGSET
+       int type;
+
+       RETV_IF(NULL == system_lang, CTSVC_LANG_OTHERS);
+
+       // az, Azerbaijan
+       if (!strncmp(system_lang, "az", strlen("az")))
+               type = CTSVC_LANG_AZERBAIJAN;
+       // ar, Bahrain - Arabic
+       else if (!strncmp(system_lang, "ar", strlen("ar")))
+               type = CTSVC_LANG_ARABIC;
+       // bg, Bulgaria - Bulgarian
+       else if (!strncmp(system_lang, "bg", strlen("bg")))
+               type = CTSVC_LANG_BULGARIAN;
+       // ca, Spain - Catalan
+       else if (!strncmp(system_lang, "ca", strlen("ca")))
+               type = CTSVC_LANG_CATALAN;
+       // cs, Czech Republic - Czech
+       else if (!strncmp(system_lang, "cs", strlen("cs")))
+               type = CTSVC_LANG_CZECH;
+       // da, Denmark - Danish
+       else if (!strncmp(system_lang, "da", strlen("da")))
+               type = CTSVC_LANG_DANISH;
+       // de, Germany - German
+       else if (!strncmp(system_lang, "de", strlen("de")))
+               type = CTSVC_LANG_GERMAN;
+       // el, Greece - Greek
+       else if (!strncmp(system_lang, "el", strlen("el")))
+               type = CTSVC_LANG_GREEK;
+       // en, en_PH, en_US
+       else if (!strncmp(system_lang, "en", strlen("en")))
+               type = CTSVC_LANG_ENGLISH;
+       // es_ES, es_US, El Salvador - Spanish
+       else if (!strncmp(system_lang, "es", strlen("es")))
+               type = CTSVC_LANG_SPANISH;
+       // et, Estonia - Estonian
+       else if (!strncmp(system_lang, "et", strlen("et")))
+               type = CTSVC_LANG_ESTONIAN;
+       // eu, Spain - Basque
+       else if (!strncmp(system_lang, "eu", strlen("eu")))
+               type = CTSVC_LANG_BASQUE;
+       // fi, Finland - Finnish
+       else if (!strncmp(system_lang, "fi", strlen("fi")))
+               type = CTSVC_LANG_FINNISH;
+       // fr_CA, fr_FR
+       else if (!strncmp(system_lang, "fr", strlen("fr")))
+               type = CTSVC_LANG_FRENCH;
+       // ga, Ireland - Irish
+       else if (!strncmp(system_lang, "ga", strlen("ga")))
+               type = CTSVC_LANG_IRISH;
+       // gl, Spain - Galician
+       else if (!strncmp(system_lang, "gl", strlen("gl")))
+               type = CTSVC_LANG_GALICIAN;
+       // hi, India - Hindi
+       else if (!strncmp(system_lang, "hi", strlen("hi")))
+               type = CTSVC_LANG_HINDI;
+       // mr, India - marathi
+       else if (!strncmp(system_lang, "mr", strlen("mr")))
+               type = CTSVC_LANG_HINDI;
+       // ne, India - nepal
+       else if (!strncmp(system_lang, "ne", strlen("ne")))
+               type = CTSVC_LANG_HINDI;
+       // hr, Bosnia and Herzegovina - Croatian
+       else if (!strncmp(system_lang, "hr", strlen("hr")))
+               type = CTSVC_LANG_CROATIAN;
+       // hu, Hungary - Hungarian
+       else if (!strncmp(system_lang, "hu", strlen("hu")))
+               type = CTSVC_LANG_HUNGARIAN;
+       // hy, Armenia - Armenian
+       else if (!strncmp(system_lang, "hy", strlen("hy")))
+               type = CTSVC_LANG_ARMENIAN;
+       // is, Iceland - Icelandic
+       else if (!strncmp(system_lang, "is", strlen("is")))
+               type = CTSVC_LANG_ICELANDIC;
+       // it_IT, Italy - Italian
+       else if (!strncmp(system_lang, "it", strlen("it")))
+               type = CTSVC_LANG_ITALIAN;
+       // ja_JP, japan
+       else if (!strncmp(system_lang, "ja", strlen("ja")))
+               type = CTSVC_LANG_JAPANESE;
+       // ka, Georgia - Georgian
+       else if (!strncmp(system_lang, "ka", strlen("ka")))
+               type = CTSVC_LANG_GEORGIAN;
+       // kk, Kazakhstan
+       else if (!strncmp(system_lang, "kk", strlen("kk")))
+               type = CTSVC_LANG_KAZAKHSTAN;
+       // ko, ko_KR
+       else if (!strncmp(system_lang, "ko", strlen("ko")))
+               type = CTSVC_LANG_KOREAN;
+       // lt, Lithuania - Lithuanian
+       else if (!strncmp(system_lang, "lt", strlen("lt")))
+               type = CTSVC_LANG_LITHUANIAN;
+       // lv, Latvia - Latvian
+       else if (!strncmp(system_lang, "lv", strlen("lv")))
+               type = CTSVC_LANG_LATVIAN;
+       // mk, Macedonia
+       else if (!strncmp(system_lang, "mk", strlen("mk")))
+               type = CTSVC_LANG_MACEDONIA;
+       // nb, Norway
+       else if (!strncmp(system_lang, "nb", strlen("nb")))
+               type = CTSVC_LANG_NORWAY;
+       // nl_Nl, Netherlands Dutch
+       else if (!strncmp(system_lang, "nl", strlen("nl")))
+               type = CTSVC_LANG_DUTCH;
+       // pl, Polish
+       else if (!strncmp(system_lang, "pl", strlen("pl")))
+               type = CTSVC_LANG_POLISH;
+       // pt_BR, pt_PT, Portugal
+       else if (!strncmp(system_lang, "pt", strlen("pt")))
+               type = CTSVC_LANG_PORTUGUESE;
+       // ro, Romania
+       else if (!strncmp(system_lang, "ro", strlen("ro")))
+               type = CTSVC_LANG_ROMANIA;
+       // ru_RU, Russia
+       else if (!strncmp(system_lang, "ru", strlen("ru")))
+               type = CTSVC_LANG_RUSSIAN;
+       // sk, Slovakia - Slovak
+       else if (!strncmp(system_lang, "sk", strlen("sk")))
+               type = CTSVC_LANG_SLOVAK;
+       // sl, Slovenia - Slovenian
+       else if (!strncmp(system_lang, "sl", strlen("sl")))
+               type = CTSVC_LANG_SLOVENIAN;
+       // sr, Serbia - Serbian
+       else if (!strncmp(system_lang, "sr", strlen("sr")))
+               type = CTSVC_LANG_SERBIAN;
+       // sv, Finland - Swedish
+       else if (!strncmp(system_lang, "sv", strlen("sv")))
+               type = CTSVC_LANG_SWEDISH;
+       // tr_TR, Turkey - Turkish
+       else if (!strncmp(system_lang, "tr", strlen("tr")))
+               type = CTSVC_LANG_TURKISH;
+       // uk, Ukraine
+       else if (!strncmp(system_lang, "uk", strlen("uk")))
+               type = CTSVC_LANG_UKRAINE;
+       // zh_CN, zh_HK, zh_SG, zh_TW
+       else if (!strncmp(system_lang, "zh", strlen("zh")))
+               type = CTSVC_LANG_CHINESE;
+       // th_TH
+       else if (!strncmp(system_lang, "th", strlen("th")))
+               type = CTSVC_LANG_THAI;
+       else if (!strncmp(system_lang, "as", strlen("as")))
+               type = CTSVC_LANG_BENGALI;
+       else if (!strncmp(system_lang, "bn", strlen("bn")))
+               type = CTSVC_LANG_BENGALI;
+       else if (!strncmp(system_lang, "pa", strlen("pa")))
+               type = CTSVC_LANG_PUNJABI;
+       else if (!strncmp(system_lang, "ml", strlen("ml")))
+               type = CTSVC_LANG_MALAYALAM;
+       else if (!strncmp(system_lang, "te", strlen("te")))
+               type = CTSVC_LANG_TELUGU;
+       else if (!strncmp(system_lang, "ta", strlen("ta")))
+               type = CTSVC_LANG_TAMIL;
+       else if (!strncmp(system_lang, "or", strlen("or")))
+               type = CTSVC_LANG_ORIYA;
+       else if (!strncmp(system_lang, "si", strlen("si")))
+               type = CTSVC_LANG_SINHALA;
+       else if (!strncmp(system_lang, "gu", strlen("gu")))
+               type = CTSVC_LANG_GUJARATI;
+       else if (!strncmp(system_lang, "kn", strlen("kn")))
+               type = CTSVC_LANG_KANNADA;
+       else if (!strncmp(system_lang, "lo", strlen("lo")))
+               type = CTSVC_LANG_LAO;
+       else if (!strncmp(system_lang, "he", strlen("he")))
+               type = CTSVC_LANG_HEBREW;
+       else if (!strncmp(system_lang, "vi", strlen("vi")))
+               type = CTSVC_LANG_VIETNAMESE;
+       else if (!strncmp(system_lang, "fa", strlen("fa")))
+               type = CTSVC_LANG_PERSIAN;
+       else if (!strncmp(system_lang, "uz", strlen("uz")))
+               type = CTSVC_LANG_UZBEK;
+       else if (!strncmp(system_lang, "ur", strlen("ur")))
+               type = CTSVC_LANG_URDU;
+       else if (!strncmp(system_lang, "sq", strlen("sq")))
+               type = CTSVC_LANG_ALBANIAN;
+       else if (!strncmp(system_lang, "my", strlen("my")))
+               type = CTSVC_LANG_BURMESE;
+       else if (!strncmp(system_lang, "ms", strlen("ms")))
+               type = CTSVC_LANG_MALAY;
+       else if (!strncmp(system_lang, "km", strlen("km")))
+               type = CTSVC_LANG_KHMER;
+       else if (!strncmp(system_lang, "id", strlen("id")))
+               type = CTSVC_LANG_INDONESIAN;
+       else if (!strncmp(system_lang, "tl", strlen("tl")))
+               type = CTSVC_LANG_TAGALOG;
+       else
+               type = CTSVC_LANG_OTHERS;
+
+       return type;
+}
+
+static char *langset = NULL;
+
+char* ctsvc_get_langset()
+{
+       return langset;
+}
+
+void ctsvc_set_langset(char *new_langset)
+{
+       free(langset);
+       langset = new_langset;
+}
+
diff --git a/native/ctsvc_localize.h b/native/ctsvc_localize.h
new file mode 100755 (executable)
index 0000000..22959c9
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CTSVC_LOCALIZE_H__
+#define __TIZEN_SOCIAL_CTSVC_LOCALIZE_H__
+
+#include <unicode/utypes.h>
+
+#include "ctsvc_localize_jp.h"
+#include "ctsvc_localize_kor.h"
+
+enum SORTTYPE{
+       CTSVC_SORT_OTHERS,              // 0??
+       CTSVC_SORT_NUMBER,              // 1
+       CTSVC_SORT_PRIMARY,             // 2
+       CTSVC_SORT_SECONDARY,   // 3
+       CTSVC_SORT_WESTERN,             // 4
+       CTSVC_SORT_KOREAN,              // 5
+       CTSVC_SORT_JAPANESE,            // 6
+       CTSVC_SORT_CJK,                 // 7
+       CTSVC_SORT_CYRILLIC,            // 8
+       CTSVC_SORT_GREEK,                       // 9
+       CTSVC_SORT_ARMENIAN,        // 10
+       CTSVC_SORT_ARABIC,          // 11
+       CTSVC_SORT_DEVANAGARI,  // hindi
+       CTSVC_SORT_GEORGIAN,    // 13
+       CTSVC_SORT_TURKISH,     // 14
+       CTSVC_SORT_THAI,        // 15
+       CTSVC_SORT_BENGALI,     // 16
+       CTSVC_SORT_PUNJABI,     // 17
+       CTSVC_SORT_MALAYALAM,   // 18
+       CTSVC_SORT_TELUGU,      // 19
+       CTSVC_SORT_TAMIL,       // 20
+       CTSVC_SORT_ORIYA,       // 21
+       CTSVC_SORT_SINHALA,     // 22
+       CTSVC_SORT_GUJARATI,    // 23
+       CTSVC_SORT_KANNADA,     // 24
+       CTSVC_SORT_LAO,         // 25
+       CTSVC_SORT_HEBREW,          // 26
+       CTSVC_SORT_BURMESE,             // 27
+       CTSVC_SORT_KHMER,               // 28
+};
+
+char* ctsvc_get_langset();
+void ctsvc_set_langset(char *new_langset);
+
+int ctsvc_get_name_sort_type(const char *src);
+int ctsvc_get_sort_type_from_language(int language);
+
+int ctsvc_get_language_type(const char *system_lang);
+const char *ctsvc_get_language_locale(int lang);
+void ctsvc_extra_normalize(UChar *word, int32_t word_size);
+
+#endif // __TIZEN_SOCIAL_CTSVC_LOCALIZE_H__
diff --git a/native/ctsvc_localize_ch.c b/native/ctsvc_localize_ch.c
new file mode 100755 (executable)
index 0000000..2b0356e
--- /dev/null
@@ -0,0 +1,2318 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <unicode/uchar.h>
+#include <unicode/ustring.h>
+
+
+#include "ctsvc_internal.h"
+#include "ctsvc_localize_ch.h"
+#include "ctsvc_localize_utils.h"
+
+
+#define CHINESE_COUNT                                          20902
+#define CHINESE_DUOYINZI_MAX_COUNT                     6
+
+
+#define CHINESE_UNICODE_START                          0x4E00
+#define CHINESE_UNICODE_END                                    0x9FA5
+
+static const char* const pinyin_spell_table[] = {
+       "yi","ding|zheng","kao|qiao|yu","qi","shang","xia","mo","wan|mo","zhang","san",
+       "shang","xia","qi|ji","bu|fou","yu","mian","gai","chou","chou","zhuan",
+       "qie|ju","pi","shi","shi","qiu","bing","ye","cong","dong","si",
+       "cheng","diu","qiu","liang","diu","you","liang","yan","bing","sang",
+       "gun","jiu","ge","ya","pan","zhong","ji","jie","feng","guan|kuang",
+       "chuan","chan","lin","zhuo","zhu","ba","wan","dan","wei","zhu",
+       "jing","li","ju","pie","fu","yi|ji","yi","nai","wu","jiu",
+       "jiu","tuo|zhe","me|yao|mB","yi","ho","zhi","wu","zha","hu","fa",
+       "le|yue","yin","ping","pang","qiao","hu","guai","cheng|sheng","cheng|sheng","yi",
+       "hao","zhe","mie|nie","jiu","qi","ye","xi","xiang","gai","jiu",
+       "hal","hol","shu","dou","shi","ji","nang","kal","keol","tol",
+       "mol","ol","mai","luan","cal","ru","xue","yan","phoi","sha",
+       "na","qian","sol","er","zu","ceor","qian|gan","zhi|luan","gui","qian",
+       "luan","lin","yi","jue","liao|le","ma","yu","zheng","shi","shi",
+       "er","chu","yu","kui","yu","yun","hu","qi","wu","jing",
+       "si","sui","gen","gen","ya","xie|suo","ya","qi|zhai","ya","ji|qi",
+       "tou","wang|wu","kang","da","jiao","hai","yi","chan","heng|peng","mu",
+       "ye","xiang","jing","ting","liang","xiang","jing","ye","qin|qing","bo",
+       "you","xie","dan","lian","duo","wei|men","ren","ren","ji","ji",
+       "wang","yi","shi|shen","ren","le","ding","ze","jin","pu","chou|qiu",
+       "ba","zhang","jin","jie","bing","reng","cong|zong","fo","jin|san","lun",
+       "bing","cang","zi|zai","shi","ta","zhang","fu","xian","xian","tuo|cha|duo",
+       "hong","tong","ren","qian","gan|han","yi|ge","bo","dai","ling","yi",
+       "chao","chang|zhang","sa","chang","yi","mu","men","ren","fan","chao|miao",
+       "yang|ang","qian","zhong","pi","wo","wu","jian","jia|jie","yao|fo","feng",
+       "cang","ren","wang","fen|bin","di","fang","zhong","qi","pei","yu",
+       "diao","dun","wen","yi","xin","kang","yi","ji","ai","wu",
+       "ji|qi","fu","fa","xiu|xu","jin","pi","dan","fu","tang","zhong",
+       "you","huo","hui|kuai","yu","cui","yun","san","wei","chuan|zhuan","che|ju",
+       "ya","qian","shang","chang","lun","cang|chen","xun","xin","wei","zhu",
+       "chi","xian|xuan","nu","bo|bai|ba","gu","ni","ni","xie","ban","xu",
+       "ling","zhou","shen","qu","si|ci","peng","si|shi","qie|jia|ga","pi","zhi",
+       "si","yi|chi","zheng","dian|tian","han|gan","mai","dan","zhu","bu","qu",
+       "bi","zhao|shao","ci","wei","di","zhu","zuo","you","yang","ti|ben",
+       "zhan|dian","he","bi","tuo","she","yu","yi|die","fo|fu|bi|bo","zuo","gou|kou",
+       "ning","tong","ni","xian","qu","yong","wa","qian","shi","ka",
+       "bao","pei","hui|huai","ge","lao","xiang","ge","yang","bai","fa",
+       "ming","jia","er|nai","bing","ji","hen","huo","gui","quan","tiao",
+       "jiao","ci","yi","shi","xing","shen","tuo","kan","zhi","gai",
+       "lai","yi","chi","kua","gong","li","yin","shi","mi","zhu",
+       "xu","you","an","lu","mou","er","lun","dong|tong","cha","chi",
+       "xun","gong","zhou","yi","ru","cun","xia","si","dai","lv",
+       "ta","jiao|yao","zhen","ce|ze|zhai","qiao","kuai","chai","ning","nong","jin",
+       "wu","hou","jiong","cheng|ting","zhen","zuo","hao","qin","lv","jv",
+       "shu|dou","ting","shen","tuo|tui","bo","nan","xiao","bian|pian","tui","yu",
+       "xi","cu","e","qiu","xu","guang","ku","wu","jun","yi",
+       "fu","liang","zu","qiao|xiao","li","yong","hun","jing","qian","san",
+       "pei","su","fu","xi","li","fu","ping","bao","yu|shu","si|qi",
+       "xia","xin|shen","xiu","yu","di","che|ju","chou","zhi","yan","liang|lia",
+       "li","lai","si","jian","xiu","fu","huo","ju","xiao","pai",
+       "jian","biao","chu|ti","fei","feng","ya","an","bei","yu","xin",
+       "bi","hu|chi","chang","zhi","bing","jiu","yao","cui|zu","liang|lia","wan",
+       "lai","cang","zong","ge","guan","bei","tian","shu","shu","men",
+       "dao","tan","jue","chui","xing","peng","tang|chang","hou","yi","qi",
+       "ti","gan","liang|jing","jie","sui","chang","jie","fang","zhi","kong",
+       "juan","zong","ju","qian","ni","lun","zhuo","wo|wei","luo","song",
+       "leng","hun","dong","zi","ben","wu","ju","nai","cai","jian",
+       "zhai","ye","zhi","sha","qing","ning","ying","cheng|chen","qian","yan",
+       "ruan","zhong|tong","chun","jia","ji|jie","wei","yu","bing","ruo","ti",
+       "wei","pian","yan","feng","tang|dang","wo","e","xie","che","sheng",
+       "kan","di","zuo","cha","ting","bei","xie","huang","yao","zhan",
+       "chou|qiao","an","you","jian","xu","zha","ci","fu","bi","zhi",
+       "zong","mian","ji","yi","xie","xun","cai|si","duan","ce|ze|zhai","zhen",
+       "ou","tou","tou","bei","zan|za|zBn","lv|lou","jie","wei","fen","chang",
+       "kui|gui","sou","zhi|si","su","xia","fu","yuan","rong","li","nu",
+       "yun","jiang|gou","ma","bang","dian","tang","hao","jie","xi","shan",
+       "qian|jian","que|jue","cang|chen","chu","san","bei","xiao","rong","yao","ta|tan",
+       "suo","yang","fa","bing","jia","dai","zai","tang","gu","bin",
+       "chu","nuo","can","lei","cui","yong","zao|cao","zong","peng","song",
+       "ao","chuan|zhuan","yu","zhai","qi|cou","shang","chuang","jing","chi","sha",
+       "han","zhang","qing","yan","di","xie","lv|lou","bei","piao|biao","jin",
+       "lian","lu","man","qian","xian","tan","ying","dong","zhuan","xiang",
+       "shan","qiao","jiong","tui","zun","pu","xi","lao","chang","guang",
+       "liao","qi","cheng|deng","zhan|zhuan|chan","wei","ji","bo","hui","chuan","tie|jian",
+       "dan","jiao|yao","jiu","seng","fen","xian","yu|ju","e|wu","jiao","jian",
+       "tong|zhuang","lin","bo","gu","xian","su","xian","jiang","min","ye",
+       "jin","jia|jie","qiao","pi","feng","zhou","ai","sai","yi","jun",
+       "nong","chan|tan|shan","yi","dang","jing","xuan","kuai","jian","chu","dan",
+       "jiao","sha","zai","can","bin","an","ru","tai","chou","chai",
+       "lan","ni|yi","jin","qian","meng","wu","ning","qiong","ni","chang",
+       "lie","lei","lv","kuang","bao","yu","biao","zan","zhi","si",
+       "you","hao","qing","chen","li","teng","wei","long","chu","chan",
+       "rang|xiang","shu","hui|xie","li","luo","zan","nuo","tang","yan","lei",
+       "nang","er","wu","yun","zan","yuan","xiong","chong","zhao","xiong",
+       "xian","guang","dui|rui|yue","ke","dui|rui|yue","mian","tu","chang|zhang","er","dui|rui|yue",
+       "er|ni","jin","tu","si","yan","yan","shi","shike","dang","qibnke",
+       "dou","gongfenPPPU","hboke","shen","dou","baike","jing","gongli","huang","ru",
+       "wang","nei","quan","liang","yu|shu","ba","gong","liu|lu","xi","han",
+       "lan","gong","tian","guan","xing","bing","qi|ji","ju","dian","zi|ci",
+       "bun","yang","jian","shou","ji","yi","ji","chan","jiong","mao",
+       "ran","nei|na","yuan","mao","gang","ran","ce","jiong","ce","zai",
+       "gua","jiong","mao","zhou","mao|mo","gou","xu","mian","mi","rong",
+       "yin|you","xie","kan","jun","nong","yi","shen","shi","guan","meng",
+       "zhong","zui","yuan","ming","kou","lin","fu","xie","mi","bing",
+       "dong","tai","gang","feng|ping","bing","hu","chong","jue","ya","kuang",
+       "ye","leng","pan","fa","min","dong","xian","lie","qia","jian",
+       "jing|cheng","sou","mei","tu","qi","gu","zhun","song","jing|cheng","liang",
+       "qing","diao","ling","dong","gan","jian","yin","cou","ai","li",
+       "cang","ming","zhun","cui","si","duo","jin","lin","lin","ning",
+       "xi","du","ji","fan","fan","fan","feng","ju","chu","yi kB|yi kB no bo li|tB ko",
+       "feng","mu","zhi","fu","feng","ping","feng","kai","huang","kai",
+       "gan","deng","ping","kan|qian","xiong","kuai","tu","ao|wa","chu","ji",
+       "dang","han","han","zao","dao","diao","dao","ren","ren","chuang",
+       "fen","qie","yi","ji","kan","qian","cun","chu","wen","ji",
+       "dan","xing","hua","wan","jue","li","yue","lie","liu","ze",
+       "gang","chuang","fu","chu","qu","diao","shan","min","ling","zhong",
+       "pan","bie","jie","jie","pao|bao","li","shan","bie","chan","jing",
+       "gua","geng","dao","chuang","kui","ku","duo","er","zhi","shua",
+       "quan|xuan","cha|sha","ci","ke","jie","gui","ci","gui","kai","duo",
+       "ji","ti","jing","dou","luo","ze","yuan","cuo","xiao|xue","kei|ke",
+       "la","qian","cha|sha","chuang","gua","jian","cuo","li","ti","fei",
+       "pou","chan","qi","chuang","zi","gang","wan","bao|bo","ji","duo",
+       "qing","yan|shan","du|zhuo","jian","ji","bao|bo","yan","ju","huo","sheng",
+       "jian","duo","zhi|duan","wu","gua","fu|pi","sheng","jian","ge","da|zha",
+       "kai","chuang","chuan","chan","tuan|zhuan","lu|jiu","li","peng","shan","piao",
+       "kou","jiao|chao","gua","qiao","jue","hua","zha","zhuo","lian","ju",
+       "pi","liu","gui","jiao|chao","gui","jian","jian","tang","huo","ji",
+       "jian","yi","jian","zhi","chan","zuan","mo","li","zhu","li",
+       "ya","quan","ban","gong","jia","wu","mai","lie","jin|jing","keng",
+       "xie|lie","zhi","dong","zhu|chu","nu","jie","qu","shao","yi","zhu",
+       "miao","li","jin|jing","lao","lao","juan","kou","yang","wa","xiao",
+       "mou","kuang","jie","lie","he","shi","ke","jin|jing","gao","bo|bei",
+       "min","chi","lang","yong","yong","mian","ke","xun","juan","qing",
+       "lu","bu","meng","chi","le|lei","kai","mian","dong","xu","xu",
+       "kan","wu","yi","xun","weng|yang","sheng","lao","mu","lu","piao",
+       "shi","ji","qin","jiang","jiao|chao","quan","xiang","yi","qiao","fan",
+       "juan","tong|dong","ju","dan","xie","mai","xun","xun","lv","li",
+       "che","rang|xiang","quan","bao","shao","yun","jiu","bao","gou","wu",
+       "yun","mo","xiong","gai","gai","bao","cong","yi","xiong","peng",
+       "ju","tao|yao","ge","pu","e","pao","fu","gong","da","jiu",
+       "gong","bi","hua","bei","nao","chi|shi","fang","jiu","yi","za",
+       "jiang","kang","jiang","kuang","hu","xia","qu","fan","gui","qie",
+       "zang|cang","kuang","fei","hu","yu","gui","kui|gui","hui","dan","kui|gui",
+       "lian","lian","suan","du","jiu","jue","xi","pi","qu|ou","yi",
+       "ke|qia","yan","bian","ni","qu|ou","shi","xun","qian","nian","sa",
+       "zu","sheng","wu","hui","ban","shi","xi","wan","hua","xie",
+       "wan","bei","zu|cu","zhuo","xie","dan|shan|chan","mai","nan|na","dan","ji",
+       "bo","shuai|lv","bu|bo","guan|kuang","bian","bu","zhan","qia|ka","lu","you",
+       "lu","xi","gua","wo","xie","jie","jie","wei","yang|ang","qiong",
+       "zhi","mao","yin","wei","shao","ji","que","luan","chi","juan",
+       "xie","xu","jin","que","wu","ji","e","qing","xi","san",
+       "chang|an|han","wei","e","ting","li","zhe|zhai","han|an","li","ya","ya",
+       "yan","she","di","zha|zhai","pang","ya","qie","ya","zhi|shi","ce",
+       "mang","ti","li","she","hou","ting","zui","cuo","fei","yuan",
+       "ce","yuan","xiang","yan","li","jue","sha|xia","dian","chu","jiu",
+       "jin","ao","gui","yan","si","li","chang","qian|lan","li","yan",
+       "yan","yuan","si|mou","gong|hong","lin|miao","rou|qiu","qu","qu","ke","lei",
+       "du","xian|xuan","zhuan","san","can|shen|cen|san","can|shen|cen|san","can|shen|cen|san","can|shen|cen|san","ai|yi","dai",
+       "you","cha","ji","you","shuang","fan","shou","guai","ba","fa",
+       "ruo","li","shu","zhuo|yi|li|jue","qu","shou","bian","xu","jia","pan",
+       "sou","ji","wei|yu","sou","die","rui","cong","kou","gu","ju|gou",
+       "ling","gua","tao|dao","kou","zhi","jiao","zhao|shao","ba","ding","ke",
+       "tai","chi","shi","you","qiu","po","ye|xie","hao","si","tan",
+       "chi","le","diao","ji","dug","hong","mie","xu|yu","mang","chi",
+       "ge","xuan|song","yao","zi","he|ge","ji","diao","dou|cun","tong","ming",
+       "hou","li","tu","xiang","zha","xia|he","ye","lv","a","ma|mB",
+       "ou","huo","yi","jun","chou","lin","tun","yin","fei","pi|bi",
+       "qin","qin","jie|ge","bu","fou|pi","ba","dun","fen","e|hua","han",
+       "ting","hang|keng","shun","qi","hong","zhi|zi","yin|shen","wu","wu","chao",
+       "na|ne","xue|chuo|jue","xi","chui","dou|ru","wen","hou","hou|hong|ou","wu|yu","gao",
+       "ya|yB","jun","lv","e","ge","wen","dai","qi","cheng","wu",
+       "gao","fu","jiao","hong","chi","sheng","na|ne","tun|tian","fu|?","yi",
+       "dai","ou","li","bei|bai","yuan|yun","wai|he|wo|wa|gua|guo","hua|qi","qiang","wu","e",
+       "shi","juan","pen","wen|min","ne","mou|m","ling","ran","you","di",
+       "zhou","shi","zhou","tie|che","xi","yi","qi|zhi","ping","zi|ci","gua|gu",
+       "zi|ci","wei","xu|hou|gou","he|a|ke","nao","xia","pei","yi","xiao|hao","shen",
+       "hu","ming","da|dan","qu","ju|zui","xian|gan","za","tuo","duo","pou",
+       "pao","bi","fu","yang","he","zha|za","he|huo|hu","hai","jiu","yong",
+       "fu","da","zhou","wa","ka","gu","ka|ga","zuo","bu","long",
+       "dong","ning","tuo","si","xian","huo","qi","er","e","guang",
+       "zha","die|xi","yi","lie","zi","mie","mi","zhi","yao","ji|xi|qia",
+       "zhou","ka|luo|lo|ge","shu|xun","zan|za|zBn","xiao","ke|hai","hui","kua","huai|shi","tao",
+       "xian","e|an","xuan","xiu","wai|he|wo|wa|gua|guo","yan|ye","lao","yi","ai","pin",
+       "shen","tong","hong","xiong","duo","wa|wB","ha","zai","you","die|di",
+       "pai","xiang","ai","gen|hen","kuang","ya","da","xiao","bi","yue|hui",
+       "nian","hua","xing","kuai","duo","po","ji|jie|zhai","nong","mou","yo",
+       "hao","yuan|yun","long","pou","mang","ge","o","chi","shao","li",
+       "na|nei|nB|ne","zu","he","ku","xiao","xian","lao","po|ba|bo","zhe","zha",
+       "liang|lang","ba","mie","lie|lv","sui","fu","bu","han","heng|hng","geng",
+       "chuo|yue","ge|jia","you","yan","gu","gu","bei|bai","han","suo","chun",
+       "yi","ai","jia|qian","tu","dan|xian|yan","wan","li","xi","tang","zuo",
+       "qiu","che","wu","zao","ya","dou","qi","di","qin","ma",
+       "ma","gong|hong","dou","ge","lao","liang","suo","zao","huan","leng",
+       "sha|shB","ji","zu","wo|wei","feng","jin|yin","hu|xia","qi","shou","wei",
+       "shua","chang","er|wa","li","qiang","an","jie|ze|zuo","yo","nian","yu",
+       "tian","lai","sha","xi","tuo","hu","ai","zhou|zhao|tiao","gou","ken",
+       "zhuo","zhuo|zhao","shang","di","heng","lan|lin","a","cai","qiang","zhun|tun|xiang|dui",
+       "wu","wen","cui|qi","sha|jie|die|ti","gu","qi","qi","tao","dan","dan",
+       "yue|wa","zi|ci","bi|tu","cui","chuo|chuai","he","ya","qi","zhe","fei",
+       "liang","xian","pi","sha","lB|la","ze","qing|ying","gua","pa","ze|shi",
+       "se","zhuan","nie","guo","luo","yan","di","quan","tan|chan|tuo","bo",
+       "ding","lang","xiao","ju","tang","chi","ti","an","jiu","dan",
+       "ka","yong","wei","nan","shan","yu","zhe","la","jie","hou",
+       "han","die|zha","zhou","chai","wai","nuo|re","huo|guo|xu","yin","zan|za|zBn","yao",
+       "o|wo","mian","hu","yun","chuan","hui","huan","huan|yuan|xuan|he","xi","he|ye",
+       "ji","kui","zhong|chuang","wei","sha","xu","huang","duo|zha","yan","xuan",
+       "liang","yu","sang","chi","qiao|jiao","yan","dan|shan|chan","pen|ben","can|sun|qi","li",
+       "yo","zha|cha","wei","miao","ying","pen","pbo","kui","xi","yu",
+       "jie","lou","ku","zao|qiao","hu","ti","yao","he|xiao|hu","sha|a","xiu",
+       "qiang","se","yong","su","gong|hong","xie","yi|ai","suo","ma|mB","cha",
+       "hai","ke","ta|da","sang","chen","ru","sou","wa|gu","ji","beng|pang",
+       "wu","xian|qian|qie","shi","ge","zi","jie","lao","weng","wa","si",
+       "chi","hao","suo","jia","hai|hei","suo","qin","nie","he","zi",
+       "sai","ng","ge","na","dia","ai","qiang","tong","bi","ao",
+       "ao","lian","zui|sui","zhe|zhu","mo","sou","sou","tan","di","qi",
+       "jiao","chong","jiao|dao","kai|ge","tan","shan|can","cao","jia","ai","xiao",
+       "piao","lou","ga","gu","xiao|jiao","hu","hui","guo","ou","xian",
+       "ze","chang","xu|shi","po","de|dei","ma","ma","hu","le","du",
+       "ga","tang","ye","beng","ying","sai","jiao","mi","xiao","hua",
+       "mai","ran","zuo","peng","lao","xiao","ji","zhu","chao|zhao","kui",
+       "zui","xiao","si","hao","fu|?","liao","qiao","xi","chu|xu|shou","tan|chan",
+       "dan|tan","hei|mo","xun","e","zun","fan|bo","chi","hui","zan","chuang",
+       "cu|za|he","dan","jue","tun|kuo","ceng","jiao","ye","xi","qi","hao",
+       "lian","xu|shi","deng","hui","yin","pu","jue","qin","xun","nie",
+       "lu","si","yan","ying","da","zhan","o","zhou|zhuo","jin","nong",
+       "yue|hui","xie","qi","e","zao","yi","shi","jiao|qiao|chi","yuan","ai",
+       "yong","jue|xue","kuai","yu","pen","dao","ga","xin|hen","dun","dang",
+       "xin","sai","pi","pi","yin","zui","ning","di","lan","ta",
+       "huo|o","ru","hao","he|xia","yan","duo","xiu|pi","zhou|chou","ji|jie|zhai","jin",
+       "hao","ti","chang","xun","me","ca|cha","ti","lu","hui","bo|pao|bao",
+       "you","nie","yin","hu","mei|me|mo","hong","zhe","li","liu","xie|hai",
+       "nang","xiao","mo","yan","li","lu","long","po","dan","chen",
+       "pin","pi","xiang","huo","me","xi","duo","ku","yan","chan",
+       "ying","rang","dian","la","ta","xiao","jiao|jue","chuo","huan","huo",
+       "zhuan","nie","xiao","ca","li","chan","chai","li","yi","luo",
+       "nang","za|zan|can","su","xi","zeng","jian","yan|za|nie","zhu","lan","nie",
+       "nang","ramo","luo","wei|guo","hui","yin","qiu","si","nin","jian|nan",
+       "hui","xin","yin","nan","tuan","tuan","dun|tun","kang","yuan","jiong",
+       "pian","yun","cong","hu","hui","yuan","e","guo","kun","cong",
+       "wei|tong","tu","wei","lun","guo","qun","ri","ling","gu","guo",
+       "tai","guo","tu","you","guo","yin","hun","pu","yu","han",
+       "yuan","lun","quan|juan","yu","qing","guo","chuan|chui","wei","yuan","quan|juan",
+       "ku","pu","yuan","yuan","ya","tuan","tu","tu","tuan","lve",
+       "hui","yi","huan|yuan","luan","luan","tu","ya","tu","ting","sheng",
+       "pu","lu","kuai","ya","zai","wei|xu","ge","yu|zhun","wu","gui",
+       "pi","yi","di|de","qian|su","qian","zhen","zhuo","dang","qia","xia",
+       "shan","kuang","chang","qi|yin","nie","mo","ji","jia","zhi","zhi",
+       "ban","xun","yi","qin","mei|fen","jun","rong|keng","tun|dun","fang","ben|fen",
+       "ben","tan","kan","huai|pei|pi","zuo","keng","bi","jing","di|lan","jing",
+       "ji","kuai","di","jing","jian","tan","li","ba","wu","fen",
+       "zhui","po","pan|ban","tang","kun","qu","tan","zhi","tuo","gan",
+       "ping","dian","gua","ni","tai","pi","jiong","yang","fo","ao",
+       "lu","qiu","mu","ke","gou","xue","fa","di|chi","che","ling",
+       "zhu","fu","hu","zhi","chui","la","long","long","lu","ao",
+       "dai","pao","min","xing","dong|tong","ji","he","lv","ci","chi",
+       "lei","gai","yin","hou","dui","zhao","fu","guang","yao","duo",
+       "duo","gui","cha","yang","yin","fa","gou","yuan","die","xie",
+       "ken","shang","shou","e","bing","dian","hong","ya","kua","da",
+       "ka","dang","kai","hang","nao","an","xing","xian","yuan|huan","bang",
+       "pou|fu","ba","yi","yin","han","xu","chui","cen","geng","ai",
+       "beng|feng","di|fang","que|jue","yong","jun","xia|jia","di","mai|man","lang","juan",
+       "cheng","yan|shan","qin|jin","zhe","lie","lie","pu|bu","cheng","hua","bu",
+       "shi","xun","guo","jiong","ye","nian","di","yu","bu","ya",
+       "quan","sui|su","pi","qing|zheng","wan","ju","lun","zheng|cheng","kong","chong|shang",
+       "dong","dai","tan","an","cai","chu|tou","beng","xian|kan","zhi","duo",
+       "yi|shi","zhi","yi","pei","ji","zhun","qi","sao","ju","ni",
+       "ku","ke","tang","kun","ni","jian","dui","jin","gang","yu",
+       "e","peng|beng","gu","tu","leng","fang","ya","qian|zan|jian","kun","an",
+       "shen","duo|hui","nao","tu","cheng","yin","huan","bi","lian","guo",
+       "die","zhuan","hou","bao|bu|pu","bao","yu","di","mao|mou|wu","jie","ruan",
+       "e|ai|ye","geng","kan","zong","yu","huang","e","yao","yan","bao",
+       "ji","mei","chang","du","tuo","yin","feng","zhong","jie","jin",
+       "feng","gang","chuan","jian","ping","lei","jiang","huang","leng","duan",
+       "wan","xuan","xi","ji","kuai","ying","ta","cheng","yong","kai",
+       "su","su","shi","mi","ta","weng","cheng","tu","tang","que",
+       "zhong","li","peng","bang","sai|se","zang","dui","tian","wu","zheng",
+       "xun","ge","zhen","ai","gong","yan","xian","tian|zhen","yuan","wen",
+       "xie","liu","hai","lang","chang","peng","beng","chen","lu","lu",
+       "ou|qiu","qian|zan|jian","mei","mo","zhuan|tuan","shuang","shu","lou","chi","man",
+       "biao","jing","qi","shu","zhi|di","zhang","kan","yong","dian","chen",
+       "zhi|zhuo","xi","guo","qiang","jin","shang","shang","mu","cui","yan",
+       "ta","zeng","qian","qiang","liang","wei","zhui","qiao","zeng","xu",
+       "shan","shan","fa","pu","kuai|tui","tuan|dong","fan","qiao|que","mo","dun",
+       "dun","zun|dun","di","sheng","duo|hui","duo","tan","deng","wu","fen",
+       "huang","tan","da","ye","zhu","jian","ao","qiang","ji","qiao|ao",
+       "ken","yi|tu","pi","bi","dian","jiang","ye","yong","xue|bo|jue","tan",
+       "lan","ju","huai","dang","rang","qian","xun","xian|lan","xi","he",
+       "ai","ya","dao","hao","ruan","jin","lei","kuang","lu","yan",
+       "tan","wei","huai","long","long","rui","li","lin","rang","chan",
+       "xun","yan","lei","ba","wan","shi","ren","san","zhuang","zhuang",
+       "sheng","yi","mai","ke|qiao","zhu","zhuang","hu","hu","kun","yi",
+       "hu","xu","kun","shou","mang","dun","shou","yi","zhi|zhong","gu|ying",
+       "chu","jiang|xiang","feng|pang","bei","zhai","bian","sui","qun","ling","fu",
+       "cuo","xia","xiong|xuan","xie","nao","xia","kui","xi","wai","yuan|wan",
+       "mao|wan","su","duo","duo","ye","qing","yi","gou","gou","qi",
+       "meng","meng","yin","huo","chen","da|dai","ce","tian","tai","fu",
+       "guai","yao","yang","hang|ben","gao","shi","tao|ben","tai","tou","yan|tao",
+       "bi","yi","kua","jia|ga|xia","duo","hua","kuang","yun","jia|ga|xia","ba",
+       "en","lian","huan","di|ti","yan","pao","juan","qi|ji","nai","feng",
+       "xie","fen","dian","quan|juan","kui","zou","huan","qi|qie|xie","kai","she|chi|zha",
+       "ben","yi","jiang","tao","zang|zhuang","ben","xi","huang","fei","diao",
+       "xun|zhui","beng","dian","ao","she","weng","po|ha|tai","ao|yu","wu","ao|yu",
+       "jiang","lian","duo","yun","jiang","shi","fen","huo","bi","luan",
+       "duo|che","nv","nu","ding|tian","nai","qian","jian","ta|jie","jiu","nuan",
+       "cha","hao","xian","fan","ji","shuo","ru","fei|pei","wang","hong",
+       "zhuang","fu","ma","dan","ren","fu|you","jing","yan","hai|jie","wen",
+       "zhong","pa","du","ji","keng|hang","zhong","yao","jin","yun","miao",
+       "fou|pei|pi","chi","yue|jue","zhuang","niu","yan","na|nan","xin","fen","bi",
+       "yu","tuo","feng","wan|yuan","fang","wu","yu","gui","du","ba",
+       "ni","zhou","zhuo","zhao","da","ni|nai","yuan","tou","xian|xuan|xu","zhi|yi",
+       "e","mei","mo","qi","bi","shen","qie","e","he","xu",
+       "fa","zheng","min","ban","mu","fu","ling","zi","zi","shi",
+       "ran","shan","yang","gan","jie","gu","si","xing","wei","zi",
+       "ju","shan","pin","ren","yao","dong","jiang","shu","ji","gai",
+       "xiang","hua|huo","juan","jiao|xiao","gou|du","mu|lao","jian","jian","yi","nian",
+       "zhi","zhen","ji","xian","heng","guang","jun|xun","kua|hu","yan","ming",
+       "lie","pei","e","you","yan","cha","shen|xian","yin","shi","gui",
+       "quan","zi","song","wei","hong","wa","lou","ya","rao","jiao",
+       "luan","ping","xian","shao","li","cheng|sheng","xie","mang","fu","suo",
+       "wu|mu","wei","ke","chuo|lai","chuo","ting","niang","xing","nan","yu",
+       "na|nuo","pou|bi","nei|sui","juan","shen","zhi","han","di","zhuang","e",
+       "pin","tui","man","mian","wu|yu","yan","wu","xi|ai","yan","yu",
+       "si","yu","wa","li","xian","ju","qu","zhui|shui","qi","xian",
+       "zhuo","dong","chang","lu","ai|e","e","e","lou","mian","cong",
+       "pou|pei|bu","ju","po","cai","ling","wan","biao","xiao","shu","qi",
+       "hui","fu|fan","wo","wo","tan","fei","fei","jie","tian","ni",
+       "quan|juan","jing","hun","jing","qian|jin","dian","xing","hu","wan|wa","lai",
+       "bi","yin","zhou|chou","chuo|nao","fu","jing","lun","an|n<e","lan","hun|kun",
+       "yin","ya","ju","li","dian","xian","huB|dB tBi","hua","ying","chan",
+       "shen","ting","dang|yang","yao","wu","nan","ruo|chuo","jia","tou|yu","xu",
+       "yu","wei","di|ti","rou","mei","dan","ruan|nen","qin","hui","wo",
+       "qian","chun","miao","fu","jie","duan","yi|pei","zhong","mei","huang",
+       "mian","an","ying","xuan","jie","wei","mei","yuan","zheng","qiu",
+       "ti","xie","tuo|duo","lian","mao","ran","si","pian","wei","wa",
+       "cu","hu","ao|yun|wo","jie","bao","xu","tou|yu","gui","chu|zou","yao",
+       "pi","xi","yuan","ying","rong","ru","chi","liu","mei","pan",
+       "ao|yun|wo","ma","gou","kui","qin|shen","jia","sao","zhen","yuan","jie|suo",
+       "rong","ming","ying","ji","su","niao","xian","tao","pang","lang",
+       "nao","biao","ai","pi","pin","yi","piao","yu","lei","xuan",
+       "man","yi","zhang","kang","yong","ni","li","di","gui","yan",
+       "jin","zhuan","chang","ze","han|nan","nen","lao","mo","zhe","hu",
+       "hu","ao","nen","qiang","ma","pie","gu","wu","qiao","tuo",
+       "zhan","miao","xian","xian","mo","liao","lian","hua","gui","deng",
+       "zhi","xu","yi","hua","xi","kui","rao","xi","yan","chan",
+       "jiao","mei","fan","fan","xian|yan|jin","yi","hui","jiao","fu","shi",
+       "bi","shan","sui","qiang","lian","huan|xuan|qiong","xin","niao","dong","yi",
+       "can","ai","niang","ning","mo","tiao","chou","jin","ci","yu",
+       "pin","rong","ru","nai","yan","tai","ying","qian","niao","yue",
+       "ying","mian","bi","mo","shen","xing","ni","du","liu","yuan",
+       "lan","yan","shuang","ling","jiao","niang","lan","xian|qian","ying","shuang",
+       "xie|hui","huan|quan","mi","li","luan","yan","zhu|chuo","lan","zi","jie",
+       "jue","jue","kong","yun","zi|ma","zi","cun","sun|xun","fu","bei",
+       "zi","xiao","xin","meng","si","tai","bao","ji","gu","nu",
+       "xue","you","zhuan","hai","luan","sun|xun","nao","mie","cong","qian",
+       "shu","chan|can","ya","zi","ni","fu","zi","li","xue","bo",
+       "ru","nai","nie","nie","ying","luan","mian","ning","rong","ta",
+       "gui","zhai","qiong","yu","shou","an","tu|jia","song","wan","rou",
+       "yao","hong","yi","jing","zhun","mi|fu","zhu","dang","hong","zong",
+       "guan","zhou","ding","wan|yuan","yi","bao","shi","shi","chong","shen",
+       "ke","xuan","shi","you","huan","yi","tiao","shi","xian","gong",
+       "cheng","qun","gong","xiao","zai","zha","bao|shi","hai","yan","xiao",
+       "jia|jiB","cai","chen","rong","huang","mi","kou","kuan","bin","su|xiu",
+       "cai","zan","ji","yuan","ji","yin","mi","kou","qing","he",
+       "zhen","jian","fu","ning","bing","huan","mei","qin","han","yu",
+       "shi","ning","jin|qin","ning","zhi","yu","bao","kuan","ning","qin",
+       "mo","cha","ju|lou","gua","qin","hu","wu","liao","shi","ning",
+       "zhai","shen","wei","xie","kuan","hui","liao","jun","huan","yi",
+       "yi","bao","qin","chong","bao","feng","cun","dui","si","xun",
+       "dao","l<e|luo","dui","shou","po","feng","zhuan","fu","she|ye|yi","kei|ke",
+       "jiang","jiang","zhuan","wei|yu","zun","xun","shu|zhu","dui","dao","xiao",
+       "jie|ji","shao","er","er","er","ga","jian","shu","chen","shang",
+       "shang","mo","ga","chang","liao","xian","xian","hun","you","wang",
+       "you","liao","liao","yao","long|mang|meng|pang","wang","wang","wang","ga","yao",
+       "duo","kui","zhong","jiu","gan","gu","gan","tui","gan","gan",
+       "shi","yin","chi|che","kao","ni","jin","wei|yi","niao|sui","ju","pi",
+       "ceng","xi","bi","ju","jie","tian","qu","ti","jie","wu",
+       "diao","shi","shi","ping|bing","ji","xie","zhen","xi","ni","zhan",
+       "xi","wei","man","e","lou","ping|bing","ti","fei","shu|zhu","xie|ti",
+       "tu","lv","lv","xi","ceng","lv","ju","xie","ju","jue",
+       "liao","jue","shu|zhu","xi","che|cao","tun|zhun","ni|ji","shan","wa","xian",
+       "li","an","hui","hui","hong|long","yi","qi","ren","wu","han|an",
+       "shen","yu","chu","sui","qi|kai","yin","yue","ban","yao","ang",
+       "ya","wu","jie","e","ji","qian","fen","wan","qi","cen",
+       "qian","qi","cha","jie","qu","gang","xian","ao","lan","dao",
+       "ba","zuo","zuo","yang","ju","gang","ke","gou","xue","po",
+       "li","tiao","ju","yan","fu","xiu","jia","ling","tuo","pi",
+       "ao","dai","kuang","yue","qu","hu","po","min","an","tiao",
+       "ling","di","ping","dong","zBi|ze mo","kui","xiu","mao","tong","xue",
+       "yi","bian","he","ke|ba","luo","e","fu|nie","xun","die","lu",
+       "en","er","gai","quan","tong|dong","yi","mu","shi","an","wei",
+       "huan","zhi|shi","mi","li","fa","tong","wei","you","qia","xia",
+       "li","yao","jiao|qiao","zheng","luan","jiao","e","e","yu","xie|ye",
+       "bu","qiao","qun","feng","feng","nao","li","you","xian","rong",
+       "dao","shen","cheng","tu","geng","jun","gao","xia","yin","wu",
+       "lang","kan","lao","lai","xian","que","kong","chong","chong","ta",
+       "lin","hua","ju","lai","qi","min","kun","kun","zu|cui","gu",
+       "cui","ya","ya","gang","lun","lun","ling","jue","duo","zheng",
+       "guo","yin","dong","han","zheng","wei","xiao","pi|bi","yan","song",
+       "jie","beng","zu","jue","dong","zhan|chan","gu","yin","zi","ze",
+       "huang","yu","wai|wei","yang|dang","feng","qiu","yang","ti","yi","zhi|shi",
+       "shi|die","zai","yao","e","zhu","kan|zhan","lv","yan","mei","han",
+       "ji","ji","huan","ting","sheng","mei","qian|kan","wu|mao","yu","zong",
+       "lan","ke|jie","yan","yan","wei","zong","cha","sui","rong","ke",
+       "qin","yu","qi","lou","tu","cui","xi","weng","cang","dang|tang",
+       "rong|ying","jie","kai|ai","liu","wu","song","kao|qiao","zi","wei","beng",
+       "dian","cuo","qin|qian","yong","nie","cuo","ji","shi","ruo","song",
+       "zong","jiang","liao","kang","yan","die|di","cen","ding","tu","lou",
+       "zhang","zhan|chan","zhan|chan","ao","cao","qu","qiang","wei","zui","dao",
+       "dao","xi","yu","pi|pei","long","xiang","ceng","bo","qin","jiao",
+       "yan","lao","zhan","lin","liao","liao","qin","deng","tuo","zun",
+       "jiao|qiao","jue|gui","yao","jiao","yao","jue","zhan|shan","yi","xue","nao",
+       "ye","ye","yi","nie","xian","ji","xie|jie","ke|jie","gui|xi|juan","di",
+       "ao","zui","wei","ni","rong","dao","ling","jie","yu","yue",
+       "yin","ru","jie","li|lie","gui|xi|juan","long","long","dian","ying|hong","xi",
+       "ju","chan","ying","kui","yan","wei","nao","quan","chao","cuan",
+       "luan","dian","dian","nie","yan","yan","yan","kui","yan","chuan",
+       "kuai","chuan","zhou","huang","jing|xing","xun","chao","chao","lie","gong",
+       "zuo","qiao","ju","gong","ge","wu","pu","pu","cha|chai|ci","qiu",
+       "qiu","ji","yi","si","ba","zhi","zhao","xiang|hang","yi","jin",
+       "xun","juan","pa","xun","jin","fu","za","bi","shi","bu",
+       "ding","shuai","fan","nie","shi","fen","pa","zhi","xi","hu",
+       "dan","wei","zhang","tang|nu","dai","mo|wa","pei","pa","tie","fu",
+       "lian","zhi","zhou","bo","zhi","di","mo","yi","yi","ping",
+       "qia","juan","ru","shuai","dai","zhen","shui","qiao","zhen","shi",
+       "qun","xi","bang","dai","gui","chou|dao","ping","zhang","jian|san","wan",
+       "dai","wei","chang","sha|qie","qi|ji","ze","guo","mao","zhu","hou",
+       "zhen","zheng","mi","wei","wo","fu","yi","bang","ping","die",
+       "gong","pan","huang","tao","mi","jia","teng","hui","zhong","shan|qiao|shen",
+       "man","mu","biao","guo","ze","mu","bang","zhang","jing","chan",
+       "fu","zhi","hu","fan","chuang|zhuang","bi","bi","zhang","mi","qiao",
+       "chan","fen","meng","bang","chou|dao","mie","chu","jie","xian","lan",
+       "gan","ping","nian","jian","bing","bing","xing","gan","yao","huan",
+       "you","you","ji","guang|an","pi","ting","ze","guang","zhuang","me|mo",
+       "qing","bi","qin","dun|tun","chuang","gui","ya","bai|ting","jie","xu",
+       "lu","wu","zhuang","ku","ying","di|de","pao","dian","ya","miao",
+       "geng","ci","fu","tong","pang","fei","xiang","yi","zhi","tiao",
+       "zhi","xiu","du|duo","zuo","xiao","tu","gui","ku","mang|meng|pang","ting",
+       "you","bu","bing|ping","cheng","lai","bei","ji|cuo","an","shu","kang",
+       "yong","tuo","song","shu","qing","yu","yu","miao","sou","ce",
+       "xiang","fei","jiu","e","gui|wei|hui","liu","sha|xia","lian","lang","sou",
+       "zhi","bu","qing","jiu","jiu","jin|qin","ao","kuo","lou","yin",
+       "liao","dai","lu","yi","chu","chan","tu","si","xin","miao",
+       "chang","wu","fei","guang","kao","kuai","bi","qiang|se","xie","lin",
+       "lin","liao","lu","ji","ying","xian","ting","yong","li","ting",
+       "yin","xun","yan","ting","di","po|pai","jian","hui","nai","hui",
+       "gong","nian","kai","bian","yi","qi","nong|long","fen","ju","yan",
+       "yi","zang","bi","yi","yi","er","san","shi","er","shi",
+       "shi","gong","diao","yin","hu","fu","hong","wu","tui","chi",
+       "jiang","ba","shen","di|ti|tui","zhang","jue|zhang","tao","fu","di","mi",
+       "xian","hu","chao","nu","jing","zhen","yi","mi","juan|quan","wan",
+       "shao","ruo","xuan|yuan","jing","diao","zhang","jiang","qiang|jiang","peng","dan|tan",
+       "qiang|jiang","bi","bi","she","dan|tan","jian","gou","ge","fa","bi",
+       "kou","jian","bie","xiao","dan|tan","guo","qiang|jiang","hong","mi","guo",
+       "wan","jue","xue","ji","gui","dang","lu","lu","tuan","hui",
+       "zhi","hui","hui","yi","yi","yi","yi","huo","huo","shan|xian",
+       "xing","wen","tong","yan","yan","yu","chi","cai","biao","diao",
+       "bin","peng|bang","yong","piao","zhang","ying","chi","chi","zhuo|bo","tuo|yi",
+       "ji","pang|fang","zhong","yi","wang","che","bi","di","ling","fo",
+       "wang","zheng","cu","wang","jing","dai","xi","xun","hen","yang",
+       "huai","lv","hou","wang|jia|wa","cheng|zheng","zhi","xu","jing","tu","cong",
+       "cong","lai","cong","de|dei","pai","xi","dong","ji","chang","zhi",
+       "cong|zong","zhou","lai","yu","xie","jie","jian","shi|ti","jia|xia","bian",
+       "huang","fu","xun","wei","pang","yao","wei","xi","zheng","piao",
+       "ti|chi","de","zhi|zheng","zhi|zheng","bie","de","zhong|chong","che","jiao|yao","hui",
+       "jiao","hui","mei","long","xiang","bao","qu|ju","xin","xin","bi",
+       "yi","le","ren","dao","ding|ting","gai","ji","ren","ren","chan",
+       "tan","te","te|tui","gan|han","yi|qi","shi|tai","cun","zhi","wang","mang",
+       "xi|lie","fan","ying","tian","min|wen","min|wen","zhong","chong","wu","ji",
+       "wu","xi","jia","you","wan","cong","song|zhong","kuai","yu|shu","bian",
+       "zhi","qi|shi","cui","chen","tai","tun|zhun|dun","qian|qin","nian","hun","xiong",
+       "niu","kuang|wang","xian","xin","kang|hang","hu","kai","fen","huai","tai",
+       "song","wu","ou","chang","chuang","ju","yi","bao","chao","min|men",
+       "pei","zuo|zha","zen","yang","kou|ju","ban","nu","nao|niu","zheng","pa",
+       "bu","tie|zhan","hu|gu","hu","cu|ju|zu","da","lian","si|sai","you|chou","di",
+       "dai","yi","tu|die","you","fu","ji","peng","xing","yuan","ni",
+       "guai","fei","xi","bi","you|yao","qie","xuan","cong","bing","huang",
+       "xu|xue","chu","bi|pi","shu","xi|shu","tan","yong","zong","dui","mi",
+       "gi","yi","shi","nen|nin","xun","shi","xi","lao","heng","kuang",
+       "mou","zhi","xie","lian","tiao|yao","huang","die","hao","kong","gui",
+       "heng","xi|qi|xu","xiao|jiao","shu","si","hu|kua","qiu","yang","hui","hui",
+       "chi","jia","yi","xiong","guai","lin","hui","zi","xu","chi",
+       "shang","nv","hen","en","ke","dong","tian","gong","quan|zhuan","xi",
+       "qia","yue","peng","ken","de","hui","e|wu","qiu","tong","yan",
+       "kai","ce","nao","yun","mang","yong","yong","yuan|juan","pi","kun",
+       "qiao","yue","yu|shu","tu","jie|ke","xi","zhe","lin","ti","han",
+       "hao|jiao","qie","ti","bu","yi","qian","hui","xi","bei","man|men",
+       "yi","heng","song","quan","cheng","kui|li","wu","wu","you","li",
+       "liang","huan","cong","yi|nian","yue","li","nin","nao","e","que",
+       "xuan","qian","wu","min","cong","fei","bei","de","cui","chang",
+       "men","li","ji","guan","guan","xing","dao","qi","kong","tian",
+       "lun","xi","kan","gun","ni","qing","chou","dun","guo","zhan",
+       "jing","wan","yuan|wan","jin","ji","lan|lin","yu|xu","huo","he","juan|quan",
+       "tan|dan","ti","ti","nian","wang","chuo|chui","hu","hun|men","xi","chang",
+       "xin","wei","hui","e|wu","suo|rui","zong","jian","yong","dian","ju",
+       "can","cheng","de","bei","qie","can","dan|da","guan","duo","nao",
+       "yun","xiang","zhui","die","huang","chun","qiong","re","xing","ce",
+       "bian","min","zong","ti|shi","qiao","chou","bei","xuan","wei","ge",
+       "qian","wei","yu","yu|tou","bi","xuan","huan","min","bi","yi",
+       "mian","yong","qi|kai","dang|shang|tang|yang","yin","e","chen|xin|dan","mao","ke|qia","ke",
+       "yu","ai","qie","yan","nuo","gan","yun","cong|song","sai|si","leng",
+       "fen","ying","kui","kui","que","gong|hong","yun","su","su|shuo","qi",
+       "yao","song","huang","ji","gu","ju","chuang","ni","xie","kai",
+       "zheng","yong","cao","xun","shen","bo","kai|xi","yuan","xi|xie","hun",
+       "yong","yang","li","cao|sao","tao","yin","ci","xu|chu","qian|qie","tai",
+       "huang","yun","shen","ming","gong|hong","she","cao|cong","piao","mu","mu",
+       "guo","chi","can","can","can","cui","min","te","zhang","tong",
+       "ao","shuang","man","guan","que","zao","jiu","hui","kai","lian",
+       "ou","song","qin|jin","yin","lv","shang","wei","tuan","man","qian",
+       "she","yong","qing","kang","di|chi","zhi|zhe","lou|lv","juan","qi","qi",
+       "yu","ping","liao","cong","you","chong","zhi","tong","cheng","qi",
+       "qu","peng","bei","bie","qiong","jiao","zeng","chi","lian","ping",
+       "kui","hui","qiao","cheng|deng|zheng","yin","yin","xi","xi","dan|da","tan",
+       "duo","dui","dui|dun|tun","su","jue","ce","xiao|jiao","fan","fen","lao",
+       "lao","chong","han","qi","xian","min","jing","liao","wu","can",
+       "jue","cu","xian","tan","sheng","pi","yi","chu","xian","nao|nang",
+       "dan","tan","jing","song","han","jiao|ji","wei","xuan|huan","dong","qin",
+       "qin","ju","cao|sao","ken","xie","ying","ao","mao","yi","lin",
+       "se","jun","huai","men","lan","ai","lin","yan","guo","xia",
+       "chi","yu","yin","dai","meng","ai|yi|ni","meng","dui","qi|ji","mo",
+       "lan|xian","men","chou","zhi","nuo","nuo","yan","yang","bo","zhi",
+       "kuang","kuang","you","fu","liu","mie","cheng","hui","chan","meng",
+       "lan","huai","xuan","rang","chan","ji","ju","huan","she","yi",
+       "lian","nan","mi","tang","jue","gang|zhuang","gang|zhuang","gang|zhuang","ge","yue",
+       "wu","jian","qu","shu","rong","xi|hu","cheng","wo","jie","ge",
+       "jian","qiang","huo","qiang","zhan","dong","qi","jia","die","zei",
+       "jia","ji","zhi","kan","ji","kui","gai","deng","zhan","qiang",
+       "ge","jian","jie","yu","jian","yan","lu","xi|hu","zhan","xi|hu",
+       "xi|hu","chuo","dai","qu","hu","hu","hu","e","shi","ti",
+       "mao","hu","li","fang","suo","bian|pian","dian","jiong","shang|jiong","yi",
+       "yi","shan","hu","fei","yan","shou","shou","cai","za|zha","qiu",
+       "le|li|cai","pu","ba|pa","da","reng","fan|fu","ru","zai","tuo","zhang",
+       "diao|di|yue|li","kang|gang","yu|wu","yu|wu|ku","han","shen","cha","tuo|chi|yi","gu|xi|ge|jie","kou",
+       "wu","den","qian","zhi","ren","kuo","men","sao","yang","niu",
+       "ban","che","rao","xi|cha|qi","qian|qin","ban","jia","yu","fu","ba|ao",
+       "xi|zhe","pi","di","zhi|sun|kan","e","den","zhao","cheng","ji","yan",
+       "kuang|wang|zai","bian","chao","ju","wen","hu|gu","yue","jue","ba","qin",
+       "dan|shen","zheng","yun","wan","ne|ni|rui|na","yi","shu","zhua","pou","tou",
+       "dou","kang","zhe|she","pou|fu","fu","pao","ba","ao|niu","ze|zhBi","tuan",
+       "kou","lun","qiang|cheng","yun","hu","bao","bing","zhi|zhai","peng","nan",
+       "bu|pu","pi","tai","yao|tao","zhen","zha","yang","bao","he|qia","ni",
+       "ye","di","chi","pi|pei","jia","mo|ma","mei","chen","ya","chou",
+       "qu","min","zhu","jia|ya","fu|bi","zha","zhu","dan","chai|ca","mu",
+       "nian","la","fu","pao","ban|pan","pai","lin","na","guai","qian",
+       "ju","tuo|ta|zhi","ba","tuo","tuo","ao|niu","ju|gou","zhuo","pan|pin|fan","zhao",
+       "bai","bai","di","ni","ju","kuo","long","jian","qia","yong",
+       "lan","ning","bo","ze|zhai","qian","hen","kuo|gua","shi","jie|jia","zheng",
+       "nin","gong","gong","quan","shuan","cun|zun","za|zan","kao","yi|chi|hai","xie",
+       "ce|se|chuo","hui","pin","zhuai|ye","shi|she","na","bai","chi","gua","zhi",
+       "kuo|guang","duo","duo","zhi","qie","an","nong","zhen","ge","jiao",
+       "kua|ku","dong","ru|na","tiao","lie","zha","lv","die|she","wa","jue",
+       "lie ri","ju","zhi","luan","ya","zhua|wo","ta","xie|jia","nao","dang",
+       "jiao","zheng","ji","hui","xian","yu","ai","tuo|shui","nuo","cuo",
+       "bo","geng","ti","zhen","cheng","suo|sB|shB","suo|sB|shB","keng|qian","mei","nong",
+       "ju","bang|peng","jian","yi","ting","shan","nuo","wan","xie|jia","cha",
+       "peng","jiao|ku","wu","jun","jiu","tong","kun","huo|chi","tu|shu|cha","zhuo",
+       "pou|fu","luo|lv","ba","han","shao","nie","juan","ze","shu|song|sou","ye|yu",
+       "jue|zhuo","bu","wan","bu|pu|zhi","zun","ye","zhai","lv","sou","tuo|shui",
+       "lao","sun","bang","jian","huan","dao","wei","wan|yu","qin","peng",
+       "she","lie","min","men","fu|bu","bai","ju","dao","wo|luo","ai",
+       "juan|quan","yue","zong","chen","chui","jie","tu","ben","na","nian|nie",
+       "ruo|wei|re","zuo","wo|xia","qi","xian","cheng","dian","sao","lun","qing|qian",
+       "gang","duo","shou","diao","pou","di","zhang","hun","ji","tao",
+       "qia","qi","pai","shu","qian|wan","ling","ye","ya","jue","zheng",
+       "liang","gua","ni|nie|yi","huo|xu","shan|yan","zheng|ding","lve","cai","tan","che",
+       "bing","jie","ti","kong","tui","yan","cuo","zou|zhou|chou","ju","tian",
+       "qian","ken","bai","pa","jie","lu","guai","ming","jie","zhi",
+       "dan|shan","meng","chan|xian|can|shan","sao","guan","peng","yuan","nuo","jian","zheng|keng",
+       "jiu|you","jian","yu","yan","kui","nan","hong","rou","pi|che","wei",
+       "sai|zong|cai","zou","xuan","miao","ti|di","nie","cha","shi","zong|song","zhen",
+       "yi","xun","huang|yong","bian","yang","huan","yan","zan|zuan","an","xu|ju",
+       "ya","wo","ke|qia","chuai|tuan|zhui","ji","ti|di","la","la","cheng","kai",
+       "jiu","jiu","tu","jie|qi","hui","gen","chong|dong","xiao","she|die|ye","xie",
+       "yuan","qian|jian","ye","cha","zha","bei","yao","wei","beng","lan",
+       "wen","qin","chan","ge","lou","zong","gen","jiao","gou","qin",
+       "rong","que","chou|zou","chuai","zhan","sun","sun","bo","chu","rong|nang",
+       "bang|peng","cuo","sao","e","yao","dao","zhi","nu|nuo|nou","la|xie|xian","jian",
+       "sou","qiu","gao","gan","shuo","sang","jin","mie","e","chui",
+       "nuo","shan","ta","jie|zhe","tang","pan|ban|po","ban","da","li","tao",
+       "hu|ku","zhi|nai","wa","hua","qian","wen","qiang|cheng","tian|shen","zhen","e",
+       "xie","na|nuo","quan","cha","zha","ge","wu","en","she","kang",
+       "she|nie","shu","bai","yao","bin","sou","tan","sa|sha|shai","chan|sun","suo",
+       "jiu|liu|liao|jiao|nao","chong","chuang","guai","bing","feng|peng","shuai","di|tu|zhi","qi|ji|cha","sou|song",
+       "zhai","lian","cheng","chi","guan","lu","luo","lou","zong","gai|xi",
+       "hu|chu","zha","qiang","tang","hua","cui","zhi|nai","mo|ma","jiang|qiang","gui",
+       "ying","zhi","ao|qiao","zhi","nie|che","man","chan|can","kou","chu","se|mi|su",
+       "tuan","jiao|chao","mo","mo","zhe","chan|xian|can|shan","keng|qian","biao","jiang","yao",
+       "gou","qian","liao","ji","ying","jue","pie","pie","lao","dun",
+       "xian","ruan","gui","zan|zen|qian","yi","xian","cheng","cheng","sa","nao",
+       "hong","si","han","heng|guang","da","zun","nian","lin","zheng|cheng","hui|wei",
+       "zhuang","jiao","ji","cao","dan","dan|shan","che","bo","che","jue",
+       "xiao|sou","liao","ben","fu","qiao","bo","cuo|zuo","zhuo","zhuan","wei|tuo",
+       "pu","qin","dun","nian","hua","xie","lu","jiao","cuan","ta",
+       "han","qiao|yao|ji","zhua|wo","jian","gan","yong","lei","nang","lu","shan",
+       "zhuo","ze|zhai","pu","chuo","ji","dang","se","cao","qing","qing|jing",
+       "huan","jie","qin","kuai","dan","xie","qia|jia|ye","pi|bo","bo|bai","ao",
+       "ju","ye","e","meng","sou","mi","ji","tai","zhuo","dao",
+       "xing","lan","ca","ju","ye","ru","ye","ye","ni","huo",
+       "jie","bin","ning","ge","zhi","zhi|jie","kuo","mo","jian","xie",
+       "lie|la","tan","bai","sou","lu","li|luo|yue","rao","ti|zhi|zhai","pan","yang",
+       "lei","ca|sa","shu","zan","nian","xian","jun|pei","huo","li|luo","la|lai",
+       "huan","ying","lu|luo","long","qian","qian","zan|cuan","qian","lan","xian|jian",
+       "ying","mei","rang","chan","weng","cuan","xie","she|nie","luo","jun",
+       "mi|mo","chi","zan|cuan","luan","tan","zuan","li|shai","dian","wa","dang",
+       "jiao","jue","lan","li|luo","nang","zhi","gui","gui","qi|yi|ji","xun",
+       "pu","pu","shou","kao","you","gai","yi","gong","gan|han","ban",
+       "fang","zheng","po","dian","kou","min","wu|mou","gu","he","ce",
+       "xiao","mi","chu|shou","ge|guo|e","di","xu","jiao","min","chen","jiu",
+       "shen","duo|dui","yu","chi","ao","bai","xu","jiao","duo|dui","lian",
+       "nie","bi","chang","dian","duo|que","yi","gan","san","ke","yan",
+       "dun|dui","qi|yi|ji","tou","xiao|xue","duo|que","jiao","jing","yang","xia","min",
+       "shu|shuo","ai|zhu","qiao","ai|zhu","zheng","di","chen","fu","shu|shuo","liao",
+       "qu","xiong|xuan","yi","jiao","shan","jiao","zhuo|zhu","yi|du","lian","bi",
+       "li|tai","xiao","xiao","wen","xue","qi","qi","zhai","bin","jue|jiao",
+       "zhai","lang","fei","ban","ban","lan","yu|zhong","lan","wei|men","dou",
+       "sheng","liao","jia","hu","xie","jia","yu","zhen","jiao","wo|guan",
+       "tou|tiao","dou","jin","chi","yin|zhi","fu","qiang","zhan","qu","zhuo",
+       "zhan","duan","zhuo","si","xin","zhuo","zhuo","qin","lin","zhuo",
+       "chu","duan","zhu","fang","chan|jie","hang","yu|wu","shi","pei","liu|you",
+       "mie","pang|bang","qi","zhan","mao","lv","pei","pi|bi","liu","fu",
+       "fang","xuan","jing","jing","ni","zu","zhao","yi","liu","shao",
+       "jian","en","yi","qi","zhi","fan","piao","fan","zhan","kuai",
+       "sui","yu","wu","ji","ji","ji","huo","ri","dan","jiu",
+       "zhi","zao","xie","tiao","xun","xu","ga","la","gan|han","han",
+       "tai|ying","di|de","xu","chan","shi","kuang","yang","shi","wang","min",
+       "min","tun|zhun","chun","wu","yun","bei","ang","ze","ban","jie",
+       "kun","sheng","hu","fang","hao","gui","chang","xuan","ming","hun",
+       "fen","qin","hu","yi","xi","xin","yan","ze","fang","tan",
+       "shen","ju","yang","zan","bing","xing","ying","xuan","po","zhen",
+       "ling","chun","hao","mei","zuo","mo","bian","xu","hun","zhao",
+       "zong","shi","shi","yu","fei","die|yi","mao","ni","chang","wen",
+       "dong","ai","bing","ang","zhou","long","xian","kuang","tiao","chao",
+       "shi","huang","huang","xuan","kui","xu|kua","jiao","jin","zhi","jin",
+       "shang","tong","hong","yan","gai","xiang","shai","xiao","ye","yun",
+       "hui","han","han","jun","wan","xian","kun","zhou","xi","sheng|cheng",
+       "sheng","bu","zhe","zhe","wu","wan","hui","hao","chen","wan",
+       "tian","zhuo","zui","zhou","pu","jing|ying","xi","shan","ni","xi",
+       "qing","qi|du","jing","gui","zheng","yi","zhi","an|yan","wan","lin",
+       "liang","cheng","wang","xiao","zan","fei","xuan","xuan","yi","xia",
+       "yun","hui","xu","min","kui","ye","ying","shu|du","wei","shu",
+       "qing","mao","nan","jian|lan","nuan","an","yang","chun","yao","suo",
+       "pu","ming","jiao","kai","hao","weng","chang","qi","hao","yan",
+       "li","ai","ji","ji","men","zan","xie","hao","mu","mu",
+       "cong","ni","zhang","hui","bao|pu","han","xuan","chuan","liao","xian",
+       "tan","jing","pie","lin","tun","xi","yi","ji","huang","dai",
+       "ye","ye","li","tan","tong","xiao","fei","shen","zhao","hao",
+       "yi","xiang","xing","shen","jiao","bao","jing","yan","ai","ye",
+       "ru","shu","meng","xun","yao","pu|bao","li","chen","kuang","die",
+       "liao","yan","huo","lu","xi","rong","long","nang","luo","luan",
+       "shai","tang","yan","zhu","yue","yue","qu","ye","geng","ye",
+       "hu","he","shu","cao","cao","sheng","man","zeng|ceng","zeng|ceng","ti",
+       "zui","can|qian|jian","xu","hui|kuai","yin","qie|he","fen","bi|pi","yue","you",
+       "ruan","peng","fen|ban","fu","ling","fei|ku","qu|xu|chun","ti","nv|ga","tiao",
+       "shuo","zhen","lang","lang","juan|zui","ming","huang|mang|wang","wang","tun","zhao|chao",
+       "ji","qi|ji","ying","zong","wang","tong|chuang","lang","lao","meng","long",
+       "mu","pin","wei","mo","ben","zha","shu|zhu","shu|zhu","teul","zhu|shu",
+       "ren","ba","piao|pu|po","duo","duo","dao|tiao|mu","li","qiu|gui","ji","jiu",
+       "bi","xiu","cheng","ci","sha","ru","za","quan","qian","yu|wu",
+       "gan","wu","cha","shan|sha","xun","fan","wu","zi","li","xing",
+       "cai","cun","ren|er","shao|biao","tuo|zhe","di|duo","zhang","mang","chi","yi",
+       "gu|gai","gong","du","yi|li|duo|tuo","qi","shu","gang","tiao","jie","mian",
+       "wan","lai","jiu","mang","yang","ma","miao","si|zhi|xi","yuan|wan","hang",
+       "fei|bei","bei","jie","dong","gao","yao","xian","chu","chun","pa",
+       "shu|dui","hua","xin","niu|chou","zhu","chou","song","ban","song","ji",
+       "wo|yue","jin","gou","ji","mao","pi","pi|mi","wang","ang","fang|bing",
+       "fen","yi","fu","nan","xi","hu|di","ya","dou","xin","zhen",
+       "yao","lin","rui","e","mei","zhao","guo","zhi|qi","cong|zong","yun",
+       "hua","sheng","shu","zao","di|duo","li","lu","jian","cheng","song|mB ti su",
+       "qiang","feng","zhan","xiao","xian|zhen","ku","ping","si|tai","xi","zhi",
+       "guai","xiao","jia","jia","ju|gou","bao|fu","mo","yi|xie","ye","ye",
+       "shi","nie","bi","tuo|duo","yi|duo|li","ling","bing","ni|chi","la","he",
+       "pan|ban","fan","zhong","dai","ci","yang|ying","fu","bai|bo","mou","gan",
+       "qi","ran","rou","mao","shao","song","zhe","xia","you","shen",
+       "gui|ju","tuo","zuo|zha","nan","ning","yong","di","zhi|die","zha|zu","cha|zha",
+       "dan","gu","bu|pu","jiu","ao","fu","jian","ba|fu|pei|bo|bie","duo|zuo|wu","ke",
+       "nai","zhu","bi|bie","liu","chai","zha","si","zhu","bei|pei","shi|fei",
+       "guai","cha|zha","yao","cheng","jiu","shi","zhi","liu","mei","li",
+       "rong","zha|shan|shi|ce","zao","biao","zhan","zhi","long","dong","lu","sa",
+       "li|yue","lan","yong","shu","xun","shuan","qi|qie","chen","qi|xi","li",
+       "yi","xiang","zhen","li","se","gua|tian","kan","ben|bing","ren","xiao|jiao",
+       "bai","ren","bing","zi","chou","yi|xie","ci","xu","zhu","jian|zun",
+       "zui","er","er","you|yu","fa","gong","kao","lao","zhan","lie",
+       "yin","yang","he|hu","gen","zhi|yi","shi","ge","zai","luan","fu",
+       "jie","heng|hang","gui","tao","guang","wei","kuang","ru","an","an",
+       "juan","yi|ti","zhuo","ku","zhi","qiong","tong","sang","sang","huan",
+       "jie|ju","jiu","xue","duo","chui","yu|mou","za|zan","kB sei","ying","jie",
+       "liu","zhan","ya","nao","zhen","dang","qi","qiao","hua","gui|hui",
+       "jiang","zhuang","xun","suo","sha","chen|zhen","bei","ting|ying","gua","jing",
+       "bo","ben|fan","fu","rui","tong","jue","xi","lang","liu","feng",
+       "qi","wen","jun","gan","su|yin","liang","qiu","ting","you","mei",
+       "bang","long","peng","zhuang","di","xuan|juan|xie","tu|cha","zao","ao|you","gu",
+       "bi","di","han","zi","zhi","ren|er","bei","geng","jian","huan",
+       "wan","nuo","jia","tiao","ji","xiao","lv","kuan","shao|sao","chen",
+       "fen","song","meng","wu","li","si|qi","dou","qin","ying","suo",
+       "ju","ti","xie","kun","zhuo","shu","chan|yan","fan","wei","jing",
+       "li","bin|bing","xia","fo","chou|tao|dao","zhi","lai","lian","jian","zhuo",
+       "ling","li","qi","bing","lun","cong|song","qian","mian","qi","qi",
+       "cai","gun|hun","chan","de|zhe","fei","pai|bei|pei","bang","bang|pou|bei","hun","zong",
+       "cheng","zao","ji","li|lie","peng","yu","yu","gu","jun","dong",
+       "tang","gang","wang","di|dai|ti","que","fan","cheng","zhan","qi","yuan",
+       "yan","yu","quan|juan","yi","sen","ren|shen","chui","leng|ling","qi","zhuo",
+       "fu|su","ke","lai","zou|sou","zou","zhao|zhuo","guan","fen","fen","chen",
+       "qing","ni","wan","guo","lu","hao","jie|qie","yi","chou|zhou|diao","ju",
+       "ju","cheng|sheng","zu|cui","liang","qiang|kong","zhi","zhui|chui","ya","ju","bei",
+       "jiao","zhuo","zi","bin","peng","ding","chu","chang","men","hua",
+       "jian","gui","xi","du","qian","dao","gui","dian","luo","zhi",
+       "quan|juan","mi eng","fu","geng","peng","shan","yi","tuo","sen","duo|chuan",
+       "ye","fu","wei|hui","wei","duan","jia","zong","jian|han","yi","zhen|shen",
+       "xi","yan|ya","yan","chuan","jian","chun","yu","he","zha|cha","wo",
+       "pian","bi","yao","guo|kua","xu","ruo","yang","la","yan","ben",
+       "hui","kui","jie","kui","si","feng","xie","tuo","ji|zhi","jian",
+       "mu","mao","chu","ku|hu","hu","lian","leng","ting","nan","yu",
+       "you","mei","song|cong","xuan|yuan","xuan","yang|ying","zhen","pian","die|ye","ji",
+       "jie","ye","chu","shun|dun","yu","cou|zou","wei","mei","di|shi","ji",
+       "jie","kai|jie","qiu","ying","rou","huang","lou","le|yue","quan","xiang",
+       "pin","shi","gai","tan","lan","wen|yun","yu","chen","lv","ju",
+       "shen","chu","bi|pi","xie","jia","yi","zhan|nian|zhen","fu|bo","nuo","mi",
+       "lang","rong","gu","jian|jin","ju","ta","yao","zhen","bang","sha|xie",
+       "yuan","zi","ming","su","jia","yao","jie","huang","gan","fei",
+       "zha","qian","ma","sun","yuan","xie","rong","shi","zhi","cui",
+       "wen","ting","liu","rong","tang","que","zhai","si","sheng","ta",
+       "ke","xi","gu","qi","gao","gao","sun","pan","tao","ge",
+       "chun","dian","nou","ji","shuo","gou","chui","qiang","cha","qian|lian|xian",
+       "huai","mei","xu","gang","gao","zhuo","tuo","qiao","yang","dian|zhen",
+       "jia","jian|kan","zui","dao","long","bin|bing","zhu","sang","xi|die","ji|gui",
+       "lian","hui","rong|yong","qian","guo","gai","gai","tuan|shuan|quan","hua","qi|se",
+       "sen","cui|zhi","peng","you|chao","hu","jiang","hu","huan","gui","nie",
+       "yi","gao","kang","gui","gui","cao","man|wan","jin","di","zhuang",
+       "le|yue","lang","chen","cong|zong","li|chi","xiu","qing","shang","fan","tong",
+       "guan","ze","su","lei","lu","liang","mi","lou","chao|jiao","su",
+       "ke","chu","cheng","biao","lu","jiu|liao","zhe","zha","shu","zhang",
+       "man","mo|mu","niao|mu","yang","tiao","peng","zhu","sha|xie","xi","quan",
+       "heng","jian","cong","ji","yan","qiang","xue","ying","er","xun",
+       "zhi","qiao","zui","cong","piao","shu","hua","gui","zhen","zun",
+       "yue","shan","xi","chun","dian","fa|fei","gan","mo","wu","qiao",
+       "rao|nao","lin","liu","qiao","xian","run","fan","zhan|jian","tuo","liao",
+       "yun","shun","tui|dun","cheng","tang|cheng","meng","ju","cheng","su|qiu","jue",
+       "jue","tan|dian","hui","ji","nuo","xiang","tuo","ning","rui","zhu",
+       "tong|chuang","zeng|ceng","fen|fei","qiong","ran|yan","heng","qian","gu","liu","lao",
+       "gao","chu","xi","sheng","zi","zan","ji","dou","jing","lu",
+       "xian","cu|chu","yuan","ta","shu|qiao","jiang","tan","lin","nong","yin",
+       "xi","hui","shan","zui","xuan","cheng","gan","ju","zui","yi",
+       "qin","pu","yan","lei","feng","hui","dang","ji","sui","bo",
+       "ping|bo","cheng","chu","zhua","gui|hui","ji","jie","jia","qing","zhai|shi|tu",
+       "jian","qiang","dao","yi","biao","song","she","lin","li","cha",
+       "meng","yin","chou|tao|dao","tai","mian","qi","tuan","bin|bing","huo","ji",
+       "qian|lian","ni|mi","ning","yi","gao","jian|kan","yin","nou|ruan|ru","qing","yan",
+       "qi","mi","zhao","gui","chun","ji","kui","po","deng","chu",
+       "ge","mian","you","zhi","huang|guo|gu","qian","lei","lei","sa","lu",
+       "li","cuan","lv|chu","mie|mei","hui","ou","lv","zhi","gao","du",
+       "yuan","li|yue","fei","zhuo|zhu","sou","lian","jiang","chu","qing","zhu",
+       "lu","yan","li","zhu","chen","jue|ji","e","su","huai|gui","nie",
+       "yu","long","la|lai","qiao","xian","gui","ju","xiao","ling","ying",
+       "jian","yin","you","ying","xiang","nong","bo","chan|zhan","lan","ju",
+       "shuang","she","wei|zui","cong","quan","qu","cang","jiu","yu","luo",
+       "li","cuan","luan","dang","qu","yan","lan","lan","zhu","lei",
+       "li","ba","nang","yu","ling","guan","qian","ci","huan","xin",
+       "yu","yu|yi","qian|xian","ou","xu","chao","chu|qu|xi","qi","ke|ai","yi|yin",
+       "jue","xi|kai","xu","he","yu","kuai","lang","kuan","shuo|sou","xi",
+       "ei|ai","qi","qi","xu|chua","chi|chuai","qin","kuan","kan|qian","kuan","kan|ke",
+       "chuan","sha","gua","yan|yin","xin","xie","yu","qian","xiao","ye",
+       "ge","wu","tan","jin|qun","ou","hu","ti","huan","xu","pen",
+       "xi","xiao","xu","xi|she","shan","lian|han","chu","yi","e","yu",
+       "chuo","huan","zhi","zheng","ci","bu","wu","qi","bu","bu",
+       "wai","ju","qian","zhi|chi","se","chi","se|sha","zhong","sui","sui",
+       "li","ze","yu","li","gui","dai","dai","si","jian","zhe",
+       "mo|wen","mo","yao","mo","cu","yang","tian","sheng","dai","shang",
+       "xu","xun","shu","can","jing","piao","qia","qiu","su","qing|jing",
+       "yun","lian","yi","fou|bo","zhi|shi","ye|yan","can","hun|mei","dan","ji",
+       "die","zhen","yun","wen","chou","bin","ti","jin","shang","yin",
+       "chi","jiu","kui|hui","cuan","yi","dan","du","jiang","lian","bin",
+       "du","jian","jian","shu","ou","duan","zhu","yin|yan","qing|keng|sheng","yi",
+       "sha","ke|qiao","ke|qiao","xiao|yao","xun","dian","hui","hui","gu","qiao",
+       "ji","yi","ou","hui","duan","yi","xiao","wu","guan|wan","mu",
+       "mei","mei","ai","jie","du|dai","yu","bi","bi","bi","pi",
+       "pi","bi","chan","mao","hao","cai","bi","lie","jia","zhan",
+       "sai","mu","tuo","xun","er","rong","xian","ju","mu","hao",
+       "qiu","dou|nuo","mushiruPPPV","tan","pei","ju","duo","cui","bi","san",
+       "san","mao","sai|sui","shu","shu","tuo","he","jian","ta","san",
+       "lv","mu","mao","tong","rong","chang","pu","lu","zhan","sao",
+       "zhan","meng","lu","qu","die","shi|zhi","di","min","jue","meng|mang",
+       "qi","pie","nai","qi","dao","xian","chuan","fen","yang|ri","nei",
+       "nei","fu","shen","dong","qing","qi","yin","xi","hai","yang",
+       "an","ya","ke","qing","ya","dong","dan","lv","qing","yang",
+       "yun","yun","shui","shui","zheng|cheng","bing","yong","dang","shui","le",
+       "ni","tun","fan","gui|jiu","ting","zhi","qiu","bin|pa","ze","mian",
+       "cuan","hui","diao","han","cha","zhuo|que","chuan","wan","fan","da",
+       "xi","tuo","mang","qiu","qi","shan","pin","han","qian","wu",
+       "wu","xun","si","ru","gong","jiang","chi","wu","tu","jiu",
+       "tang|shang","zhi|ji","zhi","qian","mi","gu|yu","wang","jing","jing","rui",
+       "jun","hong","tai","tai","ji","bian","bian","gan|han|cen","wen|men","zhong",
+       "fang|pang","xiong","jue","hu|huang","niu|you","qi","fen","xu","xu","qin",
+       "yi","wo","yun","yuan","hang","yan","shen|chen","chen","dan","you",
+       "dun","hu","huo","qi","mu","nv|niu","mei|mo","ta|da","mian","mi|wu",
+       "chong","hong|pang","bi","sha","zhi","pei","pan","zhui|zi","za","gou",
+       "pai","mei|mo","ze","feng","ou","li","lun","cang","feng","wei",
+       "hu","mo","mei","shu","ju","za","tuo|duo","tuo","tuo|duo","he",
+       "li","mi|li","yi|chi","fa","fei","you","tian","zhi","zhao","gu",
+       "zhan","yan","si","kuang","jiong","ju","xie|yi","qiu","yi|die","jia",
+       "zhong","quan","bo|po","hui","mi|bi","ben","ze","chu|she","le","you|ao",
+       "gu","hong","gan","fa","mao","si","hu","peng|ping","ci","fan",
+       "zhi","su","ning","cheng","ling","pao","bo","qi","si","ni",
+       "ju","yue|sa","zhu","sheng","lei","xuan","jue|xue","fu","pan","min",
+       "tai","yang","ji","yong","guan","beng","xue","long|shuang","lu","dan",
+       "luo|po","xie","po","ze|shi","jing","yin","pan","jie","yie","hui",
+       "hui","zai","cheng","yin","wei","hou","jian","yang","lie","si",
+       "ji","er","xing","fu","sa|xi","se|qi|zi","zhi","yin","wu","xi|xian",
+       "kao","zhu","jiang","luo","luo","an|yan|e","dong","ti","si","lei",
+       "yi","mi","quan","jin","po","wei","xiao","xie","hong","xu",
+       "su|shuo","kuang","tao","qie|jie","ju","er","zhou","ru","ping","xun",
+       "xiong","zhi","guang","huan","ming","huo","wa","qia","pai","wu",
+       "qu","liu","yi","jia","jing","qian|jian","jiang","jiao","zhen","shi",
+       "zhuo","ce","fa","kuai|hui","ji","liu","chan","hun","hu|xu","nong",
+       "xun","jin","lie","qiu","wei","zhe","jun|xun","han","bang","mang",
+       "zhuo","you|di","xi","bo","dou","huan","hong","yi","pu","ying|cheng",
+       "lan","hao","lang","han","li","geng","fu","wu","li","chun",
+       "feng|hong","yi","yu","tong","lao","hai","jin","jia","chong","jiong",
+       "mei","sui|nei","cheng","pei","xian","shen","tu","kun","ping","nie",
+       "han","jing","xiao","she","nian","tu","yong|chong","xiao","xian","ting",
+       "e","su","tun|yun","juan","cen","ti","li","shui","si","lei",
+       "shui","tao","du","lao","lai","lian","wei","wo|guo","yun","huan",
+       "di","heng","run","jian","zhang","se","fu","guan","xing","shou|tao",
+       "shuan","ya","chuo","zhang","ye","kong|nang","wan|wo|yuan","han","tuo","dong",
+       "he","wo","ju","she","liang","hun","ta","zhuo","dian","qie|ji",
+       "de","juan","zi","xi","xiao","qi","gu","guo|guan","yan","lin",
+       "tang|chang","zhou","peng","hao","chang","shu","qi","fang","zhi","lu",
+       "nao|chuo|zhuo","ju","tao","cong","lei","zhe","ping|peng","fei","song","tian",
+       "pi|pei","dan","yu|xu","ni","yu","lu","gan","mi","jing|cheng","ling",
+       "lun","yin","cui","qu","huai","yu","nian|shen","shen","biao|hu","chun|zhun",
+       "hu","yuan","lai","hun","qing","yan","qian","tian","miao","zhi",
+       "yin","bo","ben","yuan","wen|min","ruo|re|luo","fei","qing","yuan","ke",
+       "ji","she","yuan","se","lu","zi","du|dou","yi","jian","mian|sheng",
+       "pai","xi","yu","yuan","shen","shen","rou","huan","zhu","jian",
+       "nuan","yu","qiu|wu","ting","qu|ju","du","feng","zha","bo","wo",
+       "wo|guo","ti|di","wei","wen","ru","xie","ce","wei","he","gang|jiang",
+       "yan","hong","xuan","mi","ke","mao","ying","yan","you","hong|qing",
+       "miao","sheng","mei","zai","hun","nai","gui","chi","e","pai",
+       "mei","lian","qi","qi","mei","tian","cou","wei","can","tuan",
+       "mian","hui|min|xu","po","xu","ji","pen","jian","jian","hu","feng",
+       "xiang","yi","yin","zhan","shi","jie","zhen","huang","tan","yu",
+       "bi","min|hun","shi","tu","sheng","yong","ju","dong","tuan|nuan","qiu|jiao",
+       "qiu|jiao","qiu","yan|yin","tang|shang","long","huo","yuan","nan","ban|pan","you",
+       "quan","zhuang|hun","liang","chan","xian","chun","nie","zi","wan","shi",
+       "man","ying","la","kui|hui","feng|hong","jian","xu","lou","wei","gai",
+       "bo","ying","po","jin","yan|gui","tang","yuan","suo","yuan","lian|nian|xian",
+       "yao","meng","zhun","cheng","ke","tai","da|ta","wa","liu","gou",
+       "sao","ming","zha","shi","yi","lun","ma","pu","wei","li",
+       "zai","wu","xi","wen","qiang","ze","shi","su","ai","zhen|qin",
+       "sou","yun","xiu","yin","rong","hun","su","suo","ni|niao","ta",
+       "shi","ru","ai","pan","chu|xu","chu","pang","weng","cang","mie",
+       "ge","dian","hao|xue","huang","qi|xi|xie","zi","di","zhi","xing|ying","fu",
+       "jie","hua","ge","zi","tao","teng","sui","bi","jiao","hui",
+       "gun","yin","ze|hao","long","zhi","yan","she","man","ying","chun",
+       "lv","lan","luan","yao","bin","tan","yu","xiu","hu","bi",
+       "biao","zhi","jiang","kou","shen","shang","di","mi","ao","lu",
+       "hu|xu","hu","you","chan","fan","yong","gun","man","qing","yu",
+       "piao","ji","ya","chao","qi","xi","ji","lu","lou","long",
+       "jin","guo","cong|song","lou","zhi","gai","qiang","li","yan","cao",
+       "jiao","cong","chun","tuan|zhuan","ou","teng","ye","xi","mi","tang",
+       "mo","shang","han","lian","lan","wa","chi","gan","feng|peng","xuan",
+       "yi","man","zi","mang","kang","luo|ta","ben|peng","shu","zhang","zhang",
+       "chong|zhuang","xu","huan","huo|kuo","jian","yan","shuang","liao|liu","cui","ti",
+       "yang","jiang","cong|zong","ying","hong","xiu","shu","guan","ying","xiao",
+       "cong|zong","kun","xu","lian","zhi","wei","pi|pie","yu","jiao|qiao","po",
+       "dang|xiang","hui","jie","wu","pa","ji","pan","wei","su","qian",
+       "qian","xi|ya","lu","xi","xun","dun","huang|guang","min","run","su",
+       "lao|liao","zhen","cong|zong","yi","zhi","wan","tan|shan","tan","chao","xun",
+       "kui|hui","ye","shao","tu|zha","zhu","san|sa","hei","bi","shan","chan",
+       "chan","shu","tong","pu","lin","wei","se","se","cheng","jiong",
+       "cheng|deng","hua","jiao","lao","che","gan","cun","jing","si","shu|zhu",
+       "peng","han","yun","liu","hong|gong","fu","hao","he","xian","jian",
+       "shan","xi","ao","lu","lan","ning","yu","lin","mian|sheng","zao",
+       "dang","huan","ze|shi","xie","yu","li","shi","xue","ling","wan|man",
+       "zi","yong","kuai|hui","can","lian","dian","ye","ao","huan","zhen",
+       "chan","man","gan","dan|tan","yi","sui","pi","ju","ta","qin",
+       "ji","zhuo","lian","nong","guo|wo","jin","fen|pen","se","ji|sha","sui",
+       "hui|huo","chu","ta","song","ding|ting","se","zhu","lai","bin","lian",
+       "mi|ni","shi","shu","mi","ning","ying","ying","meng","jin","qi",
+       "bi|pi","ji","hao","ru","cui|zui","wo","tao","yin","yin","dui",
+       "ci","huo|hu","qing","lan","jun|xun","ai|kai|ke","pu","zhuo|zhao","wei","bin",
+       "gu","qian","ying","bin","kuo","fei","cang","me","jian","wei|dui",
+       "luo|po","zan|cuan","lv","li","you","yang","lu","si","zhi","ying",
+       "du|dou","wang","hui","xie","pan","shen","biao","chan","mie|mo","liu",
+       "jian","pu|bao","se","cheng|deng","gu","bin","huo","xian","lu","qin",
+       "han","ying","rong","li","jing","xiao","ying","sui","wei|dui","xie",
+       "huai|wai","xue","zhu","long|shuang","lai","dui","fan","hu","lai","shu",
+       "lian","ying","mi","ji","lian","jian|zun","ying","fen","lin","yi",
+       "jian","yue","chan","dai","rang|nang","jian","lan","fan","shuang","yuan",
+       "zhuo|jiao|ze","feng","she","lei","lan","cong","qu","yong","qian","fa",
+       "guan","jue","yan","hao","ying","sa","zan|cuan","luan","yan","li",
+       "mi","shan","tan","dang|tang","jiao","chan","ying","hao","ba","zhu",
+       "lan","lan","nang","wan","luan","xun|quan","xian","yan","gan","yan",
+       "yu","huo","huo|biao","mie","guang","deng","hui","xiao","xiao","hui",
+       "hong","ling","zao","zhuan","jiu","zha|yu","xie","chi","zhuo","zai",
+       "zai","can","yang","qi","zhong","fen|ben","niu","jiong|gui","wen","pu",
+       "yi","lu","chui","pi","kai","pan","yan","yan","pang|feng","mu",
+       "chao","liao","que","kang","dun","guang","xin","zhi","guang","guang",
+       "wei","qiang","bian","da","xia","zheng","zhu","ke","zhao","fu",
+       "ba","xie","xie","ling","zhuo|chu","xuan","ju","tan","pao|bao","jiong",
+       "pao|fou","tai","tai","bing","yang","tong","shan|qian","zhu","zha","dian",
+       "wei","shi","lian","chi","huang","zhou","hu","shuo","lan","ting",
+       "jiao|yao","xu","heng","quan","lie","huan","yang","xiao","xiu","xian",
+       "yin","wu","zhou","yao","shi","wei","tong|dong","mie","zai","kai",
+       "hong","lao|luo","xia","zhu","xuan","zheng","po","yan","hui","guang",
+       "che","hui","kao","chen","fan","shao","ye","hui","uu","tang",
+       "jin","re","lie","xi","fu|pao","jiong","xie|che","pu","ting","zhuo",
+       "ting","wan","hai","peng","lang","yan","xu","feng","chi","rong",
+       "hu","xi","shu","he","xun|hun","ku","juan|ye","xiao","xi","yan",
+       "han","zhuang","qu|jun","di","xie|che","ji|qi","wu","yan","lv","han",
+       "yan","huan","men","ju","dao","bei","fen","lin","kun","hun",
+       "tun","xi","cui","wu","hong","chao|ju","fu","wo|ai","jiao","zong|cong",
+       "feng","ping","qiong","ruo","xi|yi","qiong","xin","zhuo|chao","yan","yan",
+       "yi","jue","yu","gang","ran","pi","xiong|ying","gang","sheng","chang",
+       "shao","xiong|ying","nem","geng","qu","chen","he","kui","zhong","duan",
+       "xia","hui|yun|xun","feng","lian","xuan","xing","huang","jiao","jian","bi",
+       "ying","zhu","wei","tuan","shan|qian","xi|yi","nuan","nuan","chan","yan",
+       "jiong","jiong","yu","mei","sha","wei","ye|zha","jin","qiong","rou",
+       "mei","huan","xu","zhao","wei","fan","qiu","sui","yang","lie",
+       "zhu","jie","zao","gua","bao","hu","yun","nan","shi","huo",
+       "bian","gou","tui","tang","chao","shan","en|yun","bo","huang","xie",
+       "xi","wu","xi","yun","he","he|xiao","xi","yun","xiong","xiong",
+       "shan","qiong","yao","xun","mi","lian","ying","wu","rong","gong",
+       "yan","qiang","liu","xi","bi","biao","cong|zong","lu|ao","jian","shu",
+       "yi","lou","peng|feng","sui|cui","yi","teng","jue","zong","yun|yu","hu",
+       "yi","zhi","ao","wei","liu","han|ran","ou","re","jiong","man",
+       "kun","shang","cuan","zeng","jian","xi","xi","xi","yi","xiao",
+       "chi","huang","chan|dan","ye","tan","ran","yan","xun","qiao","jun",
+       "deng","dun","shen","jiao|qiao|jue|zhuo","fen","si","liao","yu","lin","tong|dong",
+       "shao","fen","fan","yan","xun","lan","mei","tang","yi","jiong",
+       "men","zhu","jiao","ying","yu","yi","xue","lan","tai|lie","zao",
+       "can","sui","xi","que","zong","lian","hui","zhu","xie","ling",
+       "wei","yi","xie","zhao","hui","da","nong","lan","xu","xian",
+       "he","xun","jin","chou","tao","yao","he","lan","biao","rong|ying",
+       "li|lie","mo","bao","ruo","lv","la|lie","ao","xun","kuang|huang","shuo",
+       "liao","li","lu","jue","liao","yan|xun","xi","xie","long","ye",
+       "can","rang","yue","lan","cong","jue","chong","guan","qu","che",
+       "mi","tang","lan","zhu","lan","ling","cuan","yu","zhao|zhua","zhao|zhua",
+       "pa","zheng","pao","cheng|chen","yuan","ai","wei","han","jue","jue",
+       "fu","ye","ba","die","ye","yao","zu","shuang","er","pan",
+       "chuang","ke","zang","die","qiang","yong","qiang","pian","ban","pan",
+       "chao","jian","pai","du","chuang","yu","zha","bian|mian","die","bang",
+       "bo","chuang","you","you|yong","du","ya","cheng","niu","niu","pin",
+       "jiu|le","mou|mu","ta","mu","lao","ren","mang","fang","mao","mu",
+       "gang","wu","yan","ge|qiu","bei","si","jian","gu","you|chou","ke",
+       "sheng","mu","di","qian","quan","quan","zi","te","xi","mang",
+       "keng","qian","wu","gu","xi","li","li","pou","ji","gang",
+       "zhi|te","ben","quan","chun","du","ju","jia","jian|qian","feng","pian",
+       "ke","ju","kao","chu","xi","bei","luo","jie","ma","san",
+       "wei","mao|li","dun","tong","qiao","jiang","xi","li","du","lie",
+       "bai","piao","bao","xi","chou","wei","kui","chou","quan","quan",
+       "quan|ba","fan","qiu","ji","chai","zhuo|bao","han|an","ge","zhuang","guang",
+       "ma","you","kang|gang","pei|fei","hou","ya","yin","huan|fan","zhuang","yun",
+       "kuang","niu","di","kuang","zhong","mu","bei","pi","ju","yi|quan|chi",
+       "sheng|xing","pao","xia","tuo|yi","hu","ling","fei","pi","ni","yao",
+       "you","gou","xue","ju","dan","bo","ku","xian","ning","huan",
+       "hen","jiao","he","zhao","jie","xun","shan","ta|shi","rong","shou",
+       "tong|dong","lao","du","xia","shi","kuai","zheng","yu","sun","yu",
+       "bi","mang|dou","xi|shi","juan","li","xia","yin","suan","lang","bei",
+       "zhi","yan","sha","li","han","xian","jing","pai","fei","xiao",
+       "bai|pi","qi","ni","biao","yin","lai","lie","jian|yan","qiang","kun",
+       "yan","guo","zong","mi","chang","yi","zhi","zheng","ya|wei","meng",
+       "cai","cu","she","lie","ceon","luo","hu","zong","gui","wei",
+       "feng","wo","yuan","xing","zhu","mao","wei","chuan","xian","tuan",
+       "ya|jia|qie","nao","xie|he|ge|hai","jia","hou","bian|pian","you","you","mei","cha",
+       "yao","sun","bo|po","ming","hua","yuan","sou","ma","huan","dai",
+       "yu","shi","hao","qiang","yi","zhen","cang","hao|gao","man","jing",
+       "jiang","mo","zhang","chan","ao","ao","hao","suo","fen","jue",
+       "bi","bi","huang","pu","lin","xu","tong","yao|xiao","lao","shuo|xi",
+       "xiao","shou","dun","jiao","ge|lie|xie","juan","du","hui","kuai","xian",
+       "xie","ta","xian","xun","ning","bian|pian","huo","nou|ru","meng","lie",
+       "nao|you","guang","shou","lu","ta","xian","mi","rang","huan","nao|you",
+       "luo","xian","qi","jue","xuan","miao","zi","shuai|lv","lu","yu",
+       "su","wang","qiu","ga","ding","le","ba","ji","hong","di",
+       "chuan","gan","jiu","yu","qi","yu","chang|yang","ma","hong","wu",
+       "fu","min|wen","jie","ya","bin|fen","bian","bang","yue","jue","men|yun",
+       "jue","wan","jian|qian","mei","dan","pin","wei","huan","xian","qiang|cang",
+       "ling","dai","yi","an|gan","ping","dian","fu","xuan|xian","xi","bo",
+       "ci","gou","jia","shao","po","ci","ke","ran","sheng","shen",
+       "yi|tai","zu|ju","jia","min","shan","liu","bi","zhen","zhen","jue",
+       "fa","long","jin","jiao","jian","li","guang","xian","zhou","gong",
+       "yan","xiu","yang","xu","luo","su","zhu","qin","yin|ken","xun",
+       "bao","er","xiang","yao","xia","hang","gui","chong","xu","ban",
+       "pei","lao","dang","ying","hun|hui","wen","e","cheng","di|ti","wu",
+       "wu","cheng","jun","mei","bei","ting","xian","chu","han","xuan|qiong",
+       "yan","qiu","xuan","lang","li","xiu","fu","liu","ya","xi",
+       "ling","li","jin","lian","suo","suo","feng","wan","dian","pin|bing",
+       "zhan","cui|se","min","yu","ju","chen","lai","min","sheng","wei|yu",
+       "tian","shu","zhuo|zuo","beng|pei","cheng","hu","qi","e","kun","chang",
+       "qi","beng","wan","lu","cong","guan","yan","diao","bei","lin",
+       "qin","pi","pa","que","zhuo","qin","fa","jin","qiong","du",
+       "jie","hun|hui","yu","mao","mei","chun","xuan","ti","xing","dai",
+       "rou","min","jian","wei","ruan","huan","xie|jie","chuan","jian","zhuan",
+       "chang|yang","lian","quan","xia","duan","yuan","ye","nao","hu","ying",
+       "yu","huang","rui","se","liu","shi","rong","suo","yao","wen",
+       "wu","zhen","jin","ying","ma","tao","liu","tang","li","lang",
+       "gui","tian|zhen","qiang|cang","cuo","jue","zhao","yao","ai","bin|pian","tu|shu",
+       "chang","kun","zhuan","cong","jin","yi","cui","cong","qi","li",
+       "jing","zao|suo","qiu","xuan","ao","lian","men","zhang","yin","ye",
+       "ying","zhi","lu","wu","deng","xiu","zeng","xun","qu","dang",
+       "lin","liao","qiong|jue","su","huang","gui","pu","jing","fan","jin",
+       "liu","ji","hui","jing","ai","bi","can","qu","zao","dang",
+       "jiao","guan","tan","hui|kuai","huan","se","sui","tian","chu","yu",
+       "jin","lu|fu","bin|pian","shu","wen","zui","lan","xi","ji|zi","xuan",
+       "ruan","wo","gai","lei","du","li","zhi","rou","li","zan",
+       "qiong","ti","gui","sui","la","long","lu","li","zan","lan",
+       "ying","mi|xi","xiang","qiong|wei","guan","dao","zan","huan|ye|ya","gua","bo",
+       "die","bo|pao","hu","zhi|hu","piao","ban","rang","li","wa","shiwa",
+       "xiang|hong","qianwa","ban","pen","fang","dan","weng","ou","fenwa","maowa",
+       "ki ro ton|mao wa","hu","ling","yi","ping","ci","bai","juan","chang","chi",
+       "liwa","dang","wa","bu","zhui","ping","bian","zhou","zhen","liwa",
+       "ci","ying","qi","xian","lou","di","ou","meng","zhuan","beng",
+       "lin","zeng","wu","pi","dan","weng","ying","yan","gan","dai",
+       "shen","tian","tian","han","chang","sheng","qing","shen","chan","chan",
+       "rui","sheng","su","shen","yong","shuai","lu","fu","yong","beng",
+       "beng","ning","tian","you","jia","shen","you","dian","fu","nan",
+       "dian|tian|sheng","ping","ting|ding","hua","ting|ding","zhen","zai|zi","meng","bi","bi|qi",
+       "mu","xun","liu","chang","mu","yun","fan","fu","geng","tian",
+       "jie","jie","quan","wei","fu|bi","tian","mu","tap","pan","jiang",
+       "wa","da|fu","nan","liu","ben","zhen","xu|chu","mu","mu","ce|ji",
+       "zai|zi","gai","bi","da","zhi|chou|shi","lve","qi","lve","fan|pan","yi",
+       "fan|pan","hua","she|yu","she","mu","jun","yi","liu","she","die",
+       "chou","hua","dang","zhui","ji","wan","jiang","cheng","chang","tuan",
+       "lei","ji","cha","liu","die","tuan","lin","jiang","jiang|qiang","chou",
+       "pi","die","die","pi|ya|shu","jie|qie","dan","shu","shu","zhi|di","yi|ni",
+       "ne","nai","ding","bi","jie","liao","gang","ge|yi","jiu","zhou",
+       "xia","shan","xu","n<e|yao","li|lai","yang","chen","you","ba","jie",
+       "jue|xue","qi","ya|xia","cui","bi","yi","li","zong","chuang","feng",
+       "zhu","pao","pi","gan","ke","ci","xue","zhi","da","zhen",
+       "fa|bian","zhi","teng","ju","ji","fei","gou","shan|dian","jia","xuan",
+       "zha","bing","nie","zheng","yong","jing","quan","teng|chong","tong","yi",
+       "jie","wei|you|yu","hui","tan|shi","yang","zhi","zhi","hen","ya","mei",
+       "dou","jing","xiao","tong","tu","mang","pi","xiao","suan","pu",
+       "li","zhi","cuo","duo","wu","sha","lao","shou","huan","xian",
+       "yi","beng|peng","zhang","guan","tan","fei","ma","ma|lin","chi","ji",
+       "tian|dian","an|ye|e","chi","bi","bi","min","gu","dui","ke|e","wei",
+       "yu","cui","ya","zhu","cu","dan","shen","zhong","zhi|chi","yu",
+       "hou","feng","la","yang","chen","tu","yu","guo","wen","huan",
+       "ku","jia|xia","yin","yi","lou","sao","jue","chi","xi","guan",
+       "yi","wen","ji","chuang","ban","hui|lei","liu","chai|cuo","shou","n<e|yao",
+       "dian|chen","da|dB","bie","tan","zhang","biao","shen","cu","luo","yi",
+       "zong","chou","zhang","zhai","sou","se","que","diao","lou","lou",
+       "mo","qin","yin","ying","huang","fu","liao","long","qiao|jiao","liu",
+       "lao","xian","fei","dan","yin","he","ai","ban","xian","guan",
+       "gui|wei","nong","yu","wei","yi","yong","pi","lei","li|lai","shu",
+       "dan","lin","dian","lin","la","bie","ji","chi","yang","xuan",
+       "jie","zheng","mo","li","huo","la","ji","dian","xuan","ying",
+       "yin","qu","yong","tan","dian","luo","luan","luan","bo","uu",
+       "gui","ba","fa","deng","fa","bai","bai","qie","ji|bi","zao",
+       "zao","mao","di|de","pa|ba","jie","huang","gui","ci","ling","gao|yao",
+       "mo","ji","jiao","peng","gao|yao","ai","e","hao","han","bi",
+       "wan","chou","qian","xi","ai","xiao","hao","huang","hao","ze",
+       "cui","hao","xiao","ye","po","hao","jiao","ai","xing","huang",
+       "li|luo|bo","piao","he","jiao","pi","gan","pao","zhou","jun","qiu",
+       "cun","que","zha","gu","jun","jun","zhou","zha|cu","gu","zhao|zhan|dan",
+       "du","min","qi","ying","yu","bei","diao","zhong","pen","he",
+       "ying","he","yi","bo","wan","he","ang","zhan","yan","jian",
+       "he","yu","kui","fan","gai|ge|he","dao","pan","fu","qiu","sheng|cheng",
+       "dao","lu","zhan","meng","li","jin","xu","jian","pan","guan",
+       "an","lu","xu","zhou|chou","dang","an","gu","li","mu","ding",
+       "gan","xu","mang","mang|wang","zhi","qi","yuan","xian|tian","xiang","dun",
+       "xin","xi|pan","pan","feng","dun","min","ming","sheng|xing","shi","yun|hun",
+       "mian","pan","fang","miao","dan","mei","mao","kan","xian","kou",
+       "shi","yang|ying","zheng","yao|ao","shen","huo","da","zhen","kuang","ju|xu|kou",
+       "shen","yi|chi","sheng","mei","mo|mie","zhu","zhen","zhen","mian","shi",
+       "yuan","die|ti","ni","zi","zi","chao","zha","xuan","bing|fang","pang|pan",
+       "long","gui|sui","tong","mi","die|zhi","di","ne","ming","xuan|shun|xun","chi",
+       "kuang","juan","mou","zhen","tiao","yang","yan","mo","zhong","mo",
+       "zhuo|zhao|zhe","zheng","mei","suo","qiao|shao|xiao","han","huan","di","cheng","cuo|zhuai",
+       "juan","e","mian","xian","xi","kun","lai","jian","shan","tian",
+       "gun","wan","leng","shi","qiong","li","ya","jing","zheng","li",
+       "lai","sui|zui","juan","shui","sui","du","bi","bi","mu","hun",
+       "ni","lu","yi|ze|gao","jie","cai","zhou","yu","hun","ma","xia",
+       "xing","hui","hun","zai","chun","jian","mei","du","hou","xuan",
+       "ti","kui","gao","rui","mao","xu","fa","wo","miao","chou",
+       "gui|wei|kui","mi","weng","kou|ji","dang","chen","ke","sou","xia","qiong|huan",
+       "mo","ming","man|men","fen","ze","zhang","yi","diao|dou","kou","mo",
+       "shun","cong","lou|lv","chi","man|men","piao","cheng","gui","meng","wan",
+       "run|shun","pie","xi","qiao","pu","zhu","deng","shen","shun","liao",
+       "che","xian|jian","kan","ye","xue","tong","wu|mi","lin","gui|kui","jian",
+       "ye","ai","hui","zhan","jian","gu","zhao","qu|ju","wei","chou",
+       "sao","ning|cheng","xun","yao","huo|yue","meng","mian","pin","mian","lei",
+       "kuang|guo","jue","xuan","mian","huo","lu","meng","long","guan|quan","man",
+       "xi","chu","tang","kan","zhu","mao","jin|qin|guan","jin|qin|guan","yu|xu|jue","shuo",
+       "ze","jue","shi","yi","shen","zhi","hou","shen","ying","ju",
+       "zhou","jiao","cuo","duan","ai","jiao","zeng","yue","ba","shi|dan",
+       "ding","qi","ji","zi","gan","wu","zhe","ku","gang|qiang|kong","xi",
+       "fan","kuang","dang","ma","sha","dan","jue","li","fu","min",
+       "e","xu|hua","kang","zhi","qi|qie","kan","jie","pin|bin|fen","e","ya",
+       "pi","zhe","yan","sui","zhuan","che","dun","wa","yan","jin",
+       "feng","fa","mo","zha","ju","yu","ke|luo","tuo","tuo","di",
+       "zhai","zhen","e","fu|fei","mu","zhu","li|la","bian","nu","ping",
+       "peng","ling","pao","le","po","bo","po","shen","za","ai",
+       "li","long","tong","yong","li","kuang","chu","keng","quan","zhu",
+       "kuang|guang","gui","e","nao","qia","lu","wei|gui","ai","luo|ge","ken|xian|gun|yin",
+       "xing","yan","dong","peng|ping","xi","lao","hong","shuo|shi","xia","qiao",
+       "qing","wei|ai|gai","qiao","ce","keng","xiao","que|ke|ku","chan","lang","hong",
+       "yu","xiao","xia","mang|bang","luo|long","yong|tong","che","che","wo","liu",
+       "ying","mang","que","yan","sha","kun","yu","ze","hua","lu",
+       "chen","jian","nve","song","zhuo","keng","peng","yan","zhui|chui|duo","kong",
+       "cheng","qi","zong|cong","qing","lin","jun","bo","ding","min","diao",
+       "jian|zhan","he","lu|liu","ai","sui","que|xi","leng","bei","yin","dui",
+       "wu","qi","lun","wan","dian","nao|gang","bei","qi","chen","ruan",
+       "yan","die","ding","zhou","tuo","jie|ya","ying","bian","ke","bi",
+       "wei","shuo|shi","zhen","duan","xia","dang","ti|di","nao","peng","jian",
+       "di","tan","cha","tian","qi","dun","feng","xuan","que","que|qiao",
+       "ma","gong","nian","su|xie","e","ci","liu","si|ti","tang","bang|pang",
+       "hua|ke|gu","pi","kui|wei","sang","lei","cuo","tian","xia|qia|ya","xi","lian|qian",
+       "pan","wei|ai|gai","yun","dui","zhe","ke","la","zhuan","yao","gun",
+       "zhuan","chan","qi","ao|qiao","peng","liu","lu","kan","chuang","chen",
+       "yin","lei","biao","qi","mo","qi|zhu","cui","zong","qing","chuo",
+       "lun","ji","shan","lao|luo","qu","zeng","deng","jian","xi","lin",
+       "ding","dian","huang","pan|bo","ji|she","qiao","di","li","jian","jiao",
+       "xi","zhang","qiao","dun","jian","yu","zhui","he|qiao","ke|huo","ze",
+       "lei","jie","chu","ye","que|hu","dang","yi","jiang","pi","pi",
+       "yu","pin","e|qi","ai","ke","jian","yu","ruan","meng","pao",
+       "ci","bo","yang","mie","ca","xian|xin","kuang","lei","lei","zhi",
+       "li","li","fan","que","pao","ying","li","long","long","mo",
+       "bo","shuang","guan","jian","ca","yan","shi","shi","li","reng",
+       "she","yue","si","qi","ta","ma","xie","yao","xian","zhi|qi",
+       "qi","zhi","beng|fang","dui","zhong","ren","yi","shi","you","zhi",
+       "tiao","fu","fu","mi|bi","zu","zhi","suan","mei","zuo","qu",
+       "hu","zhu","shen","sui","ci","chai","mi","lv","yu","xiang",
+       "wu","tiao","piao","zhu","gui","xia","zhi","ji|zhai","gao","zhen",
+       "gao","shui|lei","jin","shen","gai","kun","di","dao","huo","tao",
+       "qi","gu","guan","zui","ling","lu","bing","jin","dao","zhi",
+       "lu","chan|shan","bi|pi","chu","hui","you|chao","xi","yin","zi","huo",
+       "zhen","fu","yuan","xu","xian","shang|yang","ti|zhi","yi","mei","si",
+       "di","bei","zhuo","zhen","ying","ji","gao","tang","si","ma",
+       "ta","fu","xuan","qi","yu","xi","ji","si","shan|chan","dan",
+       "gui","sui","li","nong","mi","dao","li","rang","yue","ti",
+       "zan","lei","rou","yu","yu|ou","li","xie","qin","he","tu",
+       "xiu","si","ren","tu","zi","cha|na","gan","yi|zhi","xian","bing",
+       "nian","qiu","qiu","zhong","fen","hao|mao","yun","ke","miao","zhi",
+       "jing","bi","zhi","yu","mi|bi","ku","ban","pi","ni","li",
+       "you","zu","pi","bo","ling","mo","cheng","nian","qin","yang",
+       "zuo","zhi","di","shu","ju","zi","huo|kuo","ji","cheng|chen","tong",
+       "shi|zhi","huo|kuo","huo","yin","zi","zhi","jie","ren","du","yi",
+       "zhu","hui","nong","fu|pu","xi","gao","lang","fu","xun|ze","shui",
+       "lv","kun","gan","jing","ti","cheng","tu|shu","shao","shui","ya",
+       "lun","lu","gu","zuo","ren","zhun","bang","bai","ji|qi","zhi",
+       "zhi","kun","leng|ling","peng","ke","bing","chou","zui|zu|su","yu","su",
+       "lve","uu","yi","xi|qie","bian","ji","fu","pi|bi","nuo","jie",
+       "zhong","zong","xu","cheng|chen","dao","wen","xian|jian|lian","zi|jiu","yu","ji",
+       "xu","zhen","zhi","dao","jia","ji|qi","gao","gao","gu","rong",
+       "sui","rong","ji","kang","mu","can|shan|cen","men|mei","zhi","ji","lu",
+       "su","ji","ying","wen","qiu","se","kweok","yi","huang","qie",
+       "ji","sui","xiao|rao","pu","jiao","zhuo|bo","tong|zhong","zuo","lu","sui",
+       "nong","se","hui","rang","nuo","yu","pin","ji","tui","wen",
+       "cheng|chen","huo","kuang","lv","biao|pao","se","rang","zhuo|jue","li","cuan|zan",
+       "xue","wa","jiu","qiong","xi","qiong","kong","yu","shen","jing",
+       "yao","chuan","zhun","tu","lao","qie","zhai","yao","bian","bao",
+       "yao","bing","wa","zhu|ku","jiao|liao|liu","qiao","diao","wu","wa|gui","yao",
+       "zhi","chuang","yao","tiao|yao","jiao","chuang","jiong","xiao","cheng","kou",
+       "cuan","wo","dan","ku","ke","zhuo","huo","su","guan","kui",
+       "dou","zhuo","yin|xun","wo","wa","ya|ye","yu","ju","qiong","yao",
+       "yao","tiao","chao","yu","tian|dian|yan","diao","ju","liao","xi","wu",
+       "kui","chuang","chao|ke","kuan|cuan","kuan|cuan","long","cheng","cui","liao","zao",
+       "cuan","qiao","qiong","dou","zao","long","qie","li","chu","shi",
+       "fu","qian","chu|qi","hong","qi","hao","sheng","fen","shu","miao",
+       "qu|kou","zhan","zhu","ling","long","bing","jing","jing","zhang","bai",
+       "si","jun","hong","tong","song","jing|zhen","diao","yi","shu","jing",
+       "qu","jie","ping","duan","li","zhuan","ceng|zeng","deng","cun","wai",
+       "jing","kan","jing","zhu","zhu|du","le|jin","peng","yu","chi","gan",
+       "mang","zhu","wan","du","ji","jiao","ba","suan","ji","qin",
+       "zhao","sun","ya","zhui|rui","yuan","hu","hang","xiao","cen|jin|han","pi|bi",
+       "bi","jian","yi","dong","shan","sheng","da|xia|na","di","zhu","na",
+       "chi","gu","li","qie","min","bao","tiao","si","fu","ce",
+       "ben","fa","da","zi","di","ling","zuo|ze","nu","fu|fei","gou",
+       "fan","jia","ge","fan","shi","mao","po","ti","jian","qiong",
+       "long","min","bian","luo","gui","qu","chi","yin","yao","xian",
+       "bi","qiong","kuo","deng","jiao","jin","quan","sun","ru","fa",
+       "kuang","zhu","tong","ji","da","hang","ce","zhong","kou","lai",
+       "bi","shai","dang","zheng","ce","fu","yun|jun","tu","pa","li",
+       "lang","ju","guan","jian","han","tong","xia","zhi","cheng","suan",
+       "shi","zhu","zuo","xiao","shao","ting","ce","yan","gao","kuai",
+       "gan","chou","kuang","gang","yun","o","qian","xiao","jian","pou|bu|fu|pu",
+       "lai","zou","pai|bei","bi","bi","ge","tai|chi","guai|dai","yu","jian",
+       "zhao|dao","gu","chi","zheng","qing|jing","sha","zhou","lu","bo","ji",
+       "lin","suan","jun|qun","fu","zha","gu","kong","qian","quan","jun",
+       "chui","guan","wan|yuan","ce","zu","po","ze","qie","tuo","luo",
+       "dan","xiao","ruo","jian","xuan","bian","sun","xiang","xian","ping",
+       "zhen","xing","hu","shi|yi","zhu","yue|yao|chuo","chun","lv","wu","dong",
+       "shuo|xiao|qiao","ji","jie","huang","xing","mei","fan","chuan","zhuan","pian",
+       "feng","zhu","hong","qie","hou","qiu","miao","qian","gu","kui",
+       "yi","lou","yun","he","tang","yue","chou","gao","fei","ruo",
+       "zheng","gou","nie","qian","xiao","cuan","gong|gan|long","peng|pang","du","li",
+       "bi","zhuo|huo","chu","shai","chi","zhu","qiang|cang","long","lan","jian",
+       "bu","li","hui","bi","zhu|di","cong","yan","peng","cen|zan|can","zhuan|zuan|suan",
+       "pi","piao|biao","dou","yu","mie","tuan|zhuan","ze","shai","guo|gui","yi",
+       "hu","chan","kou","cu","ping","zao","ji","gui","su","lou",
+       "ce|ji","lu","nian","suo","cuan","diao","suo","le","duan","zhu",
+       "xiao","bo","mi|mie","shai|si","dang","liao","dan","dian","fu","jian",
+       "min","kui","dai","jiao","deng","huang","sun|zhuan","lao","zan","xiao",
+       "lu","shi","zan","qi","pai","qi","pai","gan","ju","lu",
+       "lu","yan","bo","dang","sai","zhua","gou","qian","lian","bu|bo",
+       "zhou","lai","shi","lan","kui","yu","yue","hao","zhen|jian","tai",
+       "ti","nie","chou","ji","yi","qi","teng","zhuan","zhou","fan|pan|bian",
+       "sou|shu","zhou","qian","zhuo","teng","lu","lu","jian","tuo","ying",
+       "yu","lai","long","shen shi|sen si|qie","lian","lan","qian","yue","zhong","qu",
+       "lian","bian","duan","zuan","li","shai","luo","ying","yue","zhuo",
+       "yu","mi","di","fan","shen","zhe","shen","nv","he","lei",
+       "xian","zi","ni","cun","zhang","qian","zhai","bi","ban","wu",
+       "sha|chao","kang|jing","rou","fen","bi","cui","yin","zhe","mi","ta",
+       "hu","ba","li","gan","ju","po","yu","cu","nian","zhou",
+       "chi","su","tiao","li","xi","su","hong","tong","zi|ci","ce|se",
+       "yue","zhou|yu","lin","zhuang","bai","lao","fen","er","qu","he",
+       "liang","xian","fu","liang","can","jing","li","yue","lu","ju",
+       "qi","cui","bai","zhang","lin","zong","jing","guo","hua","san|shen",
+       "shen","tang","bian","rou","mian","hou","xu","zong","hu","jian",
+       "zan","ci","li","xie","fu","nuo","bei","gu|gou","xiu","gao",
+       "tang","qiu","jia","cao","zhuang","tang","mi|mei","san|shen","fen","zao",
+       "kang","jiang","mo","san|shen","san","nuo","xi","liang","jiang","kuai",
+       "bo","huan","shu","zong","xian","nuo","tuan","nie","li","zuo",
+       "di","nie","tiao","lan","mi|si","si","jiu","xi|ji","gong","zheng",
+       "jiu","gong","ji","cha","zhou","xun","yue|yao","hong|gong","yu","he|ge",
+       "wan","ren","wen","wen","qiu","na","zi","tou","niu","fou",
+       "ji|jie","shu","chun","bi","zhen","sha","hong","zhi","ji","fen",
+       "yun","ren","dan","jin","su","fang","suo","cui","jiu","zha|za",
+       "ha","jin","fu","zhi","qi","zi","chou","hong","zha|za","lei",
+       "xi","fu","xie","shen","bo|bi","zhu","qu","ling","zhu","shao",
+       "gan","yang","fu","tuo","zhen|tian","dai","chu","shi","zhong","xian",
+       "zu","jiong","ban","qu","mo","shu","zui","kuang","jing","ren",
+       "hang","xie","jie","zhu","chou","gua|kua","bai|mo","jue","kuang","hu",
+       "ci","huan|geng","geng","tao","xie|jie","ku","jiao","quan|shuan","gai|ai","luo|lao",
+       "xuan","beng|bing|peng","xian","fu","gei|ji","tong|dong","rong","tiao|diao|dao","yin","lei",
+       "xie","juan","xu","gai|hai","die","tong","si","jiang","xiang","hui",
+       "jue","zhi","jian","juan","chi|zhi","mian|wen|man|wan","zhen","lv","cheng","qiu",
+       "shu","bang","tong","xiao","huan|wan","qin|xian","geng","xu","ti","xiu",
+       "xie","hong","xi","fu","ting","sui","dui","kun","fu","jing",
+       "hu","zhi","yan|xian","jiong","feng","ji","xu","ren","zong|zeng","lin|chen",
+       "duo","li|lie","lv","jing","chou","quan","shao","qi","qi","zhun",
+       "ji|qi","wan","qian|qing|zheng","xian","shou","wei","qing|qi","tao","wan","gang",
+       "wang","beng","zhui","cai","guo","cui","lun|guan","liu","qi","zhan",
+       "bi","chuo|chao","ling","mian","qi","ji","tian|tan|chan","zong","gun","zou",
+       "xi","zi","xing","liang","gei|ji","fei","rui","min","yu","zong",
+       "fan","lv|lu","xu","ying","shang","zi","xu","xiang","jian","ke",
+       "xian","ruan","mian","ji|qi","duan","chong|zhong","di","min","miao|mao","yuan",
+       "xie|ye","bao","si","qiu","bian","huan","geng","zong","mian","wei",
+       "fu","wei","tou|xu|shu","gou","miao","xie","lian","zong","bian|pian","gun|yun",
+       "yin","ti","gua|wo","zhi","yun|wen","cheng","chan","dai","xie","yuan",
+       "zong","xu","sheng","wei","geng","seon","ying","jin","yi","zhui",
+       "ni","bang","gu","pan","zhou","jian","ci|cuo|suo","quan","shuang","yun|wen",
+       "xia","cui|sui|shuai","xi","rong","tao","fu","yun","zhen","gao","ru",
+       "hu","zai|zeng","teng","xian|xuan","su","zhen","zong","tao","huang","cai",
+       "bi","feng","cu","li","suo|su","yan|yin","xi","zong","lei","zhuan|juan",
+       "qian","man","zhi","lv","mu|mo","piao","lian","mi","xuan","zong",
+       "ji","shan","sui","fan|po","lv","beng","yi","sao","mou|miu|miao|mu|liao","yao|you|zhou",
+       "qiang","sheng","xian","ji","zong","xiu","ran","xuan","sui","qiao",
+       "zeng","zuo","zhi","shan","san","lin","ju|jue","fan","liao","chuo",
+       "zun","jian","rao","chan","rui","xiu","hui","hua","zuan","xi",
+       "qiang","wen","da","sheng","hui","xi|ji","se","jian","jiang","huan",
+       "qiao|sao","cong","xie","jiao|zhuo","bi","dan|tan|chan","yi","nong","sui","yi",
+       "sha","ru","ji","bin","qian","lan","pu|fu","xun","zuan","zi",
+       "peng","yao|li","mo","lei","xie","zuan","kuang","you","xu","lei",
+       "xian","chan","jiao","lu","chan","ying","cai","xiang|rang","qian","zui",
+       "zuan","luo","li|xi|sa","dao","lan","lei","lian","si","jiu","yu",
+       "hong|gong","zhou","xian|qian","he|ge","yue|yao","ji","wan","kuang","ji","ren",
+       "wei","yun","hong","chun","pi|bi","sha","gang","na","ren","zong",
+       "lun|guan","fen","zhi","wen","fang","zhu","zhen","niu","shu","xian",
+       "gan","xie","fu","lian","zu","shen","xi","zhi","zhong","zhou",
+       "ban","fu","chu","shao","yi","jing","dai","bang","rong","jie",
+       "ku","rao","die","hang","hui","gei|ji","xuan","jiang","luo|lao","jue",
+       "jiao","tong","bing","xiao","juan","xiu","xi","sui","tao","ji",
+       "ti","ji","xu","ling","ying","xu","qi","fei","chuo|chao","shang",
+       "gun","sheng","wei","mian","shou","beng","chou","tao","liu","quan",
+       "zong|zeng","zhan","wan","lv|lu","zhui","zi","ke","xiang","jian","mian",
+       "lan","ti","miao","ji|qi","yun|wen","hui","si","duo","duan","bian|pian",
+       "xian","gou","zhui","huan","di","lv","bian","min","yuan","jin",
+       "fu","ru","zhen","feng","cui|sui|shuai","gao","chan","li","yi","jian",
+       "bin","piao","man","lei","ying","suo|su","mou|miu|miao|mu|liao","sao","xie","liao",
+       "shan","zeng","jiang","qian","qiao|sao","huan","jiao|zhuo","zuan","fou","xie",
+       "gang","fou","que","fou","que","bo","ping","xiang","zhao","gang",
+       "ying","ying","qing","xia","guan","zun","tan","cheng","qi","weng",
+       "ying","lei","tan","lu","guan","wang","wang","wang","wang","han",
+       "rb","luo","fu","shen","fa","gu","zhu","ju","mao","gu",
+       "min","gang","ba|pi","gua","ti","juan","fu","shen","yan","zhao",
+       "zui","guai|gua","zhuo","yu","zhi","an","fa","lan","shu","si",
+       "pi","ma","liu","ba|pi","fa","li","chao","wei","bi","ji",
+       "zeng","chong","liu","ji","juan","mi","zhao","luo","pi","ji",
+       "ji","luan","yang|xiang","mi","qiang","da","mei","yang|xiang","ling","you",
+       "fen","ba","gao","yang","gu","qiang","zang","mei|gao","ling","yi|xi",
+       "zhu","di","xiu","qiang","yi","xian","rong","qun","qun","qiang",
+       "huan","suo","xian","yi","you","qiang|kong","qian|xian|yan","yu","geng","jie",
+       "tang","yuan","xi","fan","shan","fen","shan","lian","lei","geng",
+       "nou","qiang","chan","yu","hong|gong","yi","chong","weng","fen","hong",
+       "chi","chi","cui","fu","xia","ben","yi","la","yi","pi|bi|po",
+       "ling","liu","zhi","qu|yu","xi","xie","xiang","xi","xi","ke",
+       "qiao","hui","hui","xiao","sha","hong","jiang","zhai|di","cui","fei",
+       "dao|zhou","sha","chi","zhu","jian","xuan","chi","pian","zong","wan",
+       "hui","hou","he","he","han","ao","piao","yi","lian","hou|qu",
+       "ao","lin","pen","qiao","ao","fan","yi","hui","xuan","dao",
+       "yao","lao","lao","kao","mao","zhe","qi|shi","gou","gou","gou",
+       "die","die","er","shua","ruan|nuo","er|nai","nai","duan|zhuan","lei","ting",
+       "zi","geng","chao","hao","yun","ba|pa","pi","si|chi","si","qu|chu",
+       "jia","ju","huo","chu","lao","lun","ji|jie","tang","ou","lou",
+       "nou","jiang","pang","zha|ze","lou","ji","lao","huo","you","mo",
+       "huai","er","yi","ding","ye","da","song","qin","yun|ying","chi",
+       "dan","dan","hong","geng","zhi","pan","nie","dan","zhen","che",
+       "ling","zheng","you","wa|tui|zhuo","liao","long","zhi","ning","tiao","er|nv",
+       "ya","tie|zhe","guo","xu","lian","hao","sheng","lie","pin","jing",
+       "ju","bi","di|zhi","guo","wen","xu","ping","cong","ding","ni",
+       "ting","ju","cong","kui","lian","kui","cong","lian","weng","kui",
+       "lian","lian","cong","ao","sheng","song","ting","kui","nie","zhi",
+       "dan","ning","qie","ni|jian","ting","ting","long","yu","yu","zhao",
+       "si","su","yi","su","si","zhao","zhao","rou","yi","lei|le",
+       "ji","qiu","ken","cao","ge","bo|di","huan","huang","chi","ren",
+       "xiao","ru","zhou","yuan","du","gang","rong|chen","gan","chai","wo",
+       "chang","gu","zhi","qin|han","fu","fei","ban","pei","pang|pan","jian",
+       "fang","zhun|chun","you","na","ang","ken","ran","gong","yu","wen",
+       "yao","qi","pi|bi","qian","xi","xi","fei","ken","jing","tai",
+       "shen","zhong","zhang","xie","shen","wei","zhou","die","dan","fei|bi",
+       "ba","bo","qu","tian","bei","gua","tai","zi|fei","fei|ku","zhi",
+       "ni","ping|peng","zi","fu|zhou","pang|pan","zhen","xian","zuo","pei","jia",
+       "sheng","zhi","bao","mu","qu","hu","qia","chi","yin","xu",
+       "yang","long","dong","ka","lu","jing","nu","yan","pang","kua",
+       "yi","guang","hai","ge","dong","chi","jiao","xiong","xiong","er",
+       "an","heng","pian","neng|nai","zi","gui|kui","zheng","tiao","zhi","cui",
+       "mei","xie","cui","xie","mai","mai","ji","xie","nin","kuai",
+       "sa","zang","qi","nao","mi","nong","luan","wan","bo","wen",
+       "wan","xiu","jiao","jing","rou","heng","cuo","lie","shan","ting",
+       "mei","chun","shen","jia","te","juan","cu","xiu","xin","tuo",
+       "pao","cheng","nei","fu","dou","tuo","niao","nao","pi","gu",
+       "luo","li","lian","zhang","cui","jie","liang","shui","pi","biao",
+       "lun","pian","guo","juan","chui","dan","tian","nei","jing","nai",
+       "la","ye","a","ren","shen","zhui","fu","fu","ju","fei",
+       "qiang","wan","dong","pi","guo","zong","ding","wo","mei","ruan",
+       "zhuan","chi","cou","luo","ou","di","an","xing","nao","shu",
+       "shuan","nan","yun","zhong","rou","e","sai","tu","yao","jian",
+       "wei","jiao","yu","jia","duan","bi","chang","fu","xian","ni",
+       "mian","wa","teng","tui","bang","qian","lv","wa","shou","tang",
+       "su","zhui","ge","yi","bo","liao","ji","pi","xie","gao",
+       "lv","bin","ou","chang","lu|biao","guo","pang","chuai","biao","jiang",
+       "fu","tang","mo","xi","zhuan|chuan|chun","lv","jiao","ying","lv","zhi",
+       "xue","cun","lin","tong","peng","ni","chuai","liao","cui","kui",
+       "xiao","teng","fan|pan","zhi","jiao","shan","hu|wu","cui","run","xiang",
+       "sui","fen","ying","shan|dan","zhua","dan","kuai","nong","tun","lian",
+       "bi|bei","yong","jue","chu","yi","juan","la|ge","lian","sao","tun",
+       "gu","qi","cui","bin","xun","nao","wo|yue","zang","xian","biao",
+       "xing","kuan","la","yan","lu","huo","za","luo","qu","zang",
+       "luan","ni|luan","za","chen","qian|xian","wo","guang|jiong","zang|cang","lin","guang|jiong",
+       "zi","jiao","nie","chou|xiu","ji","gao","chou","mian|bian","nie","zhi",
+       "zhi","ge","jian","die|zhi","zhi|jin","xiu","tai","zhen","jiu","xian",
+       "yu","cha","yao","yu","chong","xi","xi","jiu","yu","yu",
+       "xing","ju","jiu","xin","she","she","she","jiu","shi","tan",
+       "shu","shi","tian","tan","pu","pu","guan","hua","tian","chuan",
+       "shun","xia","wu","zhou","dao","chuan","shan","yi","fan","pa",
+       "tai","fan","ban","chuan","hang","fang","ban","bi","lu","zhong",
+       "jian","cang","ling","zhu","ze","duo","bo","xian","ge","chuan",
+       "xia","lu","qiong","pang","xi","kua","fu","zao","feng","li",
+       "shao","yu","lang","ting","yu","wei","bo","meng","nian","ju",
+       "huang","shou","ke","bian","mu","die","dao","bang","cha","yi",
+       "sou","cang","cao","lou","dai","xue","yao","chong","deng","dang",
+       "qiang","lu","yi","ji","jian","huo","meng","qi","lu","lu",
+       "chan","shuang","gen","liang","jian","jian","se","yan","fu","ping",
+       "yan","yan","cao","ao","yi","le","ding","qiu","ai","nai",
+       "tiao","qiu","jie","peng","wan","yi","chai|cha","mian","mi","gan",
+       "qian","yu","yu","shao","xiong","du","hu|xia","qi","mang","zi",
+       "hui|hu","sui","zhi","xiang","bi|pi","fu","tun|chun","wei","wu","zhi",
+       "qi","shan","wen","qian","ren","fu","kou","jie|gai","lu","xu|zhu",
+       "ji","qin","qi","yuan|yan","fen","ba","rui","xin","ji","hua",
+       "lun|hua","fang","wu|hu","jue","gou","zhi","yun","qin","ao","chu",
+       "mao","ya","fei|fu","reng","hang","cong","chan|yin","you","bian","yi",
+       "qie","wei","li","pi","e","xian","chang","cang","zhu","su",
+       "di|ti","yuan","ran","ling","tai","tiao|shao","di","miao","qing","ji",
+       "yong","ke|he","mu","bei","bao","gou","min","yi","yi","ju|qu",
+       "pie","ruo|re","ku","zhu|ning","ni","pa|bo","bing","shan","xiu","yao",
+       "xian","ben","hong","ying","zuo|zha","dong","cha","die","nie","gan",
+       "hu","ping|peng","mei","fu","sheng|rui","gu","bi","wei","fu","zhuo",
+       "mao","fan","jia","mao","mao","ba","ci","mo","zi","zhi",
+       "chi","ji","jing","long","cong","niao","yuan","xue","ying","qiong",
+       "ge","ming","li","rong","yin","gen","qian","chai","chen","yu",
+       "hao","zi","lie","wu","ji","gui","ci","jian","ci","hou",
+       "guang","mang","cha","jiao","jiao","fu","yu","zhu","zi","jiang",
+       "hui","yin","cha","fa","rong","ru","chong","mang","tong","zhong",
+       "qian","zhu","xun","huan","fu","quan","gai","da","jing","xing",
+       "chuan","cao","jing","er","an","qiao","chi","ren","jian","ti",
+       "huang","ping","li","jin","lao","shu","zhuang","da","jia","rao",
+       "bi","ce","qiao","hui","ji","dang","zi","rong","hun","xing",
+       "luo","ying","qian","jin","sun","yin","mai","hong","zhou","yao",
+       "du","wei","li","dou","fu","ren","yin","he","bi","bu",
+       "yun","di","tu","sui","sui","cheng","chen","wu","bie","xi",
+       "geng","li","pu","zhu","mo","li","zhuang","zuo","tuo","qiu",
+       "suo|sha","suo","chen","peng|feng","ju","mei","meng","xing","jing","che",
+       "shen|xin","jun","yan","ting","you","cuo","guan|wan","han","you","cuo",
+       "jia","wang","su|you","niu","shao|xiao","xian","lang|liang","fu|piao","e","mo|mu",
+       "wen|wan|mian","jie","nan","mu","kan","lai","lian","shi","wo","tu",
+       "xian|lian","huo","you","ying","ying","neus","chun","mang","mang","ci",
+       "wan|yun","jing","di","qu","dong","jian","zou|chu","gu","la","lu",
+       "ju","wei","jun","nie|ren","kun","he","pu","zi|zai","gao","guo",
+       "fu","lun","chang","chou","song","chui","zhan","men","cai","ba",
+       "li","tu","bo","han","bao","qin","juan","xi","qin","di",
+       "jie|sha","pu","dang","jin","qiao|zhao","tai|zhi|chi","geng","hua","gu","ling",
+       "fei","qin|jin","an","wang","beng","zhou","yan","zu","jian","lin|ma",
+       "tan","shu","tian","dao","hu","qi","he","cui","tao","chun",
+       "bi","chang","huan","fei","lai","qi","meng","ping","wei","dan",
+       "sha","huan","yan","yi","tiao","qi","wan","ce","nai","zhen",
+       "tuo","jiu","tie","luo","bi","yi","pan","bo","pao","ding",
+       "ying","ying","ying","xiao","sa","qiu","ke","xiang","wan","yu",
+       "yu","fu","lian","xuan","xuan","nan","ce","wo","chun","shao",
+       "yu","bian","mao","an","e","luo|la|lao","ying","kuo","kuo","jiang",
+       "mian","zuo","zuo","zu","bao","rou","xi","ye","an","qu",
+       "jian","fu","lv","jing","pen","feng","hong","hong","hou","xing",
+       "tu","zhu|zhuo|zhe","zi","xiang","ren","ge","qia","qing","mi","huang",
+       "shen","pu","gai","dong","zhou","qian","wei","bo","wei","pa",
+       "ji","hu","zang","jia","duan","yao","jun","cong","quan","wei",
+       "zhen","kui","ting","hun","xi","shi","qi","lan","zong","yao",
+       "yuan","mei","yun","shu","di","zhuan","guan","ran","xue","chan",
+       "kai","kui|kuai","uu","jiang","lou","wei","pai","yong","sou","yin",
+       "shi","chun","shi","yun","zhen","lang","ru|na","meng","li","que",
+       "suan","yuan|huan","li","ju","xi","bang","chu","xu|shu","tu","liu",
+       "huo","dian","qian","ju","po","cuo","yuan","chu","yu","kuai",
+       "pan","pu","pu","na","shuo","xi","fen","yun","zheng","jian",
+       "ji","ruo","cang","en","mi","hao","sun","zhen","ming","sou",
+       "xu","liu","xi","gu","lang","rong","weng","gai|ge|he","cuo","shi",
+       "tang","luo","ru","suo","xuan","bei","yao|zhuo","gui","bi","zong",
+       "gun","zuo","tiao","ce","pei","lan","dan","ji","li","shen",
+       "lang","yu","ling","ying","mo","diao|tiao|di","tiao","mao","tong","zhu",
+       "peng","an","lian","cong","xi","ping","qiu|xu|fu","jin","chun","jie",
+       "wei","tui","cao","yu","yi","zi|ju","liao|lu","bi","lu","xu",
+       "bu","zhang","lei","qiang","man","yan","ling","ji","biao","gun",
+       "han","di","su","lu","she","shang","di","mie","hun","wan",
+       "bu","di","cuo","zhe","shen","xuan","wei","hu","ao","mi",
+       "lou","cu","zhong","cai","po","jiang","mi","cong","niao","hui",
+       "juan","yin","jian","nian","shu","yin","guo","chen","hu","sha",
+       "kou","qian","ma","zang","ze","qiang","dou","lian","lin","kou",
+       "ai","bi","li","wei","ji","qian","sheng","fan","meng","ou",
+       "chan","dian","xun","jiao","rui","rui","lei","yu","qiao","zhu",
+       "hua","jian","mai","yun","bao","you","qu","lu","rao","hui",
+       "e","ti","fei","jue","zui","fa","ru","fen","kui","shun",
+       "rui","ya","xu","fu","jue","dang","wu","dong","si","xiao",
+       "xi","sa","yun","shao","qi","jian","yun","sun","ling","yu",
+       "xia","weng","ji","hong","si","nong","lei","xuan","yun","yu",
+       "xi|xiao","hao","bao|bo","hao","ai","wei","hui","hui","ji","ci",
+       "xiang","wan|luan","mie","yi","leng","jiang","can","shen","qiang|se","lian",
+       "ke","yuan","da","ti","tang","xue","bi","zhan","sun","xian|lian",
+       "fan","ding","xie","gu","xie","shu","jian","hao|kao","hong","sa",
+       "xin","xun","yao","bai","sou","shu","xun","dui","pin","yuan|wei",
+       "ning","chou|zhou","mai|wo","ru","piao","tai","ji","zao","chen","zhen",
+       "er","ni","ying","gao","cong","xiao|hao","qi","fa","jian","xu",
+       "kui","jie|ji","bian","diao|zhuo","mi","lan","jin","cang|zang","miao","qiong",
+       "qi","xian","liao","ou","xian","su","lv","yi","mai","xie",
+       "li","yi","la","lei","jiao","di","zhi","bei","teng","yao|yue",
+       "mo","huan","biao|pao","fan","sou","tan","tui","qiong","qiao","wei",
+       "liu","hui","ou","gao","yun","bao","li","shu","zhu|chu","ai",
+       "lin","zao","xuan","qin","lai","huo","tuo","wu","rui","rui",
+       "qi","heng","lu","su","tui","mang","yun","ping","yu","xun",
+       "ji","jiong","xuan","mo","qiu","su","jiong","peng","nie","nie",
+       "rang","yi","xian","yu","ju","lian","lian","yin","qiang","ying",
+       "long","tou","hua","yue","ling","qu","yao","fan","mi","lan",
+       "gui","lan","ji","dang","man","lei","lei","hui","feng","zhi",
+       "wei","kui","zhan","huai","li","ji","mi","lei","huai","luo",
+       "ji","kui","lu","jian","sal","teng","lei","quan","xiao","yi",
+       "luan","men","bie","hu","hu","lu","nve","lv","si","xiao",
+       "qian","chu","hu","xu","cuo","fu","xu","xu","lu","hu",
+       "yu","hao","jiao","ju","guo","bao","yan","zhan","zhan","kui",
+       "bin","xi","shu","chong","qiu","diao","ji","qiu","ding","shi",
+       "xia","jue","zhe","she","yu","han","zi","hong","hui","meng",
+       "ge","sui","xia","chai","shi","yi","ma","xiang","fang|bang","e",
+       "ba","chi","qian","wen","wen","rui","bang|beng","pi","yue","yue",
+       "jun","qi","tong","yin","qi|zhi","can","yuan|wan","jue|que","hui","qin|qian",
+       "qi","zhong","ya","hao","mu","wang","fen","fen","hang","gong|zhong",
+       "zao","fu","ran","jie","fu","chi","dou","bao","xian","ni",
+       "dai|de","qiu","you","zha","ping","chi","you","he","han","ju",
+       "li","fu","ran","zha","gou|qu|xu","pi","pi|bo","xian","zhu","diao",
+       "bie","bing","gu","zhan","qu","she|yi","tie","ling","gu","dan",
+       "tun","ying","li","cheng","qu","mou","ge|luo","ci","hui","hui",
+       "mang|bang","fu","yang","wa","lie","zhu","yi","xian","kuo","jiao",
+       "li","yi|xu","ping","jie","ge|ha","she","yi","wang","mo","qiong",
+       "qie|ni","gui","qiong","zhi","man","lao","zhe","jia","nao","si",
+       "qi","xing","jie","qiu","xiao","yong","jia","tui","che","bei",
+       "e|yi","han","shu","xuan","feng","shen","shen","fu","xian","zhe",
+       "wu","fu","li","lang","bi","chu","yuan","you","jie","dan",
+       "yan","ting","dian","tui","hui","wo","zhi","zhong","fei","ju",
+       "mi","qi","qi","yu","jun","la","meng","qiang","si","xi",
+       "lun","li","die","tiao","tao","kun","han","han","yu","bang",
+       "fei","pi","wei","dun","yi","yuan","suo","quan","qian","rui",
+       "ni","qing","wei","liang","guo","wan","dong","e","ban","di",
+       "wang","can","yang","ying","guo","chan","ding","la","ke","ji",
+       "xie","ting","mao","xu","mian","yu","jie","shi","xuan","huang",
+       "yan","bian","rou","wei","fu","yuan","mei","wei","fu","ru",
+       "xie","you","qiu","mao","xia","ying","shi","chong","tang","zhu",
+       "zong","di","fu","yuan","kui","meng","la","dai","hu","qiu",
+       "die","li","wo","yun","qu","nan","lou","chun","rong","ying",
+       "jiang","ban","lang","pang","si","xi","ci","xi","yuan","weng",
+       "lian","sou","ban","rong","rong","ji","wu","xiu","han","qin",
+       "yi","bi","hua","tang","yi","du","nai|neng","he|xia","hu","gui|hui",
+       "ma","ming","yi","wen","ying","teng","zhong","cang","sao","qi",
+       "man","dao","shang","shi|zhe","cao","chi","di","ao","lu","wei",
+       "die|zhi","tang","chen","piao","qu|ju","pi","yu","chan|jian","luo","lou",
+       "qin","zhong","yin","jiang","shuai","wen","xiao","wan","zhe","zhe",
+       "ma","ma","guo","liu","mao","xi","cong","li","man","xiao",
+       "chang","zhang","mang|meng","xiang","mo","zui","si","qiu","te","zhi",
+       "peng","peng","jiao","qu","bie","liao","pan","gui","xi","ji",
+       "zhuan","huang","fei|ben","lao|liao","jue","jue","hui","yin|xun","chan","jiao",
+       "shan","nao","xiao","wu","chong","xun","si","chu","cheng","dang",
+       "li","xie","shan","yi","jing","da","chan","qi","ci","xiang",
+       "she","luo","qin","ying","chai","li","zei","xuan","lian","zhu",
+       "ze","xie","mang","xie","qi","rong","jian","meng","hao","ru",
+       "huo","zhuo","jie","pin","he","mie","fan","lei","jie","la",
+       "min","li","chun","li","qiu","nie","lu","du","xiao","zhu",
+       "long","li","long","feng","ye","pi","nang","gu","juan","ying",
+       "shu","xi","can","qu","quan","du","can","man","qu","jie",
+       "zhu","zhuo","xie","huang","nv","pei","nv","xin","zhong","mai",
+       "er","ke","mie","xi","xing|hang|heng","yan","kan","yuan","qu","ling",
+       "xuan","shu","xian","tong","xiang","jie","xian","ya","hu","wei",
+       "dao","chong","wei","dao","zhun","heng","qu","yi","yi","bu",
+       "gan","yu","biao","cha","yi","shan","chen","fu","gun","fen",
+       "shuai","jie","na","zhong","dan","ri","zhong","zhong","jie","zhi",
+       "xie","ran","zhi","ren","qin","jin","jun","yuan","mei","chai",
+       "ao","niao","hui","ran","jia","tuo","ling","dai","bao|pao","pao",
+       "yao","zuo","bi","shao","tan","ju|jie","he|ke","xue","xiu","zhen",
+       "yi","pa","fu","di","wa","fu","gun","zhi","zhi","ran",
+       "pan","yi","mao","tuo","na|jue","gou","xuan","zhe","qu","bei|pi",
+       "yu","xi","mi","bo","uu","fu","chi|nuo","chi|qi|duo|nuo","ku","ren",
+       "peng","jia|jie|qia","jian|zun","bo|mo","jie","er","ge","ru","zhu","gui|gua",
+       "yin","cai","lie","ka","hang","zhuang","dang","xu","kun","ken",
+       "niao","shu","jia","kun","cheng","li","juan","shen","pou","ge|jie",
+       "yi","yu","zhen","liu","qiu","qun","ji","yi","bu","zhuang",
+       "shui","sha","qun","li","lian","lian","ku","jian","bao","chan",
+       "bi|pi","kun","tao","yuan","ling","chi","chang","chou|dao","duo","biao",
+       "liang","chang|shBng","pei","pei","fei","yuan|gun","luo","guo","yan|an","du",
+       "xi|ti","zhi","ju","yi","qi","guo","gua","ken","qi","ti",
+       "ti","fu","chong","xie","bian","die","kun","duan","xiu","xiu",
+       "he","yuan","bao","bao","fu","yu","tuan","yan","hui","bei",
+       "zhu","lv","pao","dan","yun","ta","gou","da","huai","rong",
+       "yuan","ru","nai","jiong","suo","ban","tui","chi","sang","niao",
+       "ying","jie","qian","huai","ku","lian","lan","li","zhe","shi",
+       "lv","yi","die","xie","xian","wei","biao","cao","ji","qiang",
+       "sen","bao","xiang","bi","fu","jian","zhuan","jian","cui","ji",
+       "dan","za","fan","bo","xiang","xin","bie","rao","man","lan",
+       "ao","ze","gui","cao","sui","nong","chan","lian","bi","jin",
+       "dang","shu","tan","bi","lan","fu","ru","zhi","ta","shu",
+       "wa","shi","bai","xie","bo","chen","lai","long","xi","xian",
+       "lan","zhe","dai","ju","zan","shi","jian","pan","yi","lan",
+       "ya","xi","ya","yao","feng","tan|qin","fu","fiao","fu","ba|po",
+       "he","ji","ji","jian|xian","guan","bian","yan","gui","jue|jiao","pian",
+       "mao","mi","mi","pie|mie","shi","si","chan","zhen","jue|jiao","mi",
+       "tiao","lian","yao","zhi","jun","xi","shan","wei","xi","tian",
+       "yu","lan","e","du","qin|qing","pang","ji","ming","ying","gou",
+       "qu","zhan","jin","guan","deng","jian|bian","luo|luan","qu","jian","wei",
+       "jue|jiao","qu","luo","lan","shen","di","guan","jian|xian","guan","yan",
+       "gui","mi","shi","chan","lan","jue|jiao","ji","xi","di","tian",
+       "yu","gou","jin","qu","jiao|jue","qiu","jin","cu","jue","zhi",
+       "chao","ji","gu","dan","zi|zui","di","shang","hua|xie","quan","ge",
+       "shi","jie|xie","gui","gong","chu","jie|xie","hun","qiu","xing","su",
+       "ni","ji|qi","jue","zhi","zha","bi","xing","hu","shang","gong",
+       "zhi","xue|hu","chu","xi","yi","li|lu","jue","xi","yan","xi",
+       "yan","yan","ding","fu","qiu","qiu","jiao","hong","ji","fan",
+       "xun","diao","hong","chai","tao","xu","jie","dan","ren","xun",
+       "yin","shan","qi","tuo","ji","xun","yin","e","fen","ya",
+       "yao","song","shen","yin","xin","jue","xiao","ne","chen","you",
+       "zhi","xiong","fang","xin","chao","she","yan","sa","zhun","xu",
+       "yi","yi","su","chi","he","shen","he","xu","zhen","zhu",
+       "zheng","gou","zi","zi","zhan","gu","fu","jian","die","ling",
+       "di","yang","li","nao","pan","zhou","gan","yi","ju","yao",
+       "zha","tuo","yi","qu","zhao","ping","bi","xiong","qu","ba",
+       "da","zu","tao","zhu","ci","zhe","yong","xu","xun","yi",
+       "huang","he","shi","cha","xiao","shi","hen","cha","gou","gui",
+       "quan","hui","jie","hua","gai","xiang","wei","shen","chou","tong",
+       "mi","zhan","ming","luo","hui","yan","xiong","gua","er","bing",
+       "tiao|diao","yi|chi","lei","zhu","kuang","kua","wu","yu","teng","ji",
+       "zhi","ren","cu","lang","e","kuang","ei|xi","shi","ting","dan",
+       "bei|bo","chan","you","keng","qiao","qin","shua","an","yu","xiao",
+       "cheng","jie","xian","wu","wu","gao","song","bu","hui","jing",
+       "shuo|shui|yue","zhen","shuo|shui|yue","du","hua","chang","shui|shei","jie","ke","qu|jue",
+       "cong","xiao","sui","wang","xian","fei","chi|lai","ta","yi","ni|na",
+       "yin","diao|tiao","pi|bei","zhuo","chan","chen","zhun","ji","qi","tan",
+       "zhui","wei","ju","qing","dong","zheng","ze|zuo|zha|cuo","zou","qian","zhuo",
+       "liang","jian","chu|ji","xia|hao","lun","shen","biao","hua","bian","yu",
+       "die","xu","pian","shi|di","xuan","shi","hun","hua|gua","e","zhong",
+       "di","xie","fu","pu","ting","jian","qi","yu","zi","zhuan",
+       "xi|shai|ai","hui","yin","an","xian","nan","chen","feng","zhu","yang",
+       "yan","huang","xuan","ge","nuo","xu","mou","ye","wei","xing",
+       "teng","zhou","shan","jian","bo","kui","huang","huo","ge","ying",
+       "mi","xiao","mi","xi","qiang","chen","xue","ti","su","bang",
+       "chi","qian","shi","jiang","yuan","xie","he","tao","yao","yao",
+       "lu","yu","biao","cong","qing","li","mo","mo","shang","zhe",
+       "miu","jian","ze","jie","lian","lou","can","ou","gun","xi",
+       "zhuo","ao","ao","jin","zhe","yi","hu","jiang","man","chao",
+       "han","hua","chan","xu","zeng","se","xi","zha","dui","zheng",
+       "nao","lan","e","ying","jue","ji","zun","jiao","bo","hui",
+       "zhuan","wu","zen","zha","shi","qiao","tan","jian","pu","sheng",
+       "xuan","zao","tan","dang","sui","xian","ji","jiao","jing","zhan",
+       "nong","yi","ai","zhan","pi","hui","hua","yi","yi","shan",
+       "rang","rou","qian","dui","ta","hu","zhou","hao","ai","ying",
+       "jian","yu","jian","hui","du","zhe","juan|xuan","zan","lei","shen",
+       "wei","chan","li","yi|tui","bian","zhe","yan","e","chou","wei",
+       "chou","yao","chan","rang","yin","lan","chen","xie","nie","huan",
+       "zan","yi","dang","zhan","yan","du","yan","ji","ding","fu",
+       "ren","ji","jie","hong","tao","rang","shan","qi","tuo","xun",
+       "yi","xun","ji","ren","jiang","hui","ou","ju","ya","ne",
+       "xu|hu","e","lun","xiong","song","feng","she","fang","jue","zheng",
+       "gu","he","ping","zu","shi|zhi","xiong","zha","su","zhen","di",
+       "zhou","ci","qu","zhao","bi","yi","yi|dai","kuang","lei","shi",
+       "gua","shi","jie|ji","hui","cheng","zhu","shen","hua","dan","gou",
+       "quan","gui","xun","yi","zheng","gai","xiang|yang","cha","hun","xu",
+       "zhou|chou","jie","wu","yu","qiao","wu","gao","you","hui","kuang",
+       "shuo|shui|yue","song","ei|xi","qing","zhu","zou","nuo","du|dou","zhuo","fei",
+       "ke","wei","yu","shui","shen","diao","chan","liang","zhun","sui",
+       "tan","shen","yi","mou","chen","die","huang","jian","xie","xue",
+       "ye","wei","e","yu","xuan","chan","zi","an","yan","di",
+       "mi","pian","xu","mo","dang","su","xie","yao","bang","shi",
+       "qian","mi","jin","man","zhe","jian","miu","tan","zen","qiao",
+       "lan","pu","jue","yan","qian","zhan","chen","gu","qian","hong",
+       "xia","ji","hong","han","hong","xi","xi","huo","liao","han",
+       "du","long","dou","jiang","qi","chi","li","deng","wan","bi",
+       "shu","xian","feng","zhi","zhi","yan","yan","shi","chu","hui",
+       "tun","yi","tun","yi","jian","ba","hou","e","chu","xiang",
+       "huan","jian","ken","gai","ju","fu","xi","bin","hao","yu",
+       "zhu","jia","fen","xi","hu","wen","huan","bin","di","zong",
+       "fen","yi","zhi","bao","chai","an","pi","na","pi","gou",
+       "na","you","diao","mo","si","xiu","huan","ken|kun","he|mo","he|hao|mo",
+       "mo","an","mao","li","ni","bi","yu","jia","tuan","mao",
+       "pi","xi","yi","ju|lou","mo","chu","tan","huan","jue","bei",
+       "zhen","yuan|yun","fu","cai","gong","dai","yi","hang","wan","pin",
+       "huo","fan","tan","guan","ze|zhai","zhi","er","zhu","shi","bi",
+       "zi","er","gui","pian","bian","mai","dai|te","sheng","kuang","fei",
+       "tie","yi","chi","mao","he","bi|ben","lu","lin","hui","gai",
+       "pian","zi","jia|gu","xu","zei","jiao","gai","zang","jian","ying",
+       "jun","zhen","she","bin","bin","qiu","she","chuan","zang","zhou",
+       "lai","zan","ci","chen","shang","tian","pei","geng","xian","mai",
+       "jian","sui","fu","dan","cong","cong","zhi","lai","zhang","du",
+       "jin","xiong|min","chun","yun","bao","zai","lai","feng","cang","ji",
+       "sheng","ai","zhuan|zuan","fu","gou","sai","ze","liao","yi","bai",
+       "chen","wan","zhi","zhui","biao","yun","zeng","dan","zan","yan",
+       "pu","shan","wan","ying","jin","gan","xian","zang","bi","du",
+       "shu","yan","shang","xuan","long","gan","zang","bei","zhen","fu",
+       "yuan","gong","cai","ze","xian","bai","zhang","huo","zhi","fan",
+       "tan","pin","bian","gou","zhu","guan","er","jian","bi","shi",
+       "tie","gui","kuang","dai","mao","fei","he","yi","zei","zhi",
+       "jia|gu","hui","zi","lin","lu","zang","zi","gai","jin","qiu",
+       "zhen","lai","she","fu","du","ji","shu","shang","ci","bi",
+       "zhou","geng","pei","dan","lai","feng","zhui","fu","zhuan","sai",
+       "ze","yan","zan","yun","zeng","shan","ying","gan","chi","xi",
+       "she","nan","tong","xi","cheng","he","cheng","zhe","xia","tang",
+       "zou","zou","li","jiu","fu","zhao","gan","qi","shan","qiong",
+       "yin","xian","zi","jue","qin","chi","ci","chen","chen","die|tu",
+       "qie|ju","chao","di","xi","zhan","jue","yue","qu|cu","ji|jie","qu",
+       "chu","gua|huo","xue","zi","tiao","duo","lie","gan","suo","cu",
+       "xi","zhao","su","yin","ju","jian","que|qi|ji","tang","chuo","cui",
+       "lu","qu|cu","dang","qiu","zi","ti","qu|cu","chi","huang","qiao",
+       "qiao","jiao","zao","ti|yue","er","zan","zan","zu","pa","bao|bo",
+       "kua|wu","ke","dun","jue|gui","fu","chen","jian","fang|pang","zhi","ta",
+       "yue","ba|pao","qi","yue","qiang","tuo","tai","yi","jian|chen","ling",
+       "mei","ba","die","ku","tuo","jia","ci","pao","qia","zhu",
+       "ju","dian|tie|die","zhi","fu","pan|ban","ju|qie","shan","bo","ni","ju",
+       "li|luo","gen","yi","ji","dai|duo|chi","xian","jiao","duo","zhu","quan",
+       "kua","zhuai","gui","qiong","kui","xiang","die","lu","pian|beng","zhi",
+       "jie","tiao|tao","cai","jian","da","qiao","bi","xian","duo","ji",
+       "ju","ji","shu|chou","tu","chuo","jing","nie","xiao","bu","xue",
+       "qun","mu","shu","liang","yong","jiao","chou","qiao","mou","ta",
+       "jian","ji","wo","wei","chuo","jie","ji","nie","ju","nie",
+       "lun","lu","leng","huai","ju","chi","wan","quan","ti","bo",
+       "zu","qie","qi","cu","zong","cai","zong","peng","zhi","zheng",
+       "dian","zhi","yu","duo","dun","chuan","yong","zhong","di","zhe",
+       "chen","chuai","jian","gua","tang","ju","fu","cu","die","pian",
+       "rou","nuo","ti","cha","tui","jian","dao","cuo","xi","ta",
+       "qiang","nian","dian","ti","ji","nie","pan","liu","zan","bi",
+       "chong","lu","liao","cu","tang","dai","su","xi","kui","ji",
+       "zhi","qiang","di","pan","zong","lian","beng","zao","nian","bie",
+       "tui","ju","deng","ceng","xian","fan","chu","zhong","dun","bo",
+       "cu","cu","jue","jue","lin","ta","qiao","qiao","pu","liao",
+       "dun","cuan","guan","zao","ta","bi","bi","zhu","ju","chu",
+       "qiao","dun","chou","ji","wu","yue","nian","lin","lie","zhi",
+       "li|luo","zhi","chan","chu","duan","wei","long","lin","xian","wei",
+       "zuan","lan","xie","rang","sa|xie","nie","ta","qu","ji","cuan",
+       "zuan","xi","kui","jue","lin","shen","gong","dan","fen","qu",
+       "ti","duo","duo","gong","lang","ren","luo","ai","ji","ju",
+       "tang","kong","lao","yan","mei","kang","qu","lou","lao","duo",
+       "zhi","yan","ti","dao","ying","yu","che|ju","ya|zha|ga","gui","jun",
+       "wei","yue","xin|xian","dai","xuan","fan|gui","ren","shan","kuang","shu",
+       "tun","chen","dai","e","na","qi","mao","ruan","kuang","qian",
+       "zhuan","hong","hu","qu","kuang","di","ling","dai","ao","zhen",
+       "fan","kuang","yang","peng","bei","gu","gu","pao","zhu","rong",
+       "e","ba","zhou","zhi","yao","ke","yi","qing","shi","ping",
+       "er","gong","ju","jiao","guang","lu","kai","quan","zhou","zai",
+       "zhi","she","liang","yu","shao","you","wan","yin","zhe","wan",
+       "fu","qing","zhou","ni","ling","zhe","han","liang","zi","hui",
+       "wang","chuo","guo","kan","yi","peng","qian","gun","nian","ping",
+       "guan","bei","lun","pai","liang","ruan","rou","ji","yang","xian",
+       "chuan","cou","chun","ge","you","hong","shu","fu","zi","fu",
+       "wen","fan","zhan","yu","wen","tao","gu","zhen","xia","yuan",
+       "lu","jiao","chao","zhuan","wei","hun","xue","zhe","jiao","zhan",
+       "bu","lao","fen","fan","lin","ge","se","kan","huan","yi",
+       "ji","dui","er","yu","jian","hong","lei","pei","li","li",
+       "lu","lin","che","ya","gui","xuan","dai","ren","zhuan","e",
+       "lun","ruan","hong","gu","ke","lu","zhou","zhi","yi","hu",
+       "zhen","li","yao","qing","shi","zai","zhi","jiao","zhou","quan",
+       "lu","jiao","zhe","fu","liang","nian","bei","hui","gun","wang",
+       "liang","chuo","zi","cou","fu","ji","wen","shu","pei","yuan",
+       "xia","zhan|nian","lu","zhe","lin","xin","gu","ci","ci","bi|pi",
+       "zui","bian","la","la","ci","xue","ban","bian","bian","bian",
+       "xue","bian","ban","ci","bian","bian","chen","ru","nong","nong",
+       "zhen","chuo","chuo","yi","reng","bian","dao|bian","shi","yu","liao",
+       "da","chan","gan","qian","yu","yu","qi","xun","yi","guo",
+       "mai","qi","bi","wang|kuang","tu","zhun","ying","da","yun","jin",
+       "hang","ya","fan","wu","da","e","huan|hai","zhe|zhei","da","jin",
+       "yuan","wei","lian","chi","che","chi","tiao","zhi|li","yi","jiong",
+       "jia","chen","dai","er","di","po|pai","zhu|wang","die","ze","tao",
+       "shu","yi","keop","jing","hui","dong","you","mi","beng","ji",
+       "nai","yi","jie","zhui|dui","lie","xun","tui","song","kuo","tao",
+       "pang","hou","ni","dun","jiong","xuan","xun","bu","you","xiao",
+       "qiu","tou","zhu","qiu","di","di","tu","jing","ti","dou",
+       "yi","zhe","tong","guang","wu","shi","cheng","su","zao","qun",
+       "feng","lian","suo","hui","li","gu","lai","ben","cuo","zhu",
+       "beng","huan","dai","lu","you","zhou","jin","yu","chuo","kui",
+       "wei","ti","yi","da","yuan","luo","bi","nuo","yu","dang",
+       "sui","dun","sui","yan","chuan","chi","di","yu","shi","zhen",
+       "you","yun","e","bian","guo","e","xia","huang","qiu","dao",
+       "da","wei","nan","yi","gou","yao","chou","liu","xun","ta",
+       "di","chi","yuan","su","ta","qian","ma","yao","guan","zhang",
+       "ao","shi","ca","chi","su","zao","zhe","dun","di","lou",
+       "chi","cuo","lin","zun","rao","qian","xuan","yu","wei","e",
+       "liao","ju","shi","bi","yao","mai","xie","sui","huan|hai","zhan",
+       "teng","er","miao","bian","bian","la","li|chi","yuan","yao","luo",
+       "li","yi","ting","deng","qi","yong","shan","han","yu","mang",
+       "ru","qiong","xi","kuang","fu","kang|hang","bin","fang","xing","na|nei",
+       "xin","shen","bang","yuan","cun","huo","xie|ya|ye|yu|xu","bang","wu","ju",
+       "you","han","tai","qiu","bi","pi","bing","shao","bei","wa",
+       "di","zou","ye","lin","kuang","gui","zhu","shi","ku","yu",
+       "gai|hai","he","qie|xi","zhi","ji","xun|huan","hou","xing","jiao","xi",
+       "gui","na","lang","jia","kuai","zheng","lang","yun","yan","cheng",
+       "dou","chi","lv","fu","wu","fu","gao","hao","lang","jia",
+       "geng","jun","ying","bo","xi","bei","li|zhi","yun","bu","xiao|ao",
+       "qi","pi","qing","guo","zhou","tan","zou","ping","lai","ni",
+       "chen","you","bu","xiang","dan","ju","yong","qiao","yi","du|dou",
+       "yan","mei","ruo","bei","e","shu","juan","yu","yun","hou",
+       "kui","xiang","xiang","sou","tang","ming","xi","ru","chu","zi",
+       "zou","yi","wu","xiang","yun","hao","yong","bi","mao","chao",
+       "fu","liao","yin","zhuan","hu","qiao","yan","zhang","man","qiao",
+       "xu","deng","bi","xun","bi","zeng","wei","zheng","mao","shan",
+       "lin","po","dan","meng","ye","cao","kuai","feng","meng","zou",
+       "kuang","lian","zan","chan","you","qi","yan","chan","cuo","ling",
+       "huan","xi","feng","cuo","li","you","ding","qiu","zhuo","pei",
+       "zhou","yi","gan","yu","jiu","yan","zui","mao","dan","xu",
+       "dou","zhen","fen","yuan","fu","yun","tai","tian","qia","tuo",
+       "cu","han","gu","su","fa","chou","zai","ming","lao","chuo",
+       "chou","you","tong","zhi","xian","jiang","cheng","yin","tu","jiao",
+       "mei","ku","suan","lei","pu","zui","hai","yan","shai","niang",
+       "wei","lu","lan","yan","tao","pei","zhan","chun","tan|dan","zui",
+       "zhui","cu","kun","ti","xian","du","hu","xu","xing","tan",
+       "qiu|chou","chun","yun","fa","ke","sou","mi","quan","chou","cuo",
+       "yun","yong","ang","zha","hai","tang","jiang","piao","chan|chen","yu",
+       "li","zao","lao","yi","jiang","bu","jiao","xi","tan","po|fa",
+       "nong","yi|shi","li","ju","yan|lian|xian","yi","niang","ru","xun","chou",
+       "yan","ling","mi","mi","niang","xin","jiao","shi","mi","yan",
+       "bian","cai","shi","you","shi","shi","li","zhong|chong","ye","liang",
+       "li","jin","jin","ga","yi","liao","dao","zhao","ding","po",
+       "qiu","he","fu","zhen","zhi","ba","luan","fu","nai","diao",
+       "shan","qiao|jiao","kou","chuan","zi","fan","hua|yu","hua|wu","han","gang",
+       "qi","mang","ri|ren|jian","di|dai","si","xi","yi","chai","shi|yi","tu",
+       "xi","nv","qian","qiu","ri|ren|jian","pi|zhao","ye|ya","jin","ba","fang",
+       "chen","xing","dou","yue","qian","fu","bu","na","xin","e",
+       "jue","dun","gou","yin","qian","ban","sa","ren","chao","niu",
+       "fen","yun","yi","qin","pi","guo","hong","yin","jun","diao",
+       "yi","zhong","xi","gai","ri","huo","tai","kang","yuan","lu",
+       "e","qin","duo","zi","ni","tu","shi","min","gu","ke",
+       "ling","bing","si","gu","bo","pi","yu","si","zuo","bu",
+       "you","dian","jia","zhen","shi","shi","tie","ju","zuan","shi",
+       "ta","xuan","zhao","bao","he","bi","sheng","chu","shi","bo",
+       "zhu","chi","za","po","tong","qian","fu","zhai","mao","qian",
+       "fu","li","yue","pi","yang","ban","bo","jie","gou","shu",
+       "zheng","mu","xi","xi","di","jia","mu","tan","shen","yi",
+       "si","kuang","ka","bei","jian","tong","xing","hong","jiao","chi",
+       "er","ge","bing","shi","mao","ha","yin","jun","zhou","chong",
+       "xiang|jiong","tong","mo","lei","ji","yu|si","xu|hui","ren","zun","zhi",
+       "qiong","shan|shuo","chi|li","xian|xi","xing","quan","pi","tie","zhu","hou|xiang",
+       "ming","kua","diao|tiao|yao","xian|kuo|tian|gua","xian","xiu","jun","cha","lao","ji",
+       "pi","ru","mi","yi","yin","guang","an","diu","you","se",
+       "kao","qian","luan","si","ng","diao","han","rui","shi|zhi","keng",
+       "qiu","xiao","zhe|nie","xiu","zang","ti","cuo","xian|kuo|tian|gua","hong|gong","zhong|yong",
+       "tou|tu|dou","lv","mei|meng","lang","wan|jian","xin","yun|jun","bei","wu","su",
+       "yu","chan","ting|ding","bo","han","jia","hong","juan|jian|cuan","feng","chan",
+       "wan","zhi","si","xuan|juan","hua|wu","wu","tiao","kuang","zhuo|chuo","lve",
+       "xing|jing","qin","shen","han","lve","ye","chu","zeng","ju","xian",
+       "e","mang","pu","li","pan","rui","cheng","gao","li","te",
+       "bing","zhu","zhen","tu","liu","zui|nie","ju","chang","yuan|wan","jian",
+       "gang","diao","tao","shang","lun","ke","ling","pi","lu","li",
+       "qing","pei","juan","min","zui","peng","an","pi","xian","ya",
+       "zhui","lei","a","kong","ta","kun","du","nei","chui","zi",
+       "zheng","ben","nie","cong","chun","tan","ding","qi","qian","zhui",
+       "ji","yu","jin","guan","mao","chang","tian","xi","lian","diao",
+       "gu","cuo","shu","zhen","lu","meng","lu","hua","biao","ga",
+       "lai","ken","fang","bu","nai","wan","zan","hu","de","xian",
+       "uu","huo","liang","fa","men","kai","yang","chi","lian","guo",
+       "xian","du","tu","wei","zong","fu","rou","ji","e","jun",
+       "chen","ti","zha","hu","yang","duan","xia","yu","keng","sheng",
+       "huang","wei","fu","zhao","cha","qie","shi","hong","kui","nuo",
+       "mou","qiao","qiao","hou","tou","cong","huan","ye","min","jian",
+       "duan","jian","si","kui","hu","xuan","zhe","jie","zhen","bian",
+       "zhong","zi","xiu","ye","mei","pai","ai","jie","qian","mei",
+       "cuo|cha","da|ta","bang","xia","lian","suo|se","kai","liu","yao|zu","ye|ta|ge",
+       "nou","weng","rong","tang","suo","qiang|cheng","ge|li","shuo","chui","bo",
+       "pan","da","bi|pi","sang","gang","zi","wu","ying","huang","tiao",
+       "liu","kai","sun","sha","sou","wan|jian","gao|hao","zhen","zhen","lang",
+       "yi","yuan","tang","nie","xi","jia","ge","ma","juan","song",
+       "zu","suo","xia","feng","wen","na","lu","suo","ou","zu|chuo",
+       "tuan","xiu","guan","xuan","lian","shou|sou","ao","man","mo","luo",
+       "bi","wei","liu","di","san|qiao|can","cong","yi","lu|ao","ao","keng",
+       "qiang","cui","qi","shang","tang","man","yong","chan","feng","jing",
+       "biao","shu","lou","xiu","cong","long","zan","jian|zan","cao","li",
+       "xia","xi","kang","shuang","beng","zhang","qian","zheng","lu","hua",
+       "ji","pu","hui|sui|rui","qiang","po","lin","se","xiu","san|xian|sa","cheng",
+       "gui","si","liu","nao","huang","pie","sui","fan","qiao","quan",
+       "xi","tang","xiang","jue","jiao","zun","liao","qi","lao","dui",
+       "xin","zan","ji","jian","zhong","deng","ya","ying","dui","jue",
+       "nou","zan","pu","tie","uu","cheng","ding","shan","kai","jian",
+       "fei","sui","lu","juan","hui","yu","lian","zhuo","qiao","jian",
+       "zhuo","lei","bi","tie","huan","ye","duo","guo","dang","ju",
+       "fen","da","bei","yi","ai","zong","xun","diao","zhu","heng",
+       "zhui","ji","nie","he","huo","qing","bin","ying","gui","ning",
+       "xu","jian","jian","qian","cha","zhi","mie","li","lei","ji",
+       "zuan","kuang","shang","peng","la","du","shuo","chuo","lv","biao",
+       "pao","lu","xian","kuan","long","e","lu","xin","jian","lan",
+       "bo","jian","yao","chan","xiang","jian","xi","guan","cang","nie",
+       "lei","cuan","qu","pan","luo","zuan","luan","zao","nie","jue",
+       "tang","zhu","lan","jin","ga","yi","zhen","ding","zhao","po",
+       "liao","tu","qian","chuan","shan","sa|xi","fan","diao","men","nv",
+       "yang","chai","xing","gai","bu","tai","ju","dun","chao","zhong",
+       "na","bei","gang","ban","qian","yue|yao","qin","jun","wu","gou",
+       "kang","fang","huo","dou","niu","ba|pa","yu","qian","zheng","qian",
+       "gu","bo","ke","po","bu","bo","yue","zuan","mu","tan",
+       "jia","dian|tian","you","tie","bo","ling","shuo","qian|yan","mao","bao",
+       "shi","xuan","ta|tuo","bi","ni","pi","duo","xing","kao","lao",
+       "er","mang","ya","you","cheng","jia","ye","nao","zhi","dang|cheng",
+       "tong","lv","diao","yin","kai","zha","zhu","xian|xi","ting|ding","diu",
+       "xian|kuo|tian|gua","hua","quan","sha","ha|ke","diao|tiao|yao","ge","ming","zheng","se",
+       "jiao","yi","chan","chong","tang","an","yin","ru","zhu","lao",
+       "pu","wu","lai","te","lian","keng","xiao","suo","li","zeng",
+       "chu","guo","gao","e","xiu","cuo","lve","feng","xin","liu",
+       "kai","jian","rui","ti","lang","qin","ju","a","qiang","zhe",
+       "nuo","cuo","mao","ben","qi","de","ke","kun","chang","xi",
+       "gu","luo","chui","zhui","jin","zhi","xian","juan","huo","pei",
+       "tan","ding","jian","ju","meng","zi","qie","ying","kai","qiang",
+       "si","e","cha","qiao","zhong","duan","sou","huang","huan","ai",
+       "du","mei","lou","zi","fei","mei","mo","zhen","bo","ge",
+       "nie","tang","juan","nie","na","liu","gao","bang","yi","jia",
+       "bin","rong","biao","tang","man","luo","beng","yong","jing","di",
+       "zu","xuan","liu","xin","jue","liao","pu","lu","dui","lan",
+       "pu","cuan","qiang","deng","huo","lei","huan","zhuo","lian","yi",
+       "cha","biao","la","chan","xiang","chang","chang","jiu","ao","die",
+       "jie","liao","mi","chang|zhang","men","ma","shuan","shan","huo|shan","men",
+       "yan","bi","han|bi","bi","ci ka Bi lu","kai","kang","beng","hong","run",
+       "san","xian","xian|jian","jian","min","xia","lao","dou","zha","nao",
+       "zhan","peng","xia|ke","ling","bian|guan","bi","run","he","guan","ge",
+       "he","fa","chu","hong|xiang","gui","min","se","kun","lang","lv",
+       "ting","sha","ju","yue","yue","chan","qu","lin","chang","sha",
+       "kun","yan","wen","yan","e|yan","hun","yu","wen","hong","bao",
+       "hong|juan|xiang","qu","yao","wen","ban|pan","an","wei","yin","kuo","que",
+       "lan","du","quan","pBi ying|po he deng","tian","nie","ta","kai","he","que",
+       "chuang","guan","dou","qi","kui","tang|chang","guan","piao","kan|han","xi|se|ta",
+       "hui","chan","bi","dang","huan","ta","wen","ta","men","shuan",
+       "shan","yan","han|bi","bi","wen","chuang","run","wei","xian","hong",
+       "jian","min","kang","men","zha","nao","gui","wen","ta","min",
+       "lv","kai","fa","ge","he","kun","jiu","yue","lang","du",
+       "yu","yan","chang","xi","wen","hun","yan","e","chan","lan",
+       "qu","hui","kuo","que","he","tian","ta","que","kan|han","huan",
+       "fu","fu","le","dui","xin","qian","wu","yi","tuo","yin",
+       "yang","dou","e","sheng","ban","pei","keng","yun","ruan","zhi",
+       "pi","jing","fang","yang","yin","zhen","jie","cheng","e","qu",
+       "di","zu","zuo","dian","lin","a","tuo","tuo","bei","bing",
+       "fu","ji","lu","long","chen","xing","duo","lou","mo","jiang",
+       "shu","duo","xian","er","gui","yu","gai","shan","jun","qiao",
+       "xing","chun","wu","bi","xia","shan","sheng","zhi","pu","dou",
+       "yuan","zhen","chu","xian","dao","nie","yun","xian","pei","fei",
+       "zou","qi","dui","lun","yin","ju","chui","chen","pi","ling",
+       "tao","xian","lu","sheng","xian","yin","zhu","yang","reng","xia",
+       "chong","yan","yin","yu|yao|shu","di","yu","long","wei","wei","nie",
+       "dui|zhui","sui|duo","an","huang","jie","sui","yin","qi|gai|ai","yan","hui|duo",
+       "ge","yun","wu","wei|kui","ai","xi","tang","ji","zhang","dao",
+       "ao","xi","yin","sa","rao","lin","tui","deng","pi","sui",
+       "sui","ao|yu","xian","fen","ni","er","ji","dao","xi","yin",
+       "zhi","hui|duo","long","xi","li|dai","li|dai","li|dai","zhui|cui|wei","hu|he","zhi",
+       "sun","jun|juan","nan|nuo","yi","que|qiao","yan","qin","jian","xiong","ya",
+       "ji","gu","huan","zhi","gou","jun|juan","ci","yong","ju","chu",
+       "hu","za","luo","yu","chou","diao","sui","han","huo","shuang",
+       "guan|huan","chu","za","yong","ji","gui|xi","chou","liu","li","nan|nuo",
+       "yu","za","chou","ji","yu","yu","xue","na","fou","se|xi",
+       "mu","wen","fen","pang","yun","li","chi","yang","ling","lei",
+       "an","bao","wu|meng","dian","dang","hu","wu","diao","xu","ji",
+       "mu","chen","xiao","zha","ting","zhen","pei","mei","ling","qi",
+       "zhou","huo","sha","fei","hong","zhan","yin","ni","shu","tun",
+       "lin","ling","dong","ying","wu","ling","shuang","ling","xia","hong",
+       "yin","mai","mai","yun","liu","meng","bin","wu","wei","kuo",
+       "yin","xi","yi","ai","dan","teng","xian","yu","lu","long",
+       "dai","ji","pang","yang","ba","pi","wei","uu","xi","ji",
+       "mai","meng","meng","lei","li","huo","ai","fei","dai","long",
+       "ling","ai","feng","li","bao","he","he","he","bing","qing",
+       "qing","liang","tian","zheng","jing","cheng","qing","jing","liang","dian",
+       "jing","tian","fei","fei","kao","mi","mian","mian","pao","ye",
+       "mian","hui","ye","ge","ding","cha","jian","ren","di","du",
+       "wu","ren","qin","jin","xue","niu","ba","yin","sa","na",
+       "mo","zu","da","ban","xie","yao","tao","bei","jie","hong",
+       "pao","yang","bing","yin","ge|ta|sa","tao","jie|ji","xie","an","an",
+       "hen","gong","qia","da","qiao","ting","man|men","bian|ying","sui","tiao",
+       "qiao|shao","xuan|juan","kong","beng","ta","shang|zhang","bing|pi|bi|bei","kuo","ju","la",
+       "xie|die","rou","bang","eng","qiu","qiu","he","qiao","mu|mou","ju",
+       "jian","bian","di","jian","wen|yun","tao","gou","ta","bei","xie",
+       "pan","ge","bi|bing","kuo","tang","lou","gui","qiao","xue","ji",
+       "jian","jiang","chan","da","huo","xian","qian","du","wa","jian",
+       "lan","wei","ren","fu","mei|wa","quan","ge","wei","qiao","han",
+       "chang","kuo","rou","yun","she|xie","wei","ge","bai","tao","gou",
+       "yun","gao","bi","wei","sui","du","wa","du","wei","ren",
+       "fu","han","wei","yun|wen","tao","jiu","jiu","xian","xie","xian",
+       "ji","yin","za","yun","shao","le","peng","huang","ying","yun",
+       "peng","an","yin","xiang","hu","ye","ding","qing","qiu","xiang",
+       "shun","han","xu","yi","xu","e","song","kui","qi","hang",
+       "yu","wan","ban","dun","di","dan","pan","po","ling","che",
+       "jing","lei","he","qiao","e","e","wei","jie","kuo","shen",
+       "yi","yi","ke","dui","yu","ping","lei","fu","jia","tou",
+       "hui","kui","jia","luo","ting","cheng","ying","jun","hu","han",
+       "geng","tui","tui","bin","lai","tui","zi","zi","chui","ding",
+       "lai","tan","han","qian","ke","cui","jiong","qin","yi","sai",
+       "ti","e","e","yan","wen","kan","yong","zhuan","yan","xian",
+       "xin","yi","yuan","sang","dian","dian","jiang","kui","lei","lao",
+       "piao","wai","man","cu","yao","hao","qiao","gu","xun","yan",
+       "hui","chan","ru","meng","bin","xian","pin","lu","lan","nie",
+       "quan","ye","ding","qing","han","xiang","shun","xu","xu","wan",
+       "gu","dun","qi","ban","song","hang","yu","lu","ling","po",
+       "jing|geng","jie|xie|jia","jia","ting","he|ge","ying","jiong","ke","yi","pin|bin",
+       "hui","tui","han","ying","ying","ke","ti","yong","e","zhuan",
+       "yan","e","nie","man","dian","sang","hao","lei","chan|zhan","ru",
+       "pin","quan","feng","biao|diu","gua","fu","xia","zhan","biao","sa",
+       "ba|fu","tai","lie","gua","xuan","xiao","ju","biao","si","wei",
+       "yang","yao","sou","kai","sao|sou","fan","liu","xi","liu|liao","piao",
+       "piao","liu","biao","biao","biao","liao","biao","se","feng","xiu",
+       "feng","yang","zhan","biao","sa","ju","si","sou","yao","liu",
+       "piao","biao","biao","fei","fan","fei","fei","shi|si|yi","shi","can",
+       "ji","ding","si","tuo","zhan","sun","xiang","tun","ren","yu",
+       "yang|juan","chi","yin","fan","fan","sun","yin","zhu|tou","si","zuo|ze|zha",
+       "bi","jie","tao","bao","ci","tie","si","bao","shi","duo",
+       "hai","ren","tian","jiao","he","bing","yao","tong","ci","xiang",
+       "yang","juan","er","yan","le","xi","can","bo","nei","e",
+       "bu","jun","dou","su","yu","shi","yao","hun","guo","shi",
+       "jian","chuo","bing","xian","bu","ye","dan","fei","zhang","wei",
+       "guan","e","nuan","yun","hu","huang","tie","hui","jian","hou",
+       "ai","xing","fen","wei","gu","cha","song","tang","bo","gao",
+       "xi","kui","liu","sou","tao","ye","wen","mo","tang","man",
+       "bi","yu","xiu","jin","san","kui","zhuan","shan","xi","dan",
+       "yi","ji","rao","cheng","yong","tao","wei","xiang","zhan","fen",
+       "hai","meng","yan","mo","chan","xiang","luo","zan","nang","shi",
+       "ding","ji","tuo","xing","tun","xi","ren","yu","chi","fan",
+       "yin","jian","shi","bao","si","duo","yi","er","rao","xiang",
+       "he","ge","jiao","xi","bing","bo","dou","e","yu","nei",
+       "jun","guo","hun","xian","guan","cha","kui","gu","sou","chan",
+       "ye","mo","bo","liu","xiu","jin","man","san","zhuan","nang",
+       "shou","kui","guo","xiang","fen","bo","ni","bi","bo","tu",
+       "han","fei","jian","an","ai","fu","xian","yun|wo","xin","fen",
+       "pin","xin","ma","yu","feng|ping","han","di","tuo|duo","tuo|zhe","chi",
+       "xun","zhu","zhi|shi","pei","xin|jin","ri","sa","yun","wen","zhi",
+       "dan","lu","you","bo","bao","jue|kuai","tuo|duo","yi","qu","wen",
+       "qu","jiong","po","zhao","yuan","peng","zhou","ju","zhu","nu",
+       "ju","pi","zang","jia","ling","zhen","tai|dai","fu","yang","shi",
+       "bi","tuo","tuo","si","liu","ma","pian","tao","zhi","rong",
+       "teng","dong","xun|xuan","quan","shen","jiong","er","hai","bo","zhu",
+       "yin","luo","zhou","dan","hai","liu","ju","song","qin","mang",
+       "liang|lang","han","tu","xuan","tui","jun","e","cheng","xing","dai",
+       "lu","zhui","zhou","she","pian","kun","tao","lai","zong","ke",
+       "qi","qi","yan","fei","sao","yan","ge","yao","wu","pian",
+       "cong","pian","qian","fei","huang","qian","huo","yu","ti","quan",
+       "xia","zong","kui","rou","si","gua","tuo","gui","sou","qian",
+       "cheng","zhi","liu","peng","teng","xi","cao","du","yan","yuan",
+       "zou","sao","shan","qi","zhi","shuang","lu","xi","luo","zhang",
+       "mo","ao","can","piao","cong","qu","bi","zhi","yu","xu",
+       "hua","bo","su","xiao","lin","zhan","dun","liu","tuo","ceng",
+       "dian","jiao","tie","yan","luo","zhan","jing","yi","ye","tuo",
+       "pin","zhou","yan","long","lv","teng","xiang","ji","shuang","ju",
+       "xi","huan","li","biao","ma","yu","duo","xun","chi","qu",
+       "ri","bo","lv","zang","shi","si","fu","ju","zou","zhu",
+       "tuo","nu","jia","yi","dai","xiao","ma","yin","jiao","hua",
+       "luo","hai","pian","biao","li","cheng","yan","xing","qin","jun",
+       "qi","qi","ke","zhui","zong","su","can","pian","zhi","kui",
+       "sao","wu","ao","liu","qian","shan","piao|biao","luo","cong","chan",
+       "zhou","ji","shuang","xiang","gu","wei","wei","wei","yu","gan",
+       "yi","ang","tou","jie","bao","bei|mo","ci","ti","di","ku",
+       "hai","qiao|xiao","hou","kua","ge","tui","geng","pian","bi","ke",
+       "qia","ou","sui","lou","bo","xiao","bang","bo|jue","ci","kuan",
+       "bin","mo","liao","lou","xiao","du","zang","sui","ti","bin",
+       "kuan","lu","gao","gao","qiao","kao","qiao","lao","sao","biao",
+       "kun","kun","di","fang","xiu","ran","mao","dan","kun","bin",
+       "fa","tiao","pi","zi","fa","ran","ti","bao","bi|po","mao|meng",
+       "fu","er","er","qu","gong","xiu","kuo|yue","ji","peng","zhua",
+       "shao","sha","ti","li","bin","zong","ti","peng","song","zheng",
+       "quan","zong","shun","jian","duo","hu","la","jiu","qi","lian",
+       "zhen","bin","peng","ma","san","man","man","seng","xu","lie",
+       "qian","qian","nong","huan","kuo","ning","bin","lie","rang","dou",
+       "dou","nao","hong","xi","dou","kan","dou","dou","jiu","chang",
+       "yu","yu","ge","yan","fu","zeng","gui","zong","liu","gui",
+       "shang","yu","gui","mei","ji","qi","ga","kui","hun","ba",
+       "bo","mei","xu","yan","xiao","liang","yu","tui","qi","wang",
+       "liang","wei","gan","chi","piao","bi","mo","ji","xu","chou",
+       "yan","zhan","yu","dao","ren","ji","ba","hong","tuo","diao",
+       "ji","yu","e","ji","sha","hang","tun","mo","jie","shen",
+       "ban","yuan","pi","lu","wen","hu","lu","za","fang","fen",
+       "na","you","pian","mo","he","xia","qu","han","pi","ling",
+       "tuo","ba","qiu","ping","fu","bi","ci|ji","wei","ju","diao",
+       "bo|ba","you","gun","pi","nian","xing","tai","bao","fu","zha",
+       "ju","gu","shi","dong","chou","ta","jie","shu","hou","xiang",
+       "er","an","wei","zhao","zhu","yin","lie","luo|ge","tong","yi",
+       "yi","bing","wei","jiao","ku","gui|xie|wa|kui","xian","ge","hui","lao",
+       "fu","kao","xiu","tuo","jun","ti","mian","shao","zha","suo",
+       "qin","yu","nei","zhe","gun","geng","su","wu","qiu","shan",
+       "pu|bu","huan","tiao","li","sha","sha","kao","meng","cheng","li",
+       "zou","xi","yong","shen","zi","qi","qing","xiang","nei","chun",
+       "ji","diao","qie","gu","zhou","dong","lai","fei","ni","yi|si",
+       "kun","lu","jiu","chang","jing","lun","ling","zou","li","meng",
+       "zong","zhi","nian","hu","yu","di","shi","shen","huan","ti",
+       "hou","xing","zhu","la","zong","ji","bian","bian","huan","quan",
+       "zei","wei","wei","yu","chun","rou","die","huang","lian","yan",
+       "qiu","qiu","jian","bi","e","yang","fu","sai","jian","xia",
+       "tuo","hu","shi","ruo","xuan","wen","jian","hao","wu","pang",
+       "sao","liu","ma","shi","shi","guan","zi","teng","ta","yao",
+       "e","yong","qian","qi","wen","ruo","ha ta ha ta","lian","ao","le",
+       "hui","min","ji","tiao","qu","jian","shen","man","xi","qiu",
+       "piao","ji","ji","zhu","jiang","xiu","zhuan","yong","zhang","kang",
+       "xue","bie","yu","qu","xiang","bo","jiao","xun","su","huang",
+       "zun","shan","shan","fan","gui","lin","xun","yao","xi","zeng",
+       "xiang","fen","guan","hou","kuai","zei","sao","zhan","gan","gui",
+       "ying","li","chang","lei","se","ai","ru","ji","xu","hu",
+       "shu","li","lie","le","mie","zhen","xiang","e","lu","guan",
+       "li","xian","yu","dao","ji","you","tun","lu","fang","ba",
+       "he|ge","ba","ping","nian","lu","you","zha","fu","bo|ba","bao",
+       "hou","pi","tai","gui|xie","jie","kao","wei","er","tong","zei",
+       "hou","kuai","ji","jiao","xian","zha","xiang","xun","geng","li",
+       "lian","jian","li","shi","tiao","gun","sha","huan","jun","ji",
+       "yong","qing","ling","qi","zou","fei","kun","chang","gu","ni",
+       "nian","diao","jing","shen","shi","zi","fen","die","bi","chang",
+       "ti","wen","wei","sai|xi","e","qiu","fu","huang","quan","jiang",
+       "bian","sao","ao","qi","ta","guan","yao","pang","jian","le",
+       "biao","xue","bie","man","min","yong","wei","xi","gui|jue","shan",
+       "lin","zun","hu","gan","li","zhan|shan","guan","niao|diao","yi","fu",
+       "li","jiu","bu","yan","fu","diao|zhao","ji","feng","ru","gan|han|yan",
+       "shi","feng","ming","bao","yuan","zhi","hu","qin","fu|gui","ban|fen",
+       "wen","jian|qian|zhan","shi","yu","fou","yao","jue","jue","pi","huan",
+       "zhen","bao","yan","ya","zheng","fang","feng","wen","ou","dai",
+       "jia","ru","ling","mie","fu","tuo","min","li","bian","zhi",
+       "ge","yuan","ci","qu","xiao","chi","dan","ju","yao","gu",
+       "zhong","yu","yang","yu","ya","die","yu","tian","ying","dui",
+       "wu","er","gua","ai","zhi","yan","heng","xiao","jia","lie",
+       "zhu","yang","yi","hong","lu","ru","mou","ge","ren","jiao",
+       "xiu","zhou","chi","luo","heng","nian","e","luan","jia","ji",
+       "tu","huan","tuo","bu","wu","juan","yu","bo","jun","jun",
+       "bi","xi","jun","ju","tu","jing","ti","e","e","kuang",
+       "hu","wu","shen","lai","zan","pan","lu","pi","shu","fu",
+       "an","zhuo","peng","qin","qian","bei","diao","lu","que","jian",
+       "ju","tu","ya","yuan","qi","li","ye","zhui","kong","duo",
+       "kun","sheng","qi","jing","yi","yi","jing","zi","lai","dong",
+       "qi","chun","geng","ju","qu","yi","zun","ji","shu","ying",
+       "chi","miao","rou","an","qiu","ti|chi","hu","ti|chi","e","jie",
+       "mao","fu|bi","chun","tu","yan","he|jie","yuan","pian|bian","kun","mei",
+       "hu","ying","chuan|zhi","wu","ju","dong","cang|qiang","fang","he|hu","ying",
+       "yuan","xian","weng","shi","he","chu","tang","xia","ruo","liu",
+       "ji","gu|hu","jian","sun|xun","han","ci","ci","yi","yao","yan",
+       "ji","li","tian","kou","ti","ti","yi","tu","ma","xiao",
+       "gao","tian","chen","ji","tuan","zhe","ao","yao","yi","ou",
+       "chi","zhi","liu","yong","lou|lv","bi","shuang","zhuo","yu","wu",
+       "jue","yin","ti","si","jiao","yi","hua","bi","ying","su",
+       "huang","fan","jiao","liao","yan","gao","jiu","xian","xian","tu",
+       "mai","zun","yu","ying","lu","tuan","xian","xue","yi","pi",
+       "zhu","luo","xi","yi","ji","ze","yu","zhan","ye","yang",
+       "pi","ning","hu","mi","ying","meng","di","yue","yu","lei",
+       "bu","lu","he","long","shuang","yue","ying","guan","qu","li",
+       "luan","niao","jiu","ji","yuan","ming","shi","ou","ya","cang",
+       "bao","zhen","gu","dong","lu","ya","xiao","yang","ling","chi",
+       "qu","yuan","xue","tuo","si","zhi","er","gua","xiu","heng",
+       "zhou","ge","luan","hong","wu","bo","li","juan","hu","e",
+       "yu","xian","ti","wu","que","miao","an","kun","bei","peng",
+       "qian","chun","geng","yuan","su","hu","he","e","gu","qiu",
+       "ci","mei","wu","yi","yao","weng","liu","ji","yi","jian",
+       "he","yi","ying","zhe","liu","liao","jiao","jiu","yu","lu",
+       "huan","zhan","ying","hu","meng","guan","shuang","lu","jin","ling",
+       "jian","xian","cuo","jian","jian","yan","cuo","lu","you","cu",
+       "ji","pao|biao","cu","pao","zhu|cu","jun|qun","zhu","jian","mi","mi",
+       "yu","liu","chen","jun","lin","ni","qi","lu","jiu","jun",
+       "jing","li","xiang","xian","jia","mi","li","she","zhang","lin",
+       "jing","qi","ling","yan","cu","mai","mai","he","chao","fu",
+       "mian","mian","fu","pao","qu","qu","mou","fu","xian","lai",
+       "qu","mian","chi","feng","fu","qu","mian","ma","mo|me","mo|me",
+       "hui","mi","zou","nun","fen","huang","huang","jin","guang","tian",
+       "tou","hong","hua","kuang","hong","shu","li","nian","chi","hei",
+       "hei","yi","qian","dan","xi","tun","mo","mo","qian","dai",
+       "chu","you","dian","yi","xia","yan","qu","mei","yan","qing",
+       "yue","li","dang","du","can","yan","yan","yan","dan|shen","an",
+       "zhen|yan","dai","can","yi","mei","dan|zhan","yan","du","lu","zhi",
+       "fen","fu","fu","min|mian|meng","min|mian|meng","yuan","cu","qu","chao","wa",
+       "zhu","zhi","meng","ao","bie","tuo","bi","yuan","chao","tuo",
+       "ding","mi","nai","ding","zi","gu","gu","dong","fen","tao",
+       "yuan","pi","chang","gao","cao","yuan","tang","teng","shu","shu",
+       "fen","fei","wen","ba","diao","tuo","zhong","qu","sheng","shi",
+       "you","shi","ting","wu","ju","jing","hun","ju","yan","tu",
+       "si","xi","xian","yan","lei","bi","yao","qiu","han","wu",
+       "wu","hou","xie","e","zha","xiu","weng","zha","nong","nang",
+       "qi","zhai","ji","zi","ji","ji","qi","ji","chi","chen",
+       "chen","he","ya","yin","xie","bao","ze","xie","zi","chi",
+       "yan","ju","tiao","ling","ling","chu","quan","xie","yin","nie",
+       "jiu","yao","chuo","yun","yu","chu","yi","ni","ze","zou",
+       "qu","yun","yan","yu","e","wo","yi","ci","zou","dian",
+       "chu","jin","ya","chi","chen","he","yin|ken","ju","ling","bao",
+       "tiao","zi","yin|ken","yu","chuo","qu","wo","long","pang","gong|wo",
+       "pang","yan","long","long","gong","kan","da","ling","da","long",
+       "gong","kan","gui|jun|qiu","qiu","bie","gui|jun|qiu","yue","chui","he","jiao",
+       "xie","yu"};
+
+#define DUOYINZI_SEPERATOR '|'
+
+static inline int __ctsvc_get_pinyinspell(UChar src, char spell[CHINESE_DUOYINZI_MAX_COUNT][CHINESE_PINYIN_SPELL_MAX_LEN])
+{
+       int offset, len, i, j;
+       int count=0;
+
+       offset = src - CHINESE_UNICODE_START;
+       RETVM_IF(offset < 0 || offset >= CHINESE_COUNT , CONTACTS_ERROR_INVALID_PARAMETER, "src is invalid");
+
+       len = strlen(pinyin_spell_table[offset]);
+
+       for(i=0, j=0; i<=len; i++) {
+               if (pinyin_spell_table[offset][i]== DUOYINZI_SEPERATOR
+                               || pinyin_spell_table[offset][i] == '\0') {
+                       strncpy(spell[count], pinyin_spell_table[offset]+j, i-j);
+                       j=i+1;
+                       count++;
+               }
+       }
+
+       return count;
+}
+
+static inline bool __ctsvc_is_chinese(const UChar *src)
+{
+       if (CHINESE_UNICODE_START <= *src && *src <= CHINESE_UNICODE_END)
+               return true;
+
+       return  false;
+}
+
+static inline bool
+__ctsvc_has_chinese(const UChar *src)
+{
+       int     i, len;
+
+       len = u_strlen(src);
+
+       for (i = 0; i < len; i++)
+       {
+               if (__ctsvc_is_chinese(&src[i]))
+                       return true;
+       }
+
+       return false;
+}
+
+bool ctsvc_has_chinese(const char *src)
+{
+       UChar   temp[strlen(src)+1];
+       UErrorCode status = 0;
+
+       RETVM_IF(src==NULL, false, "src is NULL");
+       RETVM_IF(!*src, false, "*src is NULL");
+
+       u_strFromUTF8(temp, array_sizeof(temp), NULL, src, -1, &status);
+       if (U_FAILURE(status)){
+               CTS_ERR("u_strFromUTF8 Failed(%s)", u_errorName(status));
+               return false;
+       }
+
+       return __ctsvc_has_chinese(temp);
+}
+
+#define CTSVC_CHINESE_MULTIPLE_PINYIN_MAX_LEN  3
+
+/* One chinese can have multiple pinyin spell (maximum 6).
+ * If the src is 2-length chinese, first one has 2 pinyin spells and second one has 3 pinyin spells,
+ * then the size will be 6 (2*3) and there are 6 pinyin spell names.
+ * If src is very long and it has many chinese characters which have multiple pinyin spell,
+ * the size can be too many. So, we limit to support total 3 multiple pinyin spell.
+ * If exceeded 3 length, then we will pick first one.
+ */
+int ctsvc_convert_chinese_to_pinyin(const char *src, pinyin_name_s **name, int *size)
+{
+       UChar   temp_result[strlen(src)+1];
+       int     count = 0, len=0, total_count=0;
+       int ret, i, j;
+       int multi_pinyin_count = 0;
+       UErrorCode status = 0;
+       pinyin_name_s *temp_name = NULL;
+
+       *size = 0;
+
+       RETVM_IF(src==NULL, CONTACTS_ERROR_SYSTEM, "src is NULL");
+       RETVM_IF(!*src, CONTACTS_ERROR_SYSTEM, "*src is NULL");
+
+       u_strFromUTF8(temp_result, array_sizeof(temp_result), NULL, src, -1, &status);
+       if (U_FAILURE(status)){
+               CTS_ERR("u_strFromUTF8 Failed(%s)", u_errorName(status));
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       len = u_strlen(temp_result);
+
+       char spell[len][CHINESE_DUOYINZI_MAX_COUNT][CHINESE_PINYIN_SPELL_MAX_LEN];
+       int pinyin_spell_count[len];
+       memset(spell, 0x0, len * CHINESE_DUOYINZI_MAX_COUNT * CHINESE_PINYIN_SPELL_MAX_LEN);
+
+       for (count = 0; count < len; count++) {
+               if (__ctsvc_is_chinese(&temp_result[count])) {
+                       ret = __ctsvc_get_pinyinspell(temp_result[count], spell[count]);
+                       RETVM_IF(ret < CONTACTS_ERROR_NONE, CONTACTS_ERROR_SYSTEM, "__ctsvc_get_pinyinspell() Failed(%d)", ret);
+                       if (multi_pinyin_count >= CTSVC_CHINESE_MULTIPLE_PINYIN_MAX_LEN)
+                               ret = 1;
+
+                       pinyin_spell_count[count] = ret;
+
+                       if(total_count==0)
+                               total_count = ret;
+                       else
+                               total_count *= ret;
+                       if (ret > 1)
+                               multi_pinyin_count ++;
+               }
+               else {
+                       UChar temp[2];
+                       int temp_size;
+
+                       temp[0] = temp_result[count];
+                       temp[1] = 0x00;
+                       u_strToUTF8(spell[count][0], 10, &temp_size, temp, -1, &status);
+                       RETVM_IF(U_FAILURE(status), CONTACTS_ERROR_SYSTEM, "u_strToUTF8() Failed(%s)", u_errorName(status));
+                       spell[count][0][temp_size]='\0';
+                       pinyin_spell_count[count] = 1;
+               }
+       }
+
+       *size = total_count;
+       temp_name = calloc(total_count, sizeof(pinyin_name_s));
+       RETVM_IF(temp_name == NULL, CONTACTS_ERROR_OUT_OF_MEMORY,"calloc Failed()");
+
+       int repeat = 1;
+       int name_len[total_count];
+       int initial_len[total_count];
+       int pinyin_name_len = sizeof(char) * ((len + 2) * CHINESE_PINYIN_SPELL_MAX_LEN);
+       int pinyin_initial_len = sizeof(char) * (len * 5 + 1);
+       for(i=0; i < count ; i++) {
+               for(j=0;j<total_count;j++) {
+                       int index = (j/repeat) %pinyin_spell_count[i];
+
+                       if (i==0) {
+                               name_len[j] = 0;
+                               initial_len[j] = 0;
+
+                               temp_name[j].pinyin_name = calloc(1, pinyin_name_len);
+                               temp_name[j].pinyin_initial = calloc(1, pinyin_initial_len);
+                       }
+
+                       if (spell[i][index][0]) {
+                               if(temp_name[j].pinyin_name[0])
+                                       name_len[j] += snprintf(temp_name[j].pinyin_name + name_len[j], pinyin_name_len - name_len[j], " ");
+
+                               name_len[j] += snprintf(temp_name[j].pinyin_name + name_len[j], pinyin_name_len - name_len[j],
+                                                               "%s", spell[i][index]);
+
+                               int char_len = ctsvc_check_utf8(spell[i][index][0]);
+                               if (char_len == 1)
+                                       initial_len[j] += snprintf(temp_name[j].pinyin_initial + initial_len[j], pinyin_initial_len - initial_len[j],
+                                                                       "%c", spell[i][index][0]);
+                               else if (0 < char_len) {
+                                       char temp[10];
+                                       snprintf(temp, sizeof(temp), "%s", spell[i][index]);
+                                       temp[char_len] ='\0';
+                                       initial_len[j] += snprintf(temp_name[j].pinyin_initial + initial_len[j], pinyin_initial_len - initial_len[j],
+                                                                       "%s", temp);
+                               }
+                       }
+               }
+               repeat *= pinyin_spell_count[i];
+       }
+
+       *name = temp_name;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+void ctsvc_pinyin_free(pinyin_name_s *pinyinname, int size)
+{
+       int i;
+       if (pinyinname == NULL)
+               return;
+
+       for (i=0;i<size;i++) {
+               free(pinyinname[i].pinyin_initial);
+               free(pinyinname[i].pinyin_name);
+       }
+       free(pinyinname);
+}
+
diff --git a/native/ctsvc_localize_ch.h b/native/ctsvc_localize_ch.h
new file mode 100755 (executable)
index 0000000..a204578
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CTSVC_LOCALIZE_CH_H__
+#define __TIZEN_SOCIAL_CTSVC_LOCALIZE_CH_H__
+
+#define CHINESE_PINYIN_SPELL_MAX_LEN   15
+
+typedef struct {
+       char *pinyin_initial;
+       char *pinyin_name;
+} pinyin_name_s;
+
+int ctsvc_convert_chinese_to_pinyin(const char *src, pinyin_name_s **name, int *size);
+void ctsvc_pinyin_free(pinyin_name_s *pinyinname, int size);
+
+bool ctsvc_has_chinese(const char *src);
+
+#endif // __TIZEN_SOCIAL_CTSVC_LOCALIZE_CH_H__
diff --git a/native/ctsvc_localize_jp.c b/native/ctsvc_localize_jp.c
new file mode 100644 (file)
index 0000000..2953824
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <unicode/ustring.h>
+#include <unicode/unorm.h>
+#include <unicode/ucol.h>
+#include <unicode/uset.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+
+#include "ctsvc_internal.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_localize.h"
+#include "ctsvc_localize_utils.h"
+
+#include "ctsvc_localize_jp.h"
+
+/* japanese - katakana */
+#define CTSVC_JAPANESE_KATAKANA_START  0x30A0
+#define CTSVC_JAPANESE_KATAKANA_END    0x30FF
+
+/* japanese - katakana phonetic extensions */
+#define CTSVC_JAPANESE_KATAKANA_PHONETIC_EXTENSIONS_START 0x31F0
+#define CTSVC_JAPANESE_KATAKANA_PHONETIC_EXTENSIONS_END 0x31FF
+
+/* japanese - halfwidth and fullwidth forms */
+#define CTSVC_JAPANESE_HALFWIDTH_AND_FULLWIDTH_FORMS_START 0xFF00
+#define CTSVC_JAPANESE_HALFWIDTH_AND_FULLWIDTH_FORMS_END 0xFFEF
+
+/* japanese - halfwidth and fullwidth forms */
+#define CTSVC_ASCII_HALFWIDTH_AND_FULLWIDTH_FORMS_START 0xFF01
+#define CTSVC_ASCII_HALFWIDTH_AND_FULLWIDTH_FORMS_END 0xFF5E
+
+/* japanese - hiragana */
+#define CTSVC_JAPANESE_HIRAGANA_START 0x3040
+#define CTSVC_JAPANESE_HIRAGANA_END 0x309F
+
+
+static const unsigned char japanese_halfwidth_katakana_to_hiragana[] = { // 0xff66 - 0xff9d
+       0x92, 0x41, 0x43, 0x45, 0x47, 0x49, 0x83, 0x85, 0x87, 0x63,
+       0x00, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4B, 0x4D, 0x4F, 0x51,
+       0x53, 0x55, 0x57, 0x59, 0x5B, 0x5D, 0x5F, 0x61, 0x64, 0x66,
+       0x68, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x72, 0x75, 0x78,
+       0x7B, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x84, 0x86, 0x88, 0x89,
+       0x8A, 0x8B, 0x8C, 0x8D, 0x8F, 0x93};
+
+static const unsigned char japanese_halfwidth_katakana_sonant_to_hiragana[] = { // 0xff76 - 0xff89
+       0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A, 0x5C, 0x5E,
+       0x60, 0x62, 0x65, 0x67, 0x69, 0x70, 0x73, 0x76, 0x79, 0x7C};
+
+static const unsigned char japanese_halfwidth_katakana_half_dullness_to_hiragana[] = { // 0xff8a - 0xff8e
+       0x71, 0x74, 0x77, 0x7A, 0x7D};
+
+
+static inline bool is_japanese(UChar src)
+{
+       if (CTSVC_COMPARE_BETWEEN(CTSVC_JAPANESE_KATAKANA_START, src, CTSVC_JAPANESE_KATAKANA_END )
+                       || CTSVC_COMPARE_BETWEEN(CTSVC_JAPANESE_KATAKANA_PHONETIC_EXTENSIONS_START, src, CTSVC_JAPANESE_KATAKANA_PHONETIC_EXTENSIONS_END )
+                       || CTSVC_COMPARE_BETWEEN(CTSVC_JAPANESE_HALFWIDTH_AND_FULLWIDTH_FORMS_START, src, CTSVC_JAPANESE_HALFWIDTH_AND_FULLWIDTH_FORMS_END )
+                       || CTSVC_COMPARE_BETWEEN(CTSVC_JAPANESE_HIRAGANA_START, src, CTSVC_JAPANESE_HIRAGANA_END ))
+               return true;
+       else
+               return false;
+}
+
+
+int ctsvc_convert_japanese_to_hiragana_unicode(UChar *src, UChar *dest, int dest_size)
+{
+       int i, j = 0, len = 0;
+
+       len = u_strlen(src);
+
+       for(i = 0; i < len; i++) {
+               int unicode_value1 = 0;
+               int unicode_value2 = 0;
+
+               unicode_value2 = (0xFF & (src[i]));
+
+               if (CTSVC_COMPARE_BETWEEN(CTSVC_JAPANESE_KATAKANA_START, src[i], CTSVC_JAPANESE_KATAKANA_END)) {
+                       unicode_value1 = 0x30;
+                       if ((unicode_value2 >= 0xa1 && unicode_value2 <= 0xef )
+                                       || (unicode_value2 == 0xF2 || unicode_value2 == 0xF3) ) {
+                               unicode_value2 -= 0x60;
+                               dest[j] = unicode_value1 << 8 | unicode_value2;
+                       }
+                       else {
+                               dest[j] = src[i];
+                       }
+               }
+               else if (CTSVC_COMPARE_BETWEEN(CTSVC_JAPANESE_HALFWIDTH_AND_FULLWIDTH_FORMS_START,
+                                                       src[i], CTSVC_JAPANESE_HALFWIDTH_AND_FULLWIDTH_FORMS_END)) {
+                       unicode_value1 = 0x30;
+                       if (i+1 < len && (0xFF & (src[i+1])) == 0x9E
+                                       && unicode_value2 >= 0x76 && unicode_value2 <= 0x89) {
+                               unicode_value2 = japanese_halfwidth_katakana_sonant_to_hiragana[unicode_value2 - 0x76];
+                               dest[j] = unicode_value1 << 8 | unicode_value2;
+                               i++;
+                       }
+                       else if (i+1 < len && (0xFF & (src[i])) == 0x9F
+                                       && unicode_value2 >= 0x8a && unicode_value2 <= 0x8e) {
+                               unicode_value2 = japanese_halfwidth_katakana_half_dullness_to_hiragana[unicode_value2 - 0x8a];
+                               dest[j] = unicode_value1 << 8 | unicode_value2;
+                               i++;
+                       }
+                       else if (unicode_value2 >= 0x66 && unicode_value2 <= 0x9d) {
+                               unicode_value2 = japanese_halfwidth_katakana_to_hiragana[unicode_value2 - 0x66];
+                               dest[j] = unicode_value1 << 8 | unicode_value2;
+                       }
+                       else {
+                               dest[j] = src[i];
+                       }
+               }
+               else if (CTSVC_COMPARE_BETWEEN(CTSVC_ASCII_HALFWIDTH_AND_FULLWIDTH_FORMS_START,
+                                                       src[i], CTSVC_ASCII_HALFWIDTH_AND_FULLWIDTH_FORMS_END)) {
+                       unicode_value1 = 0x00;
+                       unicode_value2 = unicode_value2 - 0x20;
+                       dest[j] = unicode_value1 << 8 | unicode_value2;
+               } else {
+                       dest[j] = src[i];
+               }
+               j++;
+       }
+
+       dest[j] = 0x0;
+
+       return j;
+}
+
+int ctsvc_convert_japanese_to_hiragana(const char *src, char **dest)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       UChar *tmp_result = NULL;
+       UChar *result = NULL;
+       UErrorCode status = 0;
+       int32_t size;
+
+       u_strFromUTF8(NULL, 0, &size, src, strlen(src), &status);
+       if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) {
+               CTS_ERR("u_strFromUTF8 to get the dest length Failed(%s)", u_errorName(status));
+               return CONTACTS_ERROR_SYSTEM;
+       }
+       status = U_ZERO_ERROR;
+       tmp_result = calloc(1, sizeof(UChar) * (size + 1));
+       if (NULL == tmp_result) {
+               CTS_ERR("calloc() return NULL");
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       u_strFromUTF8(tmp_result, size + 1, NULL, src, -1, &status);
+       if (U_FAILURE(status)){
+               CTS_ERR("u_strFromUTF8 Failed(%s)", u_errorName(status));
+               free(tmp_result);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       result = calloc(1, sizeof(UChar) * (size + 1));
+       if (NULL == result) {
+               CTS_ERR("calloc() return NULL");
+               free(tmp_result);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       ctsvc_convert_japanese_to_hiragana_unicode(tmp_result, result, size + 1 );
+
+       u_strToUTF8(NULL, 0, &size, result, -1, &status);
+       if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) {
+               CTS_ERR("u_strToUTF8 to get the dest length Failed(%s)", u_errorName(status));
+               free(result);
+               free(tmp_result);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       status = U_ZERO_ERROR;
+       *dest = calloc(1, sizeof(char)*(size+1));
+       if (NULL == *dest) {
+               CTS_ERR("calloc() return NULL");
+               free(result);
+               free(tmp_result);
+               return CONTACTS_ERROR_OUT_OF_MEMORY;
+       }
+
+       u_strToUTF8(*dest, size + 1, &size, result, -1, &status);
+       if (U_FAILURE(status) ) {
+               CTS_ERR("u_strToUTF8 Failed(%s)", u_errorName(status));
+               free(result);
+               free(tmp_result);
+               free(*dest);
+               *dest = NULL;
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       return ret;
+}
+
diff --git a/native/ctsvc_localize_jp.h b/native/ctsvc_localize_jp.h
new file mode 100644 (file)
index 0000000..ec76d77
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CTSVC_LOCALIZE_JAPAN_H__
+#define __TIZEN_SOCIAL_CTSVC_LOCALIZE_JAPAN_H__
+
+int ctsvc_convert_japanese_to_hiragana(const char *src, char **dest);
+int ctsvc_convert_japanese_to_hiragana_unicode(UChar *src, UChar *dest, int dest_size);
+
+#endif         //__TIZEN_SOCIAL_CTSVC_LOCALIZE_JAPAN_H__
\ No newline at end of file
diff --git a/native/ctsvc_localize_kor.c b/native/ctsvc_localize_kor.c
new file mode 100644 (file)
index 0000000..3b1a36b
--- /dev/null
@@ -0,0 +1,443 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <unicode/ustring.h>
+#include <unicode/unorm.h>
+#include <unicode/ucol.h>
+#include <unicode/uset.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+
+#include "ctsvc_internal.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_localize.h"
+#include "ctsvc_localize_utils.h"
+
+#include "ctsvc_localize_kor.h"
+
+
+
+/* korean -Hangul Jamo extended A*/
+#define CTSVC_JAMO_A_START (UChar)0xA960
+#define CTSVC_JAMO_A_END (UChar)0xA97F
+
+/* korean -Hangul Jamo extended B*/
+#define CTSVC_JAMO_B_START (UChar)0xD7B0
+#define CTSVC_JAMO_B_END (UChar)0xD7FF
+
+/* korean -Hangul Compatability */
+#define CTSVC_HAN_C_START (UChar)0x3130
+#define CTSVC_HAN_C_END (UChar)0x318F
+
+/* korean -Hangul halfwidth */
+#define CTSVC_HAN_HALF_START (UChar)0xFFA0
+#define CTSVC_HAN_HALF_END (UChar)0xFFDC
+
+/* korean -Hangul Syllables */
+#define CTSVC_HAN_SYLLABLES_START (UChar)0xAC00
+#define CTSVC_HAN_SYLLABLES_END (UChar)0xD7A3
+
+
+static const char hangul_compatibility_choseong[] = {
+       0x31, 0x32, 0x34, 0x37, 0x38, 0x39, 0x40, 0x41,
+       0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+       0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x65, 0x66, 0x6E,
+       0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+       0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80,
+       0x81, 0x84, 0x85, 0x86, 0x00};
+
+static const unsigned char hangul_jamo_choseong[] = {
+       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x1A, 0x06, 0x07,           // to choseong 0x1100~0x115F
+       0x08, 0x21, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+       0x10, 0x11, 0x12, 0x14, 0x15, 0x1C, 0x1D, 0x1E, 0x20,
+       0x22, 0x23, 0x27, 0x29, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+       0x32, 0x36, 0x40, 0x47, 0x4C, 0x57, 0x58, 0x59, 0x00};
+
+static const char hangul_compatibility_jungseong[] = {
+       0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,
+       0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E,
+       0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x87, 0x88,
+       0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x00};
+
+static const unsigned char hangul_jamo_jungseong[] = {
+       0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,   // to jungseong 0x1160~0x11A7
+       0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
+       0x73, 0x74, 0x75, 0x60, 0x84, 0x85, 0x88, 0x91, 0x92,
+       0x94, 0x9E, 0xA1, 0x00};
+
+static const char hangul_compatibility_jongseong[] = {
+       0x33, 0x35, 0x36, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E,
+       0x3F, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
+       0x6F, 0x70, 0x82, 0x83, 0x00};
+
+static const unsigned char hangul_jamo_jongseong[] = {
+       0xAA, 0xAC, 0xAD, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5,   // to jongseong 0x11A8~0x11FF
+       0xC7, 0xC8, 0xCC, 0xCE, 0xD3, 0xD7, 0xD9, 0xDF, 0xF1, 0xF2, 0x00};
+
+static inline bool is_chosung(UChar src)
+{
+       int unicode_value1 = 0;
+       int unicode_value2 = 0;
+
+       unicode_value1 = (0xFF00 & (src)) >> 8;
+       unicode_value2 = (0xFF & (src));
+
+       if (unicode_value1 == 0x31
+                       && (unicode_value2 >= 0x30 && unicode_value2 <= 0x4e)) //compatiblility jame
+               return true;
+
+       if (unicode_value1 == 0xA9
+                       && (unicode_value2 >= 0x60 && unicode_value2 <= 0x7C))//jamo Extended-A
+               return true;
+
+       if (unicode_value1 == 0x11
+                       && (unicode_value2 >= 0x00 && unicode_value2 <= 0x5E))//jamo
+               return true;
+
+       return false;
+}
+
+bool ctsvc_is_hangul(UChar src)
+{
+       if ((0x1100 == (src & 0xFF00))       /* korean -Hangul Jamo*/
+                       || CTSVC_COMPARE_BETWEEN(CTSVC_JAMO_A_START, src, CTSVC_JAMO_A_END)
+                       || CTSVC_COMPARE_BETWEEN(CTSVC_JAMO_B_START, src, CTSVC_JAMO_B_END)
+                       || CTSVC_COMPARE_BETWEEN(CTSVC_HAN_C_START, src, CTSVC_HAN_C_END)
+                       || CTSVC_COMPARE_BETWEEN(CTSVC_HAN_HALF_START, src, CTSVC_HAN_HALF_END)
+                       || CTSVC_COMPARE_BETWEEN(CTSVC_HAN_SYLLABLES_START, src, CTSVC_HAN_SYLLABLES_END))
+               return true;
+       else
+               return FALSE;
+}
+
+
+void ctsvc_hangul_compatibility2jamo(UChar *src)
+{
+       int unicode_value1 = 0;
+       int unicode_value2 = 0;
+
+       unicode_value1 = (0xFF00 & (*src)) >> 8;
+       unicode_value2 = (0xFF & (*src));
+
+       /* korean -Hangul Jamo halfwidth*/
+       if (CTSVC_COMPARE_BETWEEN(CTSVC_HAN_HALF_START, *src, CTSVC_HAN_HALF_END)) {
+               unicode_value1 = 0x31;
+
+               if (unicode_value2 < 0xBF)
+                       unicode_value2 -= 0x70;
+               else if (unicode_value2 < 0xC8)
+                       unicode_value2 -= 0x73;
+               else if (unicode_value2 < 0xD0)
+                       unicode_value2 -= 0x75;
+               else if (unicode_value2 < 0xD8)
+                       unicode_value2 -= 0x77;
+               else
+                       unicode_value2 -= 0x79;
+
+               (*src) = unicode_value1 << 8 | unicode_value2;
+       }
+
+       if (CTSVC_COMPARE_BETWEEN(CTSVC_HAN_C_START, *src, CTSVC_HAN_C_END)) {
+               char *pos;
+               if (NULL != (pos = strchr(hangul_compatibility_choseong, unicode_value2))) {
+                       unicode_value1 = 0x11;
+                       unicode_value2 = hangul_jamo_choseong[pos - hangul_compatibility_choseong];
+                       (*src) = unicode_value1 << 8 | unicode_value2;
+               }
+               else if (NULL != (pos = strchr(hangul_compatibility_jungseong, unicode_value2))) {
+                       unicode_value1 = 0x11;
+                       unicode_value2 = hangul_jamo_jungseong[pos - hangul_compatibility_jungseong];
+                       (*src) = unicode_value1 << 8 | unicode_value2;
+               }
+               else if (NULL != (pos = strchr(hangul_compatibility_jongseong, unicode_value2))) {
+                       unicode_value1 = 0x11;
+                       unicode_value2 = hangul_jamo_jongseong[pos - hangul_compatibility_jongseong];
+                       (*src) = unicode_value1 << 8 | unicode_value2;
+               }
+       }
+}
+
+int ctsvc_get_chosung(const char *src, char *dest, int dest_size)
+{
+       int32_t size;
+       UErrorCode status = 0;
+       UChar tmp_result[10];
+       UChar result[10];
+       int chosung_len=0, count = 0, i=0, j=0;
+       int char_len = 0;
+       int str_len = strlen(src);
+       char temp[dest_size];
+
+       for (i=0;i<str_len;i+=char_len) {
+               char char_src[10];
+               char_len = ctsvc_check_utf8(src[i]);
+               RETVM_IF(char_len <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "check_utf8 failed");
+
+               memcpy(char_src, &src[i], char_len);
+               char_src[char_len] = '\0';
+
+               u_strFromUTF8(tmp_result, array_sizeof(tmp_result), NULL, char_src, -1, &status);
+               RETVM_IF(U_FAILURE(status), CONTACTS_ERROR_SYSTEM,
+                               "u_strFromUTF8() Failed(%s)", u_errorName(status));
+
+               u_strToUpper(tmp_result, array_sizeof(tmp_result), tmp_result, -1, NULL, &status);
+               RETVM_IF(U_FAILURE(status), CONTACTS_ERROR_SYSTEM,
+                               "u_strToLower() Failed(%s)", u_errorName(status));
+
+               size = unorm_normalize(tmp_result, -1, UNORM_NFD, 0,
+                               (UChar *)result, array_sizeof(result), &status);
+               RETVM_IF(U_FAILURE(status), CONTACTS_ERROR_SYSTEM,
+                               "unorm_normalize(%s) Failed(%s)", src, u_errorName(status));
+               ctsvc_extra_normalize(result, size);
+               u_strToUTF8(temp, dest_size, &size, result, -1, &status);
+               RETVM_IF(U_FAILURE(status), CONTACTS_ERROR_SYSTEM,
+                               "u_strToUTF8() Failed(%s)", u_errorName(status));
+               chosung_len = ctsvc_check_utf8(temp[0]);
+               RETVM_IF(chosung_len <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "check_utf8 failed");
+               memcpy(&dest[j], temp, chosung_len);
+               j += chosung_len;
+               count++;
+       }
+
+       dest[j] = '\0';
+
+       return count;
+}
+
+int ctsvc_get_korean_search_pattern(const char *src, char *dest, int dest_size)
+{
+       int32_t size;
+       UErrorCode status = 0;
+       UChar tmp_result[10];
+       UChar result[10];
+       int i=0, j=0, count=0;
+       int char_len = 0;
+       int str_len = strlen(src);
+
+       for (i=0;i<str_len;i+=char_len) {
+               char char_src[10];
+               char_len = ctsvc_check_utf8(src[i]);
+               RETVM_IF(char_len <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "check_utf8 failed");
+               if (char_len == 1 && src[i] == ' ')
+                       continue;
+
+               memcpy(char_src, &src[i], char_len);
+               char_src[char_len] = '\0';
+
+               u_strFromUTF8(tmp_result, array_sizeof(tmp_result), NULL, char_src, -1, &status);
+               RETVM_IF(U_FAILURE(status), CONTACTS_ERROR_SYSTEM,
+                               "u_strFromUTF8() Failed(%s)", u_errorName(status));
+
+               if (is_chosung(tmp_result[0]))
+               {
+                       ctsvc_hangul_compatibility2jamo(tmp_result);
+
+                       u_strToUTF8(&dest[j], dest_size - j, &size, tmp_result, -1, &status);
+                       RETVM_IF(U_FAILURE(status), CONTACTS_ERROR_SYSTEM,
+                                       "u_strToUTF8() Failed(%s)", u_errorName(status));
+                       j += size;
+                       dest[j] = '*';
+                       j++;
+               }
+               else {
+                       u_strToUpper(tmp_result, array_sizeof(tmp_result), tmp_result, -1, NULL, &status);
+                       RETVM_IF(U_FAILURE(status), CONTACTS_ERROR_SYSTEM,
+                                       "u_strToUpper() Failed(%s)", u_errorName(status));
+                       size = unorm_normalize(tmp_result, -1, UNORM_NFD, 0,
+                                       (UChar *)result, array_sizeof(result), &status);
+                       RETVM_IF(U_FAILURE(status), CONTACTS_ERROR_SYSTEM,
+                                       "unorm_normalize(%s) Failed(%s)", src, u_errorName(status));
+                       ctsvc_extra_normalize(result, size);
+                       u_strToUTF8(&dest[j], dest_size - j, &size, result, -1, &status);
+                       RETVM_IF(U_FAILURE(status), CONTACTS_ERROR_SYSTEM,
+                                       "u_strToUTF8() Failed(%s)", u_errorName(status));
+                       j += size;
+               }
+               count++;
+       }
+
+       dest[j] = '\0';
+       return count;
+}
+
+bool ctsvc_is_chosung(const char *src)
+{
+       int char_len = 0;
+
+       char_len = ctsvc_check_utf8(src[0]);
+       if (char_len < 0) return false;         // invalid value
+
+       if (char_len == 3) {
+               unsigned short tmp;
+
+               tmp = (src[1] << 8) | src[2];
+               if (((char)0xE1 == src[0] && CTSVC_COMPARE_BETWEEN(0x8480, tmp, 0x859F)) /* korean -Hangul Jamo*/
+                               || ((char)0xE3 == src[0] && CTSVC_COMPARE_BETWEEN(0x84B1, tmp, 0x858E)) /* korean -Hangul Compatibility Jamo */
+                               || ((char)0xEA == src[0] && CTSVC_COMPARE_BETWEEN(0xA5A0, tmp, 0xA5BC))) /* korean -Hangul Jamo extended A*/
+                       return true;
+       }
+       return false;
+}
+
+bool ctsvc_has_chosung(const char *src)
+{
+       int  i=0;
+       int char_len = 0;
+       int str_len = strlen(src);
+
+       for (i=0;i<str_len;i+=char_len) {
+               char_len = ctsvc_check_utf8(src[i]);
+               if (ctsvc_is_chosung(&(src[i])))
+                       return true;
+       }
+       return false;
+}
+
+static bool __ctsvc_is_hangul(const char *src)
+{
+       int char_len = 0;
+
+       char_len = ctsvc_check_utf8(src[0]);
+       if (char_len <= 0) return false;                // invalid value
+
+       if (char_len == 3) {
+               switch(src[0]) {
+               // Hangul Jamo : 0x1100 ~ 0x11FF
+                       // e1 84 80 ~ e1 87 bf
+               case 0xE1:
+                       switch(src[1]) {
+                       case 0x84 ... 0x87:
+                               if (0x80 <= src[2] && src[2] <= 0xBF)
+                                       return true;
+                               else return false;
+                       default :
+                               return false;
+                       }
+                       break;
+
+               // Hangul Compatibility Jamo : 0x3130 ~ 0x318F
+                       // e3 84 b0 ~ e3 84 bf
+                       // e3 85 80 ~ e3 85 bf
+                       // e3 86 80 ~ e3 86 8f
+               case 0xE3:
+                       switch(src[1]) {
+                       case 0x84:
+                               if (0xB0 <= src[2] && src[2] <= 0xBF)
+                                       return true;
+                               else return false;
+                       case 0x85:
+                               if (0x80 <= src[2] && src[2] <= 0xBF)
+                                       return true;
+                               else return false;
+                       case 0x86:
+                               if (0x80 <= src[2] && src[2] <= 0x8F)
+                                       return true;
+                               else return false;
+                       default :
+                               return false;
+                       }
+                       break;
+
+               // Hangul Jamo Extended A : 0xA960 ~ 0xA97F
+                       // ea a5 a0  ~ ea a5 bf
+               // Hangul syllables : 0xAC00 ~ 0xD7AF
+                       // ea b0 80 ~ ea bf bf
+               case 0xEA:
+                       switch(src[1]) {
+                       case 0xA5:
+                               if (0xA0 <= src[2] && src[2] <= 0xBF)
+                                       return true;
+                               else return false;
+                       case 0xB0 ... 0xBF:
+                               if (0x80 <= src[2] && src[2] <= 0xBF)
+                                       return true;
+                               else return false;
+                       default :
+                               return false;
+                       }
+                       break;
+
+               // Hangul syllables : 0xAC00 ~ 0xD7AF
+                       // eb 80 80 ~ eb bf bf
+                       // ec 80 80 ~ ec bf bf
+               case 0xEB ... 0xEC:
+                       switch(src[1]) {
+                       case 0x80 ... 0xBF:
+                               if (0x80 <= src[2] && src[2] <= 0xBF)
+                                       return true;
+                               else return false;
+                               break;
+                       default :
+                               return false;
+                       }
+                       break;
+
+               // Hangul syllables : 0xAC00 ~ 0xD7AF
+                       // ed 80 80 ~ ed 9e af
+               // Hangul Jamo Extended B : 0xD7B0 ~ 0xD7FF
+                       // ed 9e b0 ~ ed 9f bf
+               case 0xED:
+                       switch(src[1]) {
+                       case 0x80 ... 0x9F:
+                               if (0x80 <= src[2] && src[2] <= 0xBF)
+                                       return true;
+                               else return false;
+                       default :
+                               return false;
+                       }
+                       break;
+
+               // Hangul halfwidth : 0xFFA0 ~ 0xFFDC
+                       // ef be a0 ~ ef bf 9c
+               case 0xEF:
+                       switch(src[1]) {
+                       case 0xBE:
+                               if (0xA0 <= src[2] && src[2] <= 0xBF)
+                                       return true;
+                               else return false;
+                       case 0xbf:
+                               if (0x80 <= src[2] && src[2] <= 0x9C)
+                                       return true;
+                               else return false;
+                       default :
+                               return false;
+                       }
+                       break;
+               default:
+                       return false;
+               }
+       }
+       return false;
+}
+
+bool ctsvc_has_korean(const char *src)
+{
+       int  i=0;
+       int char_len = 0;
+       int str_len = strlen(src);
+
+       for (i=0;i<str_len;i+=char_len) {
+               char_len = ctsvc_check_utf8(src[i]);
+               RETV_IF(CONTACTS_ERROR_INVALID_PARAMETER == char_len, false);
+               if (__ctsvc_is_hangul(&(src[i])))
+                       return true;
+       }
+       return false;
+}
+
old mode 100755 (executable)
new mode 100644 (file)
similarity index 57%
rename from src/cts-inotify.h
rename to native/ctsvc_localize_kor.h
index 5d092f7..bbe0775
@@ -3,8 +3,6 @@
  *
  * 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
  * limitations under the License.
  *
  */
-#ifndef __CTS_INOTIFY_H__
-#define __CTS_INOTIFY_H__
 
-int cts_inotify_init(void);
-void cts_inotify_close(void);
-int cts_inotify_subscribe(const char *path, void (*cb)(void *), void *data);
-int cts_inotify_unsubscribe(const char *path, void (*cb)(void *));
-int cts_inotify_unsubscribe_with_data(const char *path,
-               void (*cb)(void *), void *user_data);
+#ifndef __TIZEN_SOCIAL_CTSVC_LOCALIZE_KOR_H__
+#define __TIZEN_SOCIAL_CTSVC_LOCALIZE_KOR_H__
 
+int ctsvc_get_chosung(const char *src, char *dest, int dest_size);
+int ctsvc_get_korean_search_pattern(const char *src, char *dest, int dest_size);
+bool ctsvc_has_korean(const char *src);
+bool ctsvc_has_chosung(const char *src);
+bool ctsvc_is_chosung(const char *src);
+bool ctsvc_is_hangul(UChar src);
+void ctsvc_hangul_compatibility2jamo(UChar *src);
 
-#endif //__CTS_INOTIFY_H__
+#endif         //__TIZEN_SOCIAL_CTSVC_LOCALIZE_KOR_H__
diff --git a/native/ctsvc_normalize.c b/native/ctsvc_normalize.c
new file mode 100644 (file)
index 0000000..be663cb
--- /dev/null
@@ -0,0 +1,498 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <ctype.h>
+#include <unicode/ulocdata.h>
+#include <unicode/ustring.h>
+#include <unicode/unorm.h>
+#include <unicode/ucol.h>
+#include <unicode/uset.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_localize.h"
+#include "ctsvc_localize_utils.h"
+
+#define CTSVC_COMBINING_DIACRITICAL_MARKS_START 0x0300
+#define CTSVC_COMBINING_DIACRITICAL_MARKS_END  0x036f
+
+typedef struct {
+       UChar letter;
+       char start;
+       char end;
+}hiragana_group_letter;
+
+static hiragana_group_letter hiragana_group[13] = {
+       {0x3042, 0x41, 0x4a}, // ぁ    あ     ぃ     い     ぅ     う     ぇ     え     ぉ     お
+       {0x3042, 0x94, 0x94}, // ゔ
+       {0x304b, 0x4b, 0x54}, // か    が     き     ぎ     く     ぐ     け     げ     こ     ご
+       {0x304b, 0x95, 0x96}, // ゕ    ゖ
+       {0x3055, 0x55, 0x5e}, // さ    ざ     し     じ     す     ず     せ     ぜ     そ     ぞ
+       {0x305f, 0x5f, 0x69}, // た    だ     ち     ぢ     っ     つ     づ     て     で     と     ど
+       {0x306a, 0x6a, 0x6e}, // な    に     ぬ     ね     の
+       {0x306f, 0x6f, 0x7d}, // は    ば     ぱ     ひ     び     ぴ     ふ     ぶ     ぷ     へ     べ     ぺ     ほ     ぼ     ぽ
+       {0x307e, 0x7e, 0x82}, // ま    み     む     め     も
+       {0x3084, 0x83, 0x88}, // ゃ    や     ゅ     ゆ     ょ     よ
+       {0x3089, 0x89, 0x8d}, // ら    り     る     れ     ろ
+       {0x308f, 0x8e, 0x92}, // ゎ    わ
+       {0x3093, 0x93, 0x93}, // ゐ    ゑ     を
+};
+
+static int __ctsvc_remove_special_char(const char *src, char *dest, int dest_size)
+{
+       int s_pos=0, d_pos=0, char_type, src_size;
+
+       if (NULL == src) {
+               CTS_ERR("The parameter(src) is NULL");
+               dest[d_pos] = '\0';
+               return 0;
+       }
+       src_size = strlen(src);
+
+       while (src[s_pos] != 0) {
+               char_type = ctsvc_check_utf8(src[s_pos]);
+
+               if (0 < char_type && char_type < dest_size - d_pos && char_type <= src_size - s_pos) {
+                       memcpy(dest+d_pos, src+s_pos, char_type);
+                       d_pos += char_type;
+                       s_pos += char_type;
+               }
+               else {
+                       CTS_ERR("The parameter(src:%s) has invalid character set", src);
+                       dest[d_pos] = '\0';
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+
+       dest[d_pos] = '\0';
+       return d_pos;
+}
+
+static inline int __ctsvc_collation_str(const char *src, char **dest)
+{
+       int32_t size = 0;
+       UErrorCode status = U_ZERO_ERROR;
+       UChar *tmp_result = NULL;
+       UCollator *collator;
+
+       char *region = strdup(ctsvc_get_langset());
+       RETVM_IF(NULL == region, CONTACTS_ERROR_OUT_OF_MEMORY, "strdup() return NULL");
+
+       char *dot = strchr(region, '.');
+       if (dot)
+               *dot = '\0';
+
+       collator = ucol_open(region, &status);
+       if (U_FAILURE(status)){
+               CTS_ERR("ucol_open Failed(%s)", u_errorName(status));
+               free(region);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       // TODO: ucol_setAttribute is not called
+       if (U_FAILURE(status)){
+               CTS_ERR("ucol_setAttribute Failed(%s)", u_errorName(status));
+               free(region);
+               ucol_close(collator);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       u_strFromUTF8(NULL, 0, &size, src, strlen(src), &status);
+       if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) {
+               CTS_ERR("u_strFromUTF8 to get the dest length Failed(%s)", u_errorName(status));
+               free(region);
+               ucol_close(collator);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+       status = U_ZERO_ERROR;
+       tmp_result = calloc(1, sizeof(UChar) * (size + 1));
+       u_strFromUTF8(tmp_result, size + 1, NULL, src, -1, &status);
+       if (U_FAILURE(status)){
+               CTS_ERR("u_strFromUTF8 Failed(%s)", u_errorName(status));
+               free(region);
+               free(tmp_result);
+               ucol_close(collator);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       size = ucol_getSortKey(collator, tmp_result, -1, NULL, 0);
+       *dest = calloc(1, sizeof(uint8_t) * (size + 1));
+       size = ucol_getSortKey(collator, tmp_result, -1, (uint8_t *)*dest, size + 1);
+
+       ucol_close(collator);
+       free(tmp_result);
+       free(region);
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_collation_str(char *src, char **dest)
+{
+       int ret;
+       char temp[SAFE_STRLEN(src) + 1];
+
+       ret = __ctsvc_remove_special_char(src, temp, sizeof(temp));
+       WARN_IF(ret < CONTACTS_ERROR_NONE, "__ctsvc_remove_special_char() Failed(%d)", ret);
+
+       return __ctsvc_collation_str(temp, dest);
+}
+
+static int __ctsvc_normalize_str(const char *src, char **dest)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int32_t tmp_size = 100;
+       int32_t upper_size;
+       int32_t size = 100;
+       UErrorCode status = 0;
+       UChar *tmp_result = NULL;
+       UChar *tmp_upper = NULL;
+       UChar *result = NULL;
+
+       tmp_result = calloc(1, sizeof(UChar)*(tmp_size+1));
+       if (NULL == tmp_result) {
+               CTS_ERR("calloc() return NULL");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               goto DATA_FREE;
+       }
+       u_strFromUTF8(tmp_result, tmp_size + 1, &tmp_size, src, -1, &status);
+
+       if (status == U_BUFFER_OVERFLOW_ERROR) {
+               status = U_ZERO_ERROR;
+               free(tmp_result);
+               tmp_result = calloc(1, sizeof(UChar) * (tmp_size + 1));
+               if (NULL == tmp_result) {
+                       CTS_ERR("calloc() return NULL");
+                       ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                       goto DATA_FREE;
+               }
+               u_strFromUTF8(tmp_result, tmp_size + 1, NULL, src, -1, &status);
+               if (U_FAILURE(status)) {
+                       CTS_ERR("u_strFromUTF8()Failed(%s)", u_errorName(status));
+                       ret = CONTACTS_ERROR_SYSTEM;
+                       goto DATA_FREE;
+               }
+       }
+       else if (U_FAILURE(status)) {
+               CTS_ERR("u_strFromUTF8() Failed(%s)", u_errorName(status));
+               ret = CONTACTS_ERROR_SYSTEM;
+               goto DATA_FREE;
+       }
+
+       tmp_upper = calloc(1, sizeof(UChar)*(tmp_size+1));
+       if (NULL == tmp_upper) {
+               CTS_ERR("calloc() return NULL");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               goto DATA_FREE;
+       }
+
+       upper_size = u_strToUpper(tmp_upper, tmp_size+1, tmp_result, -1, NULL, &status);
+       if (status == U_BUFFER_OVERFLOW_ERROR) {
+               status = U_ZERO_ERROR;
+               free(tmp_upper);
+               tmp_upper = calloc(1, sizeof(UChar) * (upper_size + 1));
+               if (NULL == tmp_upper) {
+                       CTS_ERR("calloc() return NULL");
+                       ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                       goto DATA_FREE;
+               }
+
+               u_strFromUTF8(tmp_upper, upper_size + 1, NULL, src, -1, &status);
+               if (U_FAILURE(status)) {
+                       CTS_ERR("u_strFromUTF8()Failed(%s)", u_errorName(status));
+                       ret = CONTACTS_ERROR_SYSTEM;
+                       goto DATA_FREE;
+               }
+       }
+       else if (U_FAILURE(status)) {
+               CTS_ERR("u_strToUpper() Failed(%s)", u_errorName(status));
+               ret = CONTACTS_ERROR_SYSTEM;
+               goto DATA_FREE;
+       }
+
+       result = calloc(1, sizeof(UChar)*(size+1));
+       if (NULL == result) {
+               CTS_ERR("calloc() return NULL");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               goto DATA_FREE;
+       }
+
+       size = unorm_normalize(tmp_upper, -1, UNORM_NFD, 0,
+                       result, size+1, &status);
+       if (status == U_BUFFER_OVERFLOW_ERROR) {
+               status = U_ZERO_ERROR;
+               free(result);
+               result = calloc(1, sizeof(UChar)*(size + 1));
+               if (NULL == result) {
+                       CTS_ERR("calloc() return NULL");
+                       ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                       goto DATA_FREE;
+               }
+
+               unorm_normalize(tmp_upper, -1, UNORM_NFD, 0, result, size+1, &status);
+               if (U_FAILURE(status)) {
+                       CTS_ERR("unorm_normalize() Failed(%s)", u_errorName(status));
+                       ret = CONTACTS_ERROR_SYSTEM;
+                       goto DATA_FREE;
+               }
+       }
+       else if (U_FAILURE(status)) {
+               CTS_ERR("unorm_normalize() Failed(%s)", u_errorName(status));
+               ret = CONTACTS_ERROR_SYSTEM;
+               goto DATA_FREE;
+       }
+
+       ret = ctsvc_check_language(result);
+       ctsvc_extra_normalize(result, size);
+
+       // remove diacritical : U+3000 ~ U+034F
+       int i, j;
+       UChar *temp_result = NULL;
+       temp_result = calloc(1, sizeof(UChar)*(size+1));
+       if (NULL == temp_result) {
+               CTS_ERR("calloc() return NULL");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               goto DATA_FREE;
+       }
+       bool replaced = false;
+       for(i=0,j=0; i<size;i++) {
+               if (CTSVC_COMPARE_BETWEEN((UChar)CTSVC_COMBINING_DIACRITICAL_MARKS_START,
+                       result[i], (UChar)CTSVC_COMBINING_DIACRITICAL_MARKS_END)) {
+                       replaced = true;
+               }
+               else
+                       temp_result[j++] = result[i];
+       }
+
+       if (replaced) {
+               temp_result[j] = 0x0;
+               free(result);
+               result = temp_result;
+       }
+       else
+               free(temp_result);
+
+       u_strToUTF8(NULL, 0, &size, result, -1, &status);
+       status = U_ZERO_ERROR;
+       *dest = calloc(1, sizeof(char) * (size+1));
+       if (NULL == *dest) {
+               CTS_ERR("calloc() return NULL");
+               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+               goto DATA_FREE;
+       }
+
+       u_strToUTF8(*dest, size+1, NULL, result, -1, &status);
+       if (U_FAILURE(status)) {
+               CTS_ERR("u_strToUTF8() Failed(%s)", u_errorName(status));
+               ret = CONTACTS_ERROR_SYSTEM;
+               free(*dest);
+               *dest = NULL;
+               goto DATA_FREE;
+       }
+
+DATA_FREE:
+       free(tmp_result);
+       free(tmp_upper);
+       free(result);
+       return ret;
+}
+
+static int __ctsvc_convert_halfwidth_ascii_and_symbol(const char *src, UChar *dest, int dest_size, int* str_size)
+{
+       int i;
+       int32_t size = dest_size;
+       UErrorCode status = 0;
+
+       u_strFromUTF8(dest, dest_size, &size, src, strlen(src), &status);
+       if (U_FAILURE(status)) {
+               CTS_ERR("u_strFromUTF8() Failed(%s)", u_errorName(status));
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       *str_size = size;
+
+       // full width -> half width
+       for ( i=0; i < size; i++ ) {
+               // FF00 ~ FF60: Fullwidth ASCII variants
+               if (CTSVC_COMPARE_BETWEEN((UChar)0xFF00, dest[i], (UChar)0xFF60)) {
+                       int unicode_value1 = 0;
+                       int unicode_value2 = 0;
+                       unicode_value1 = 0x0;
+                       unicode_value2 = (0xFF & dest[i]) + 0x20;
+                       dest[i] = unicode_value1 << 8 | unicode_value2;
+               }
+               // FFE0~FFE6: Fullwidth symbol variants
+               else if (CTSVC_COMPARE_BETWEEN((UChar)0xFFE0, dest[i], (UChar)0xFFE6)) {
+                       if( dest[i] == (UChar)0xFFE0 )
+                       {
+                               dest[i] = (UChar)0x00A2;
+                       }
+                       else if( dest[i] == (UChar)0xFFE1 )
+                       {
+                               dest[i] = (UChar)0x00A3;
+                       }
+                       else if( dest[i] == (UChar)0xFFE2 )
+                       {
+                               dest[i] = (UChar)0x00AC;
+                       }
+                       else if( dest[i] == (UChar)0xFFE3 )
+                       {
+                               dest[i] = (UChar)0x00AF;
+                       }
+                       else if( dest[i] == (UChar)0xFFE4 )
+                       {
+                               dest[i] = (UChar)0x00A6;
+                       }
+                       else if( dest[i] == (UChar)0xFFE5 )
+                       {
+                               dest[i] = (UChar)0x00A5;
+                       }
+                       else if( dest[i] == (UChar)0xFFE6 )
+                       {
+                               dest[i] = (UChar)0x20A9;
+                       }
+                       else
+                       {
+
+                       }
+               }
+               else {
+
+               }
+
+       }
+
+       dest[size] = 0x00;
+       return CONTACTS_ERROR_NONE;
+}
+
+#define LARGE_BUFFER_SIZE 100
+
+int ctsvc_get_halfwidth_string(const char *src, char** dest, int* dest_size)
+{
+       UChar unicodes[LARGE_BUFFER_SIZE+1];
+       int ustr_size = 0;
+
+       if( __ctsvc_convert_halfwidth_ascii_and_symbol(src, unicodes, LARGE_BUFFER_SIZE, &ustr_size) != CONTACTS_ERROR_NONE )
+       {
+               CTS_ERR("convert to halfwidth failed! %s ", src);
+
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       UErrorCode status = 0;
+
+       // pre-flighting
+       int size = 0;
+       u_strToUTF8(NULL, 0, &size, unicodes, -1, &status);
+       status = U_ZERO_ERROR;
+       *dest = calloc(1, sizeof(char) * (size+1));
+
+       u_strToUTF8(*dest, size+1, dest_size, unicodes, ustr_size, &status);
+       if (U_FAILURE(status)) {
+               CTS_ERR("u_strToUTF8() Failed(%s)", u_errorName(status));
+
+               free(*dest);
+               *dest = NULL;
+               *dest_size = 0;
+
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_normalize_str(const char *src, char **dest)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       char temp[strlen(src) + 1];
+
+       ret = __ctsvc_remove_special_char(src, temp, strlen(src) + 1);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "__ctsvc_remove_special_char() Failed(%d)", ret);
+
+       ret = __ctsvc_normalize_str(temp, dest);
+       return ret;
+}
+
+static void __ctsvc_convert_japanese_group_letter(char *dest)
+{
+       int i, size, dest_len;
+       UErrorCode status = 0;
+       UChar tmp_result[2];
+       UChar result[2] = {0x00};
+       int unicode_value;
+
+       dest_len = strlen(dest) + 1;
+       u_strFromUTF8(tmp_result, array_sizeof(tmp_result), NULL, dest, -1, &status);
+       RETM_IF(U_FAILURE(status), "u_strFromUTF8() Failed(%s)", u_errorName(status));
+
+       unicode_value = (0xFF & (tmp_result[0]));
+
+       for(i=0; i < 13; i++) {
+               if (hiragana_group[i].start <= unicode_value
+                               && unicode_value <= hiragana_group[i].end)
+                       result[0] = hiragana_group[i].letter;
+       }
+
+       u_strToUTF8(dest, dest_len, &size, result, -1, &status);
+       RETM_IF(U_FAILURE(status), "u_strToUTF8() Failed(%s)", u_errorName(status));
+
+}
+
+static bool __ctsvc_check_range_out_index(const char src[])
+{
+       if(src[0] == 0xe2 && src[1] == 0x80 && src[2] == 0xa6){
+               return true;
+       }
+       return false;
+}
+
+int ctsvc_normalize_index(const char *src, char **dest)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       char first_str[10] = {0};
+       int length = 0;
+
+       if(first_str[0] == '\0' || __ctsvc_check_range_out_index(first_str)){
+               length = ctsvc_check_utf8(src[0]);
+               RETVM_IF(length <= 0, CONTACTS_ERROR_INTERNAL, "check_utf8 is failed");
+               memset(first_str,0x00, sizeof(first_str));
+               strncpy(first_str, src, length);
+               if (length != strlen(first_str)){
+                       CTS_ERR("length : %d, first_str : %s, strlne : %d", length, first_str, strlen(first_str));
+                       return CONTACTS_ERROR_INVALID_PARAMETER;
+               }
+       }
+       ret = __ctsvc_normalize_str(first_str, dest);
+       RETVM_IF(dest == NULL, ret, "__ctsvc_normalize_str is failed");
+
+       if ((*dest)[0] != '\0') {
+               length = ctsvc_check_utf8((*dest)[0]);
+               (*dest)[length] = '\0';
+       }
+
+       if (ret == CTSVC_LANG_JAPANESE) {
+               __ctsvc_convert_japanese_group_letter(*dest);
+       }
+
+       return ret;
+}
+
+
diff --git a/native/ctsvc_normalize.h b/native/ctsvc_normalize.h
new file mode 100644 (file)
index 0000000..c6c9b23
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CTSVC_NORMALIZE_H__
+#define __TIZEN_SOCIAL_CTSVC_NORMALIZE_H__
+
+int ctsvc_normalize_str(const char *src, char **dest);
+int ctsvc_collation_str(char *src, char **dest);
+int ctsvc_normalize_index(const char *src, char **dest);
+int ctsvc_get_halfwidth_string(const char *src, char** dest, int* dest_size);
+
+#endif /*  __TIZEN_SOCIAL_CTSVC_NORMALIZE_H__ */
diff --git a/native/ctsvc_notification.c b/native/ctsvc_notification.c
new file mode 100644 (file)
index 0000000..65654bf
--- /dev/null
@@ -0,0 +1,547 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include "contacts.h"
+#include "contacts_db_status.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_notify.h"
+#include "ctsvc_notification.h"
+
+static TLS bool contact_change = false;
+static TLS bool my_profile_change = false;
+static TLS bool phonelog_change = false;
+static TLS bool speed_change = false;
+static TLS bool addressbook_change = false;
+static TLS bool group_change = false;
+static TLS bool group_rel_change = false;
+static TLS bool person_change = false;
+static TLS bool activity_change = false;
+static TLS bool activity_photo_change = false;
+static TLS bool address_change = false;
+static TLS bool data_change = false;
+static TLS bool event_change = false;
+static TLS bool number_change = false;
+static TLS bool email_change = false;
+static TLS bool messenger_change = false;
+static TLS bool name_change = false;
+static TLS bool note_change = false;
+static TLS bool url_change = false;
+static TLS bool nickname_change = false;
+static TLS bool sdn_change = false;
+static TLS bool relationship_change = false;
+static TLS bool image_change = false;
+static TLS bool profile_change = false;
+static TLS bool company_change = false;
+
+void ctsvc_noti_publish_socket_initialize(void)
+{
+       int fd = open(CTSVC_NOTI_IPC_READY, O_TRUNC | O_RDWR);
+       if (0 <= fd)
+               close(fd);
+}
+
+static inline void __ctsvc_noti_publish_contact_change(void)
+{
+       int fd = open(CTSVC_NOTI_CONTACT_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               contact_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_my_profile_change(void)
+{
+       int fd = open(CTSVC_NOTI_MY_PROFILE_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               my_profile_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_phonelog_change(void)
+{
+       int fd = open(CTSVC_NOTI_PHONELOG_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               phonelog_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_speed_change(void)
+{
+       int fd = open(CTSVC_NOTI_SPEEDDIAL_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               speed_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_addressbook_change(void)
+{
+       int fd = open(CTSVC_NOTI_ADDRESSBOOK_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               addressbook_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_group_change(void)
+{
+       int fd = open(CTSVC_NOTI_GROUP_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               group_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_group_rel_change(void)
+{
+       int fd = open(CTSVC_NOTI_GROUP_RELATION_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               group_rel_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_person_change(void)
+{
+       int fd = open(CTSVC_NOTI_PERSON_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               person_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_name_change(void)
+{
+       int fd = open(CTSVC_NOTI_NAME_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               name_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_number_change(void)
+{
+       int fd = open(CTSVC_NOTI_NUMBER_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               number_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_email_change(void)
+{
+       int fd = open(CTSVC_NOTI_EMAIL_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               email_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_event_change(void)
+{
+       int fd = open(CTSVC_NOTI_EVENT_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               event_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_url_change(void)
+{
+       int fd = open(CTSVC_NOTI_URL_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               url_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_address_change(void)
+{
+       int fd = open(CTSVC_NOTI_ADDRESS_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               address_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_note_change(void)
+{
+       int fd = open(CTSVC_NOTI_NOTE_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               note_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_company_change(void)
+{
+       int fd = open(CTSVC_NOTI_COMPANY_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               company_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_relationship_change(void)
+{
+       int fd = open(CTSVC_NOTI_RELATIONSHIP_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               relationship_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_image_change(void)
+{
+       int fd = open(CTSVC_NOTI_IMAGE_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               image_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_nickname_change(void)
+{
+       int fd = open(CTSVC_NOTI_NICKNAME_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               nickname_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_messenger_change(void)
+{
+       int fd = open(CTSVC_NOTI_MESSENGER_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               messenger_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_data_change(void)
+{
+       int fd = open(CTSVC_NOTI_DATA_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               data_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_sdn_change(void)
+{
+       int fd = open(CTSVC_NOTI_SDN_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               sdn_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_profile_change(void)
+{
+       int fd = open(CTSVC_NOTI_PROFILE_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               profile_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_activity_change(void)
+{
+       int fd = open(CTSVC_NOTI_ACTIVITY_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               activity_change = false;
+       }
+}
+
+static inline void __ctsvc_noti_publish_activity_photo_change(void)
+{
+       int fd = open(CTSVC_NOTI_ACTIVITY_PHOTO_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               activity_photo_change = false;
+       }
+}
+
+void ctsvc_nofitication_cancel(void)
+{
+       contact_change = false;
+       my_profile_change = false;
+       phonelog_change = false;
+       speed_change = false;
+       addressbook_change = false;
+       group_change = false;
+       group_rel_change = false;
+       person_change = false;
+       activity_change = false;
+       activity_photo_change = false;
+       address_change = false;
+       data_change = false;
+       event_change = false;
+       number_change = false;
+       email_change = false;
+       messenger_change = false;
+       name_change = false;
+       note_change = false;
+       url_change = false;
+       nickname_change = false;
+       sdn_change = false;
+       relationship_change = false;
+       image_change = false;
+       profile_change = false;
+       company_change = false;
+}
+
+void ctsvc_set_contact_noti(void)
+{
+       contact_change = true;
+}
+
+void ctsvc_set_my_profile_noti(void)
+{
+       my_profile_change = true;
+}
+
+void ctsvc_set_phonelog_noti(void)
+{
+       phonelog_change = true;
+}
+
+void ctsvc_set_speed_noti(void)
+{
+       speed_change = true;
+}
+
+void ctsvc_set_addressbook_noti(void)
+{
+       addressbook_change = true;
+}
+
+void ctsvc_set_group_noti(void)
+{
+       group_change = true;
+}
+
+void ctsvc_set_group_rel_noti(void)
+{
+       group_rel_change = true;
+}
+
+void ctsvc_set_person_noti(void)
+{
+       person_change = true;
+}
+
+void ctsvc_set_activity_noti(void)
+{
+       activity_change = true;
+}
+
+void ctsvc_set_activity_photo_noti(void)
+{
+       activity_photo_change = true;
+}
+
+void ctsvc_set_address_noti(void)
+{
+       address_change = true;
+}
+
+void ctsvc_set_data_noti(void)
+{
+       data_change = true;
+}
+
+void ctsvc_set_event_noti(void)
+{
+       event_change = true;
+}
+
+void ctsvc_set_number_noti(void)
+{
+       number_change = true;
+}
+
+void ctsvc_set_email_noti(void)
+{
+       email_change = true;
+}
+
+void ctsvc_set_messenger_noti(void)
+{
+       messenger_change = true;
+}
+
+void ctsvc_set_nickname_noti(void)
+{
+       nickname_change = true;
+}
+
+void ctsvc_set_name_noti(void)
+{
+       name_change = true;
+}
+
+void ctsvc_set_note_noti(void)
+{
+       note_change = true;
+}
+
+void ctsvc_set_url_noti(void)
+{
+       url_change = true;
+}
+
+void ctsvc_set_sdn_noti(void)
+{
+       sdn_change = true;
+}
+
+void ctsvc_set_relationship_noti(void)
+{
+       relationship_change = true;
+}
+
+void ctsvc_set_image_noti(void)
+{
+       image_change = true;
+}
+
+void ctsvc_set_profile_noti(void)
+{
+       profile_change = true;
+}
+
+void ctsvc_set_company_noti(void)
+{
+       company_change = true;
+}
+
+void ctsvc_notification_send()
+{
+       if (contact_change) __ctsvc_noti_publish_contact_change();
+       if (my_profile_change) __ctsvc_noti_publish_my_profile_change();
+       if (phonelog_change) __ctsvc_noti_publish_phonelog_change();
+       if (speed_change) __ctsvc_noti_publish_speed_change();
+       if (addressbook_change) __ctsvc_noti_publish_addressbook_change();
+       if (group_change) __ctsvc_noti_publish_group_change();
+       if (group_rel_change) __ctsvc_noti_publish_group_rel_change();
+       if (person_change) __ctsvc_noti_publish_person_change();
+       if (activity_change) __ctsvc_noti_publish_activity_change();
+       if (activity_photo_change) __ctsvc_noti_publish_activity_photo_change();
+       if (address_change) __ctsvc_noti_publish_address_change();
+       if (data_change) __ctsvc_noti_publish_data_change();
+       if (company_change) __ctsvc_noti_publish_company_change();
+       if (event_change) __ctsvc_noti_publish_event_change();
+       if (number_change) __ctsvc_noti_publish_number_change();
+       if (email_change) __ctsvc_noti_publish_email_change();
+       if (messenger_change) __ctsvc_noti_publish_messenger_change();
+       if (name_change) __ctsvc_noti_publish_name_change();
+       if (note_change) __ctsvc_noti_publish_note_change();
+       if (url_change) __ctsvc_noti_publish_url_change();
+       if (nickname_change) __ctsvc_noti_publish_nickname_change();
+       if (sdn_change) __ctsvc_noti_publish_sdn_change();
+       if (relationship_change) __ctsvc_noti_publish_relationship_change();
+       if (image_change) __ctsvc_noti_publish_image_change();
+       if (profile_change) __ctsvc_noti_publish_profile_change();
+}
+
+// Whenever deleting data table record, this function will be called
+// in order to set notification
+void ctsvc_db_data_delete_callback(sqlite3_context * context,
+               int argc, sqlite3_value ** argv)
+{
+       CTS_FN_CALL;
+       int datatype;
+
+       if (argc > 2) {
+               sqlite3_result_null(context);
+               return;
+       }
+
+       datatype = sqlite3_value_int(argv[1]);
+
+       switch(datatype) {
+       case CTSVC_DATA_NAME:
+               ctsvc_set_name_noti();
+               break;
+       case CTSVC_DATA_POSTAL:
+               ctsvc_set_address_noti();
+               break;
+       case CTSVC_DATA_MESSENGER:
+               ctsvc_set_messenger_noti();
+               break;
+       case CTSVC_DATA_URL:
+               ctsvc_set_url_noti();
+               break;
+       case CTSVC_DATA_EVENT:
+               ctsvc_set_event_noti();
+               break;
+       case CTSVC_DATA_COMPANY:
+               ctsvc_set_company_noti();
+               break;
+       case CTSVC_DATA_NICKNAME:
+               ctsvc_set_nickname_noti();
+               break;
+       case CTSVC_DATA_NUMBER:
+               ctsvc_set_number_noti();
+               break;
+       case CTSVC_DATA_EMAIL:
+               ctsvc_set_email_noti();
+               break;
+       case CTSVC_DATA_PROFILE:
+               ctsvc_set_profile_noti();
+               break;
+       case CTSVC_DATA_RELATIONSHIP:
+               ctsvc_set_relationship_noti();
+               break;
+       case CTSVC_DATA_NOTE:
+               ctsvc_set_note_noti();
+               break;
+       case CTSVC_DATA_IMAGE:
+               ctsvc_set_image_noti();
+               break;
+       case CTSVC_DATA_EXTENSION:
+               ctsvc_set_data_noti();
+               break;
+       default:
+               break;
+       }
+       sqlite3_result_null(context);
+       CTS_FN_END;
+}
+
+API int contacts_db_add_status_changed_cb(
+               contacts_db_status_changed_cb cb, void* user_data)
+{
+       CTS_ERR("Please use contacts-service2 instead of contacts-service3");
+       return CONTACTS_ERROR_INTERNAL;
+}
+
+API int contacts_db_remove_status_changed_cb(
+               contacts_db_status_changed_cb cb, void* user_data)
+{
+       CTS_ERR("Please use contacts-service2 instead of contacts-service3");
+       return CONTACTS_ERROR_INTERNAL;
+}
diff --git a/native/ctsvc_notification.h b/native/ctsvc_notification.h
new file mode 100644 (file)
index 0000000..a3a76d5
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CTSVC_NOTIFICATION_H__
+#define __TIZEN_SOCIAL_CTSVC_NOTIFICATION_H__
+
+#include "ctsvc_sqlite.h"
+
+void ctsvc_set_contact_noti(void);
+void ctsvc_set_my_profile_noti(void);
+void ctsvc_set_phonelog_noti(void);
+void ctsvc_set_speed_noti(void);
+void ctsvc_set_addressbook_noti(void);
+void ctsvc_set_group_noti(void);
+void ctsvc_set_group_rel_noti(void);
+void ctsvc_set_person_noti(void);
+void ctsvc_set_data_noti(void);
+void ctsvc_set_activity_noti(void);
+void ctsvc_set_activity_photo_noti(void);
+void ctsvc_set_address_noti(void);
+void ctsvc_set_event_noti(void);
+void ctsvc_set_messenger_noti(void);
+void ctsvc_set_number_noti(void);
+void ctsvc_set_email_noti(void);
+void ctsvc_set_name_noti(void);
+void ctsvc_set_note_noti(void);
+void ctsvc_set_url_noti(void);
+void ctsvc_set_nickname_noti(void);
+void ctsvc_set_relationship_noti(void);
+void ctsvc_set_image_noti(void);
+void ctsvc_set_profile_noti(void);
+void ctsvc_set_sdn_noti(void);
+void ctsvc_set_company_noti(void);
+
+void ctsvc_notification_send();
+void ctsvc_nofitication_cancel(void);
+void ctsvc_noti_publish_socket_initialize(void);
+
+void ctsvc_db_data_delete_callback(sqlite3_context * context,
+               int argc, sqlite3_value ** argv);
+
+#endif /* __TIZEN_SOCIAL_CTSVC_NOTIFICATION_H__ */
diff --git a/native/ctsvc_number_utils.c b/native/ctsvc_number_utils.c
new file mode 100644 (file)
index 0000000..3e0a901
--- /dev/null
@@ -0,0 +1,1127 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <ctype.h>
+#include <unicode/ustring.h>
+
+#include <TapiUtility.h>
+#include <ITapiNetwork.h>
+#include <sqlite3.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_setting.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_localize_utils.h"
+#include "ctsvc_number_utils.h"
+
+typedef struct {
+       int mcc;
+       char *cc;
+}ctsvc_mcc_cc_map;
+
+const static ctsvc_mcc_cc_map __mcc_cc_list[] = {
+       {0, "1"},
+       {202, "30"},
+       {204, "31"},
+       {206, "32"},
+       {208, "33"},
+       {212, "377"},
+       {213, "376"},
+       {214, "34"},
+       {216, "36"},
+       {218, "387"},
+       {219, "385"},
+       {220, "381"},
+       {222, "39"},
+       {225, "39"},
+       {226, "40"},
+       {228, "41"},
+       {230, "420"},
+       {231, "421"},
+       {232, "43"},
+       {234, "44"},
+       {235, "44"},
+       {238, "45"},
+       {240, "46"},
+       {242, "47"},
+       {244, "358"},
+       {246, "370"},
+       {247, "371"},
+       {248, "372"},
+       {250, "7"},
+       {255, "380"},
+       {257, "375"},
+       {259, "373"},
+       {260, "48"},
+       {262, "49"},
+       {266, "350"},
+       {268, "351"},
+       {270, "352"},
+       {272, "353"},
+       {274, "354"},
+       {276, "355"},
+       {278, "356"},
+       {280, "357"},
+       {282, "995"},
+       {283, "374"},
+       {284, "359"},
+       {286, "90"},
+       {288, "298"},
+       {290, "299"},
+       {292, "378"},
+       {293, "386"},
+       {294, "389"},
+       {295, "423"},
+       {297, "382"},
+       {302, "1"},
+       {308, "508"},
+       {310, "1"},
+       {311, "1"},
+       {312, "1"},
+       {313, "1"},
+       {314, "1"},
+       {315, "1"},
+       {316, "1"},
+       {330, "1"},
+       {332, "1"},
+       {334, "52"},
+       {338, "1"},
+       {340, "590"},
+       {340, "596"},
+       {342, "1"},
+       {344, "1"},
+       {346, "1"},
+       {348, "1"},
+       {350, "1"},
+       {352, "1"},
+       {354, "1"},
+       {356, "1"},
+       {358, "1"},
+       {360, "1"},
+       {362, "599"},
+       {363, "297"},
+       {364, "1"},
+       {365, "1"},
+       {366, "1"},
+       {368, "53"},
+       {370, "1"},
+       {372, "509"},
+       {374, "1"},
+       {376, "1"},
+       {400, "994"},
+       {401, "7"},
+       {402, "975"},
+       {404, "91"},
+       {405, "91"},
+       {406, "91"},
+       {410, "92"},
+       {412, "93"},
+       {413, "94"},
+       {414, "95"},
+       {415, "961"},
+       {416, "962"},
+       {417, "963"},
+       {418, "964"},
+       {419, "965"},
+       {420, "966"},
+       {421, "967"},
+       {422, "968"},
+       {424, "971"},
+       {425, "972"},
+       {426, "973"},
+       {427, "974"},
+       {428, "976"},
+       {429, "977"},
+       {430, "971"},
+       {431, "971"},
+       {432, "98"},
+       {434, "998"},
+       {436, "992"},
+       {437, "996"},
+       {438, "993"},
+       {440, "81"},
+       {441, "81"},
+       {450, "82"},
+       {452, "84"},
+       {454, "852"},
+       {455, "853"},
+       {456, "855"},
+       {457, "856"},
+       {460, "86"},
+       {461, "86"},
+       {466, "886"},
+       {467, "850"},
+       {470, "880"},
+       {472, "960"},
+       {502, "60"},
+       {505, "61"},
+       {510, "62"},
+       {514, "670"},
+       {515, "63"},
+       {520, "66"},
+       {525, "65"},
+       {528, "673"},
+       {530, "64"},
+       {536, "674"},
+       {537, "675"},
+       {539, "676"},
+       {540, "677"},
+       {541, "678"},
+       {542, "679"},
+       {543, "681"},
+       {544, "1"},
+       {545, "686"},
+       {546, "687"},
+       {547, "689"},
+       {548, "682"},
+       {549, "685"},
+       {550, "691"},
+       {551, "692"},
+       {552, "680"},
+       {602, "20"},
+       {603, "213"},
+       {604, "212"},
+       {605, "216"},
+       {606, "218"},
+       {607, "220"},
+       {608, "221"},
+       {609, "222"},
+       {610, "223"},
+       {611, "224"},
+       {612, "225"},
+       {613, "226"},
+       {614, "227"},
+       {615, "228"},
+       {616, "229"},
+       {617, "230"},
+       {618, "231"},
+       {619, "232"},
+       {620, "233"},
+       {621, "234"},
+       {622, "235"},
+       {623, "236"},
+       {624, "237"},
+       {625, "238"},
+       {626, "239"},
+       {627, "240"},
+       {628, "241"},
+       {629, "242"},
+       {630, "243"},
+       {631, "244"},
+       {632, "245"},
+       {633, "248"},
+       {634, "249"},
+       {635, "250"},
+       {636, "251"},
+       {637, "252"},
+       {638, "253"},
+       {639, "254"},
+       {640, "255"},
+       {641, "256"},
+       {642, "257"},
+       {643, "258"},
+       {645, "260"},
+       {646, "261"},
+       {647, "262"},
+       {648, "263"},
+       {649, "264"},
+       {650, "265"},
+       {651, "266"},
+       {652, "267"},
+       {653, "268"},
+       {654, "269"},
+       {655, "27"},
+       {657, "291"},
+       {702, "501"},
+       {704, "502"},
+       {706, "503"},
+       {708, "504"},
+       {710, "505"},
+       {712, "506"},
+       {714, "507"},
+       {716, "51"},
+       {722, "54"},
+       {724, "55"},
+       {730, "56"},
+       {732, "57"},
+       {734, "58"},
+       {736, "591"},
+       {738, "592"},
+       {740, "593"},
+       {742, "594"},
+       {744, "595"},
+       {746, "597"},
+       {748, "598"},
+       {750, "500"},
+};
+
+static char *cc = NULL;
+static TapiHandle *handle_for_cc = NULL;
+
+char* ctsvc_get_network_cc(bool reload)
+{
+       int i;
+       int state;
+       int ret;
+       int mcc = 0;
+       char *temp = NULL;
+       TapiHandle *handle = NULL;
+       static bool cc_loaded = false;
+
+       if (cc_loaded && !reload)
+               return cc;
+
+       cc_loaded = true;
+       cc = NULL;
+       handle = (TapiHandle *)ctsvc_init_tapi_handle_for_cc();
+       RETVM_IF(NULL == handle, NULL, "tel_init() Failed");
+
+       ret = tel_get_property_int(handle, TAPI_PROP_NETWORK_SERVICE_TYPE, &state);
+       if (ret != TAPI_API_SUCCESS) {
+               CTS_ERR("tel_get_property_int Fail(%d)", ret);
+               tel_deinit(handle);
+               return NULL;
+       }
+
+       if (state == TAPI_NETWORK_SERVICE_TYPE_UNKNOWN
+                       || state == TAPI_NETWORK_SERVICE_TYPE_NO_SERVICE
+                       || state == TAPI_NETWORK_SERVICE_TYPE_EMERGENCY
+                       || state == TAPI_NETWORK_SERVICE_TYPE_SEARCH) {
+               CTS_INFO("network service is not working : state(%d)", state);
+               return NULL;
+       }
+
+       ret = tel_get_property_string(handle, TAPI_PROP_NETWORK_PLMN,  &temp);
+       if (ret != TAPI_API_SUCCESS) {
+               CTS_ERR("tel_get_property_string Fail(%d)", ret);
+               return NULL;
+       }
+
+       if (temp && strlen(temp) > 3)
+               temp[3] = '\0';
+       mcc = atoi(temp);
+       for (i=0;i<sizeof(__mcc_cc_list)/sizeof(ctsvc_mcc_cc_map);i++)
+               if(__mcc_cc_list[i].mcc == mcc)
+                       cc = __mcc_cc_list[i].cc;
+       return cc;
+}
+
+static void __ctsvc_network_cc_changed(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
+{
+       ctsvc_get_network_cc(true);
+}
+
+void* ctsvc_init_tapi_handle_for_cc()
+{
+       if (handle_for_cc)
+               return handle_for_cc;
+
+       handle_for_cc = tel_init(NULL);
+       if (handle_for_cc) {
+               int ret = tel_register_noti_event(handle_for_cc,
+                               TAPI_PROP_NETWORK_PLMN, __ctsvc_network_cc_changed, NULL);
+               WARN_IF(ret != TAPI_API_SUCCESS, "tel_register_noti_event Fail(%d)", ret);
+       }
+       else
+               CTS_ERR("tel_init fail");
+       return handle_for_cc;
+}
+
+void ctsvc_deinit_tapi_handle_for_cc()
+{
+       if (handle_for_cc) {
+               int ret = tel_deregister_noti_event(handle_for_cc,  TAPI_PROP_NETWORK_PLMN);
+               WARN_IF(ret != TAPI_API_SUCCESS, "tel_register_noti_event Fail(%d)", ret);
+               tel_deinit(handle_for_cc);
+       }
+       handle_for_cc = NULL;
+}
+
+static inline int __ctsvc_phone_number_has_country_code(const char *src, int len)
+{
+       int ret = 0;
+
+       if (len <= 0)
+               return 0;
+
+       switch (src[ret++]-'0') {
+       case 1:
+       case 7:
+               break;
+       case 2:
+               if (ret >= len) return 0;
+               switch (src[ret++]-'0') {
+               case 0:
+               case 7:
+                       break;
+               case 1:
+               case 2:
+               case 3:
+               case 4:
+               case 5:
+               case 6:
+               case 8:
+               case 9:
+                       ret += 1;
+                       break;
+               default:
+                       CTS_ERR("The parameter(src:%s) has invalid character set", src);
+               }
+               break;
+       case 3:
+               if (ret >= len) return 0;
+               switch (src[ret++]-'0') {
+               case 0:
+               case 1:
+               case 2:
+               case 3:
+               case 4:
+               case 6:
+               case 9:
+                       break;
+               case 5:
+               case 7:
+               case 8:
+                       ret += 1;
+                       break;
+               default:
+                       CTS_ERR("The parameter(src:%s) has invalid character set", src);
+               }
+               break;
+       case 4:
+               if (ret >= len) return 0;
+               switch (src[ret++]-'0') {
+               case 0:
+               case 1:
+               case 3:
+               case 4:
+               case 5:
+               case 6:
+               case 7:
+               case 8:
+               case 9:
+                       break;
+               case 2:
+                       ret += 1;
+                       break;
+               default:
+                       CTS_ERR("The parameter(src:%s) has invalid character set", src);
+               }
+               break;
+       case 5:
+               if (ret >= len) return 0;
+               switch (src[ret++]-'0') {
+               case 1:
+               case 2:
+               case 3:
+               case 4:
+               case 5:
+               case 6:
+               case 7:
+               case 8:
+                       break;
+               case 0:
+               case 9:
+                       ret += 1;
+                       break;
+               default:
+                       CTS_ERR("The parameter(src:%s) has invalid character set", src);
+               }
+               break;
+       case 6:
+               if (ret >= len) return 0;
+               switch (src[ret++]-'0') {
+               case 0:
+               case 1:
+               case 2:
+               case 3:
+               case 4:
+               case 5:
+               case 6:
+                       break;
+               case 7:
+               case 8:
+               case 9:
+                       ret += 1;
+                       break;
+               default:
+                       CTS_ERR("The parameter(src:%s) has invalid character set", src);
+               }
+               break;
+       case 8:
+               if (ret >= len) return 0;
+               switch (src[ret++]-'0') {
+               case 1:
+               case 2:
+               case 4:
+               case 6:
+                       break;
+               case 0:
+               case 3:
+               case 5:
+               case 7:
+               case 8:
+               case 9:
+                       ret += 1;
+                       break;
+               default:
+                       CTS_ERR("The parameter(src:%s) has invalid character set", src);
+               }
+               break;
+       case 9:
+               if (ret >= len) return 0;
+               switch (src[ret++]-'0') {
+               case 0:
+               case 1:
+               case 2:
+               case 3:
+               case 4:
+               case 5:
+               case 8:
+                       break;
+               case 6:
+               case 7:
+               case 9:
+                       ret += 1;
+                       break;
+               default:
+                       CTS_ERR("The parameter(src:%s) has invalid character set", src);
+               }
+               break;
+       case 0:
+       default:
+               CTS_ERR("The parameter(src:%s) has invalid character set", src);
+               return 0;
+       }
+
+       return ret;
+}
+
+// Number Matching Rule
+// refer to the http://www.itu.int/dms_pub/itu-t/opb/sp/T-SP-E.164C-2011-PDF-E.pdf
+enum {
+       CTSVC_PLUS_ONLY,                // +
+       CTSVC_PLUS_IP_ONLY,     // +IP (International prefix)
+       CTSVC_PLUS_CC_ONLY,     // +CC (Country code)
+       CTSVC_PLUS_IP_CC,       // +IP CC
+       CTSVC_IP_ONLY,  // IP
+       CTSVC_CC_ONLY,  // CC
+       CTSVC_IP_CC,            // IP CC
+       CTSVC_NONE,
+};
+
+static int __ctsvc_number_has_ip_and_cc(const char*number, int len, int *index)
+{
+       bool have_cc = false;
+       bool have_plus = false;
+       int ret = CTSVC_NONE;
+       int start_index;
+       int match_len;
+       *index = 0;
+
+       // Check IP
+       start_index = 0;
+       match_len = 0;
+
+       switch(number[start_index]) {
+       case '+':
+               start_index++;
+               have_plus = true;
+               if (start_index >= len) {
+                       *index = start_index;
+                       return CTSVC_PLUS_ONLY;         //'+'
+               }
+       default:
+               {
+                       // IP can be
+                       //                      0 (Turks and Caicos Islands, Samoa)
+                       //                      00, 011, 0011, 010, 000
+                       //                      001/007 (Cambodia), 001/008 (Indonesia, Singapore), 001/002 (Korea), 002(Taiwan)
+                       //                      810 (Belarus, Kazakhstan, Russian, Tajikistan, Turkmenistan)
+                       //                      009/007/005(Colombia), 009(Nigeria)
+                       //                      119 (Cuba)
+                       //                      00/012/013/014 (Israel)
+                       switch(number[start_index]) {
+                       case '0':               // '+0'
+                               {
+                                       start_index++;
+                                       if (start_index >= len) {
+                                               *index = start_index;
+                                               return (have_plus?CTSVC_PLUS_IP_ONLY:CTSVC_IP_ONLY);            // '+0'
+                                       }
+
+                                       switch(number[start_index]) {
+                                       case '0':               // '+00'
+                                               {
+                                                       start_index++;
+                                                       if (start_index >= len) {
+                                                               *index = start_index;
+                                                               return (have_plus?CTSVC_PLUS_IP_ONLY:CTSVC_IP_ONLY);            // '+00'
+                                                       }
+
+                                                       switch(number[start_index]) {
+                                                       case '0':               // '+000'
+                                                       case '2':               // '+002'
+                                                       case '5':               // '+005'
+                                                       case '7':               // '+007'
+                                                       case '8':               // '+008'
+                                                       case '9':               // '+009'
+                                                                                               // or '+00 CC'
+                                                               start_index++;
+                                                               if (start_index >= len) {
+                                                                       *index = start_index;
+                                                                       return (have_plus?CTSVC_PLUS_IP_ONLY:CTSVC_IP_ONLY);                    // '+00Y'
+                                                               }
+
+                                                               have_cc = __ctsvc_phone_number_has_country_code(&number[start_index], len-start_index);
+                                                               if (have_cc > 0) {
+                                                                       *index = start_index;
+                                                                       return (have_plus?CTSVC_PLUS_IP_CC:CTSVC_IP_CC);                                        // '+00Y CC'
+                                                               }
+                                                               else {
+                                                                       have_cc = __ctsvc_phone_number_has_country_code(&number[start_index-1], len-start_index+1);
+                                                                       if (have_cc > 0) {
+                                                                               *index = start_index-1;
+                                                                               return (have_plus?CTSVC_PLUS_IP_CC:CTSVC_IP_CC);                // '+00 CC'
+                                                                       }
+                                                               }
+                                                               *index = start_index;
+                                                               return (have_plus?CTSVC_PLUS_IP_ONLY:CTSVC_IP_ONLY);    // '+00Y XXX'
+                                                       case '1':               // '+001'
+                                                               start_index++;
+                                                               if (start_index >= len) {
+                                                                       *index = start_index;
+                                                                       return (have_plus?CTSVC_PLUS_IP_ONLY:CTSVC_IP_ONLY);            // '+001'
+                                                               }
+
+                                                               if (number[start_index] == '1') {
+                                                                       start_index++;
+                                                                       if (start_index >= len) {
+                                                                               *index = start_index;
+                                                                               return (have_plus?CTSVC_PLUS_IP_ONLY:CTSVC_IP_ONLY);            // '+0011'
+                                                                       }
+
+                                                                       have_cc = __ctsvc_phone_number_has_country_code(&number[start_index], len-start_index);
+                                                                       if (have_cc > 0) {
+                                                                               *index = start_index;
+                                                                               return (have_plus?CTSVC_PLUS_IP_CC:CTSVC_IP_CC);                        //  '+0011 CC'
+                                                                       }
+                                                                       start_index--;
+                                                               }
+
+                                                               have_cc = __ctsvc_phone_number_has_country_code(&number[start_index], len-start_index);
+                                                               *index = start_index;
+                                                               if (have_cc > 0)
+                                                                       return (have_plus?CTSVC_PLUS_IP_CC:CTSVC_IP_CC);                        // '+001 CC'
+                                                               else
+                                                                       return (have_plus?CTSVC_PLUS_IP_ONLY:CTSVC_IP_ONLY);            // '+001 XXX'
+                                                       default:                // '+00 3', '+00 4', '+00 6'
+                                                               *index = start_index;
+                                                               have_cc = __ctsvc_phone_number_has_country_code(&number[start_index], len-start_index);
+                                                               if (have_cc > 0)
+                                                                       return (have_plus?CTSVC_PLUS_IP_CC:CTSVC_IP_CC);                        // '+00 CC'
+                                                               else
+                                                                       return (have_plus?CTSVC_PLUS_IP_ONLY:CTSVC_IP_ONLY);    // '+00 XXX'
+                                                       }       // end of fourth switch
+                                               }
+                                               break;
+                                       case '1':               // '+01'
+                                               {
+                                                       start_index++;
+                                                       if (start_index >= len) {
+                                                               *index = start_index-1; // '+0 1'
+                                                               return (have_plus?CTSVC_PLUS_IP_CC:CTSVC_IP_CC);
+                                                       }
+
+                                                       switch(number[start_index]) {
+                                                       case '0':               // '+010'
+                                                       case '1':               // '+011'
+                                                       case '2':               // '+012'
+                                                       case '3':               // '+013'
+                                                       case '4':               // '+014'
+                                                               {
+                                                                       start_index++;
+                                                                       if (start_index >= len) {
+                                                                               *index = start_index;
+                                                                               return (have_plus?CTSVC_PLUS_IP_ONLY:CTSVC_IP_ONLY);            // '+01Y'
+                                                                       }
+
+                                                                       have_cc = __ctsvc_phone_number_has_country_code(&number[start_index], len-start_index);
+                                                                       *index = start_index;
+                                                                       if (have_cc > 0)
+                                                                               return (have_plus?CTSVC_PLUS_IP_CC:CTSVC_IP_CC);                        // '+01Y CC'
+                                                                       else
+                                                                               return (have_plus?CTSVC_PLUS_IP_ONLY:CTSVC_IP_ONLY);    // '+01Y XXX'
+                                                               }
+                                                               break;
+                                                       default:
+                                                               *index = start_index-1; // '+0 1'
+                                                               return (have_plus?CTSVC_PLUS_IP_CC:CTSVC_IP_CC);
+                                                       }
+                                               }
+                                               break;
+                                       default:                // '+0 CC'
+                                               {
+                                                       have_cc = __ctsvc_phone_number_has_country_code(&number[start_index], len-start_index);
+                                                       *index = start_index;
+                                                       if (have_cc > 0)
+                                                               return (have_plus?CTSVC_PLUS_IP_CC:CTSVC_IP_CC);                        // '+0 CC'
+                                                       else
+                                                               return (have_plus?CTSVC_PLUS_IP_ONLY:CTSVC_IP_ONLY);    // '+0 XXX'
+                                               }
+                                               break;
+                                       }               // end of third switch
+                               }
+                               break;          // end of '+0'
+                       case '1':               // '+1'
+                               start_index++;
+                               if (start_index+2 <= len && strncmp(&number[start_index], "19", 2) == 0) {      // '+119'
+                                       match_len = start_index + 2;
+                                       ret = (have_plus?CTSVC_PLUS_IP_ONLY:CTSVC_IP_ONLY);
+                               }
+                               else {
+                                       match_len = start_index-1;
+                                       ret = (have_plus?CTSVC_PLUS_ONLY:CTSVC_NONE);           // '+ CC'
+                               }
+                               break;
+                       case '8':               // '+8'
+                               start_index++;
+                               if (start_index+2 <= len && strncmp(&number[start_index], "10", 2) == 0) {      // '+810'
+                                       match_len = start_index + 2;
+                                       ret = (have_plus?CTSVC_PLUS_IP_ONLY:CTSVC_IP_ONLY);
+                               }
+                               else {
+                                       match_len = start_index-1;
+                                       ret = (have_plus?CTSVC_PLUS_ONLY:CTSVC_NONE);           // '+ CC'
+                               }
+                               break;
+                       default:
+                               match_len = start_index;
+                               ret = (have_plus?CTSVC_PLUS_ONLY:CTSVC_NONE);           // '+ CC'
+                               break;
+                       }               // end of second switch
+               }
+               break;          // '+' default
+       }       // end of first switch
+       *index = match_len;
+
+       // Check CC
+       if (match_len < len) {
+               have_cc = __ctsvc_phone_number_has_country_code(&number[match_len], len-match_len);
+               if (have_cc > 0) {
+                       switch (ret) {
+                       case CTSVC_NONE:
+                               return CTSVC_CC_ONLY;
+                       case CTSVC_PLUS_ONLY:
+                               return CTSVC_PLUS_CC_ONLY;
+                       case CTSVC_PLUS_IP_ONLY:
+                               return CTSVC_PLUS_IP_CC;
+                       case CTSVC_IP_ONLY:
+                               return CTSVC_IP_CC;
+                       }
+               }
+       }
+       return ret;
+}
+
+int ctsvc_normalize_number(const char *src, char *dest, int dest_size, bool replace_alphabet)
+{
+       int index;
+       int n;
+       char *cc = NULL;
+       int d_pos = 0;
+       int first_zero = 0;
+
+       if (NULL == src) {
+               CTS_ERR("The parameter(src) is NULL");
+               return 0;
+       }
+
+       d_pos = strlen(src);
+       if (d_pos <= 0)
+               return d_pos;
+
+       cc = ctsvc_get_network_cc(false);
+       n = __ctsvc_number_has_ip_and_cc(src, d_pos-ctsvc_get_phonenumber_min_match_digit(), &index);
+
+       if (src[0] == '0'       // remove first '0'
+                       || (cc && cc[0] == '7' && src[0] == '8'))       // Russian
+               first_zero = 1;
+
+       // 001 82 10 1234 5678 -> +82 10 1234 5678
+       // +001 82 10 1234 5678 -> +82 10 1234 5678
+       // 82 10 1234 5678 -> +82 10 1234 5678
+       // add '+'
+       // do not append + if the number without cc is too short
+       // cc 010-1234-5678 ==> +cc 010-1234-5678, cc3456 => cc3456
+       if (CTSVC_IP_CC == n || CTSVC_CC_ONLY == n) {
+               if (dest_size > d_pos + 1) {
+                       dest[0] = '+';
+                       memcpy(dest+1, src, d_pos+1);
+                       d_pos++;
+                       dest[d_pos] = 0;
+                       return d_pos;
+               }
+       }
+       else if (CTSVC_PLUS_ONLY == n || CTSVC_PLUS_CC_ONLY == n
+                || CTSVC_PLUS_IP_ONLY == n || CTSVC_PLUS_IP_CC == n) {
+               if (dest_size > d_pos) {
+                       // Just copy
+                       memcpy(dest, src, d_pos+1);
+                       dest[d_pos] = 0;
+                       return d_pos;
+               }
+       }
+       // append country code
+       else {  // CTSVC_NONE,  // invalid case : CTSVC_IP_ONLY
+               if (cc && d_pos >= ctsvc_get_phonenumber_min_match_digit()) {
+                       // add '+cc'
+                       // do not append cc if the number is too short
+                       // 010-1234-5678 ==> +cc 10-1234-5678, 1234 ==> 1234
+                       // 8 XXX-XXX-XX-XX ===> +7 XXX-XXX-XX-XX
+                       if (dest_size > d_pos + strlen(cc) + 1) {
+                               dest[0] = '+';
+                               memcpy(dest+1, cc, strlen(cc));
+                               memcpy(dest+1+strlen(cc), src+first_zero, d_pos+1-first_zero);
+                               d_pos += (1+strlen(cc));
+                               dest[d_pos] = 0;
+                               return d_pos;
+                       }
+               }
+       }
+
+       memcpy(dest, src, d_pos+1);
+       dest[d_pos] = 0;
+
+       return d_pos;
+}
+
+// vaild character : digit, +, *, #, , ;, alphabet(depends on replace_alphabet parameter)
+// Remove invalid string from number
+int ctsvc_clean_number(const char *src, char *dest, int dest_size, bool replace_alphabet)
+{
+       int s_pos;
+       int d_pos;
+       int pos;
+       char temp[dest_size];
+
+       if (NULL == src) {
+               CTS_ERR("The parameter(src) is NULL");
+               return 0;
+       }
+
+       s_pos = 0;
+       pos = 0;
+       while (src[s_pos] != 0) {
+               int char_len;
+               if (pos > dest_size-2) break;
+
+               char_len = ctsvc_check_utf8(src[s_pos]);
+               if (char_len <= 0) {
+                       break;
+               }
+
+               if (char_len == 3) {
+                       // fullwidth -> halfwidth
+                       if (src[s_pos] == 0xef) {
+                               if (src[s_pos+1] == 0xbc) {
+                                       if (0x90 <= src[s_pos+2] && src[s_pos+2] <= 0x99)                               // ef bc 90 : '0' ~ ef bc 99 : '9'
+                                               temp[pos++] = src[s_pos+2] - 0x60;
+                                       else if (0xa1 <= src[s_pos+2] && src[s_pos+2] <= 0xba)                  // ef bc a1 : 'A' ~ ef bc ba : 'Z'
+                                               temp[pos++] = src[s_pos+2] - 0x60;
+                                       else if (0x8b == src[s_pos+2])                                                          // ef bc 8b : '+'
+                                               temp[pos++] = '+';
+                                       else if (0x8a == src[s_pos+2])                                                          // ef bc 8a : '*'
+                                               temp[pos++] = '*';
+                                       else if (0x83 == src[s_pos+2])                                                          // ef bc 83 : '#'
+                                               temp[pos++] = '#';
+                                       else if (0x8c == src[s_pos+2])                                                          // ef bc 8c : ','
+                                               temp[pos++] = ',';
+                                       else if (0x9b == src[s_pos+2])                                                          // ef bc 9b : ';'
+                                               temp[pos++] = ';';
+                               }
+                               else if (src[s_pos+1] == 0xbd
+                                               && (0x81 <= src[s_pos+2] && src[s_pos+2] <= 0x9a))              // ef bd 81 : 'a' ~ ef bd 9a : 'z'
+                                       temp[pos++] = src[s_pos+2] - 0x40;
+                       }
+                       else {
+                               s_pos += char_len;
+                               continue;
+                       }
+               }
+               else if (char_len == 1) {
+                       if (0x41 <= src[s_pos] && src[s_pos] <= 0x5a)                   // 'A' ~ 'Z'
+                               temp[pos++] = src[s_pos];
+                       else if (0x61 <= src[s_pos] && src[s_pos] <= 0x7a)                      // 'a' ~ 'z'
+                               temp[pos++] = src[s_pos] - 0x20;
+                       else
+                               temp[pos++] = src[s_pos];
+               }
+               s_pos += char_len;
+       }
+       temp[pos] = 0x0;
+
+       pos = 0;
+       d_pos = 0;
+       while(temp[pos] != 0) {
+               if ('0' <= temp[pos] && temp[pos] <= '9')
+                       dest[d_pos++] = temp[pos];
+               else if (temp[pos] == '+' || temp[pos] == '#'
+                               || temp[pos] == '*' || temp[pos] == ';' || temp[pos] == ',')
+                       dest[d_pos++] = temp[pos];
+               pos++;
+       }
+       dest[d_pos] = 0;
+
+       return d_pos;
+}
+
+static int __ctsvc_minmatch_number(const char *src, char *dest, int dest_size, int min_match)
+{
+       int i;
+       int len = 0;
+       int d_pos = 0;
+       const char *temp_number;
+       const char *cc = ctsvc_get_network_cc(false);
+
+       if ('+' == src[0]) {
+               len = __ctsvc_phone_number_has_country_code(&src[1], strlen(src)-1);
+               temp_number = src + len +1;
+       }
+       else if ('0' == src[0])
+               temp_number = src+1;
+       else if (cc && cc[0] == '7' && src[0] == '8')
+               temp_number = src+1;
+       else
+               temp_number = src;
+
+       len = strlen(temp_number);
+
+       if (0 < len) {
+               while(0 <= (len-d_pos-1) && temp_number[len-d_pos-1]
+                               && d_pos < min_match) {
+                       if (dest_size-d_pos == 0) {
+                               CTS_ERR("Destination string buffer is not enough(%s)", src);
+                               return CONTACTS_ERROR_INTERNAL;
+                       }
+
+                       dest[d_pos] = temp_number[len-d_pos-1];
+                       d_pos++;
+               }
+               dest[d_pos] = 0;
+
+               len = strlen(dest);
+               for(i=0; i<len/2;i++) {
+                       char c;
+                       c = dest[i];
+                       dest[i] = dest[len-i-1];
+                       dest[len-i-1] = c;
+               }
+       }
+       else {
+               memcpy(dest, src, strlen(src));
+               dest[strlen(src)] = 0;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_get_minmatch_number(const char *src, char *dest, int dest_size, int min_match)
+{
+       int ret;
+
+       RETV_IF(NULL == src, CONTACTS_ERROR_INVALID_PARAMETER);
+       RETV_IF(NULL == dest, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       ret = __ctsvc_minmatch_number(src, dest, dest_size, min_match);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("__ctsvc_minmatch_number() failed(%d)", ret);
+               return ret;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static bool __ctsvc_is_phonenumber_halfwidth(const char* keyword)
+{
+       int i;
+       int len = strlen(keyword);
+
+       // TODO: we should add predicate including '+'
+       // TODO: finally, we try to check the number with regular expression.
+       for(i=0; i<len; i++) {
+               if ((keyword[i] < '0' || keyword[i] > '9') && keyword[i] != '+') {
+                       CTS_ERR("keyword[%d]: %c is not number)", i, keyword[i]);
+                       return false;
+               }
+       }
+       return true;
+}
+
+#define UTF8_FULLWIDTH_LENGTH 3
+static bool __ctsvc_is_phonenumber_fullwidth(const char* keyword)
+{
+       int char_len = 1;
+       int str_len;
+       int i;
+       if (keyword == NULL || *keyword == '\0')
+               return false;
+
+       str_len = strlen(keyword);
+       for (i=0;i<str_len;i += char_len) {
+               char_len = ctsvc_check_utf8(keyword[i]);
+               if (char_len != UTF8_FULLWIDTH_LENGTH || str_len-i < UTF8_FULLWIDTH_LENGTH)
+                       return false;
+
+               if (keyword[i] == 0xef) {
+                       if (keyword[i+1] == 0xbc) {
+                               if (0x90 <= keyword[i+2] && keyword[i+2] <= 0x99)                       // ef bc 90 : '0' ~ ef bc 99 : '9'
+                                       continue;
+                               else if (0x8b == keyword[i+2])                                                          // ef bc 8b : '+'
+                                       continue;
+                               else
+                                       return false;
+                       }
+                       else
+                               return false;
+               }
+               else
+                       return false;
+       }
+       return true;
+}
+
+bool ctsvc_is_phonenumber(const char* src)
+{
+       return ( __ctsvc_is_phonenumber_halfwidth(src) || __ctsvc_is_phonenumber_fullwidth(src) );
+}
+
+// numbers are cleaned number or normalized number
+static bool __ctsvc_number_compare(const char *number1, const char *number2)
+{
+       int len1;
+       int len2;
+       int matched;
+       int minmatch_len = ctsvc_get_phonenumber_min_match_digit();
+       const char *cc = ctsvc_get_network_cc(false);
+
+       if (NULL == number1 || NULL == number2 || '\0' == *number1 || '\0' == *number2)
+               return false;
+
+       len1 = strlen(number1);
+       len2 = strlen(number2);
+
+       // compare  number in reverse order
+       for (matched = 0; len1 > 0 && len2 > 0;) {
+               if (number1[len1-1] != number2[len2-1])
+                       break;
+               len1--;
+               len2--;
+               matched++;
+       }
+
+       // full match
+       if (len1 == 0 && len2 == 0)
+               return true;
+
+       // one is substring of the other string
+       if (matched >= minmatch_len && (len1 == 0 || len2 == 0))
+               return true;
+
+       // one is +IPCC or +CC, the other is start wth NTP (National trunk prefix)
+       if (matched >= minmatch_len) {
+               int index1 = 0;
+               int index2 = 0;
+               int cc_index = 0;
+
+               ///////////////////////////////////////////////////
+               // International Prefix (IP) is related to current location where to call
+               // Country Code (CC) is related to the SIM card who to call
+               // If you try to call in United State using Korea SIM card,
+               // the number will be 011 82 X XXXXXXXX.
+               // So, when comparing number, just check IP validation and CC and natinal number matching.
+
+               int n1 = __ctsvc_number_has_ip_and_cc(number1, len1, &index1);
+               int n2 = __ctsvc_number_has_ip_and_cc(number2, len2, &index2);
+
+               ///////////////////////////////////////////////////
+               // + (IP) CC XXXXXXXX, 0XXXXXXXX
+               // + (810) 7 XXX XXX XX XX, 8XXX XXX XX XX (Russian)
+               if ((CTSVC_PLUS_IP_CC == n1 || CTSVC_PLUS_CC_ONLY == n1 ||
+                               CTSVC_IP_CC == n1 || CTSVC_CC_ONLY == n1)
+                               && (number2[0] == '0' || (cc && cc[0] == '7' && number2[0] == '8')))
+                       return true;
+               else if ((CTSVC_PLUS_IP_CC == n2 || CTSVC_PLUS_CC_ONLY == n2 ||
+                                       CTSVC_IP_CC == n2 || CTSVC_CC_ONLY == n2)
+                               && (number1[0] == '0' || (cc && cc[0] == '7' && number1[0] == '8')))
+                       return true;
+               //////////////////////////////////////////////////
+               // + IP CC XXXXXXXX, + CC XXXXXXXX  (ex. +001 82  11 1234 5678 , +82 10 1234 5678)
+               else if ((CTSVC_PLUS_IP_CC == n1 || CTSVC_IP_CC == n1)
+                               && (CTSVC_PLUS_CC_ONLY == n2 || CTSVC_CC_ONLY == n2)) {
+                       int p = (CTSVC_PLUS_CC_ONLY == n2)?1:0;
+                       cc_index = __ctsvc_phone_number_has_country_code(&number2[p], len2-p);
+                       if (cc_index > 0 && strncmp(&number1[index1], &number2[p], cc_index) == 0)
+                               return true;
+               }
+               else if ((CTSVC_PLUS_IP_CC == n2 || CTSVC_IP_CC == n2)
+                               && (CTSVC_PLUS_CC_ONLY == n1 || CTSVC_CC_ONLY == n1)) {
+                       int p = (CTSVC_PLUS_CC_ONLY == n1)?1:0;
+                       cc_index = __ctsvc_phone_number_has_country_code(&number1[p], len1-p);
+                       if (cc_index > 0 && strncmp(&number2[index2], &number1[p], cc_index) == 0)
+                               return true;
+               }
+               ///////////////////////////////////////////////////
+               // + CC XXXXXXXX, + IP CC XXXXXXXX  (ex. +001 82  10 1234 5678 , +82 10 1234 5678)
+               else if ((CTSVC_PLUS_IP_ONLY == n1 || CTSVC_IP_ONLY == n1)
+                               && CTSVC_PLUS_ONLY == n2) {
+                       return true;
+               }
+               else if ((CTSVC_PLUS_IP_ONLY == n2 || CTSVC_IP_ONLY == n2)
+                               && CTSVC_PLUS_ONLY == n1) {
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+// When querying _NUMBER_COMPARE_, this function will be called.
+void ctsvc_db_phone_number_equal_callback(sqlite3_context * context,
+               int argc, sqlite3_value ** argv)
+{
+#ifdef _CONTACTS_IPC_SERVER
+       char *number1;
+       char *number2;
+
+       if (argc < 4) {
+               sqlite3_result_int(context, 0);
+               CTS_ERR("argc invalid");
+               return;
+       }
+
+       number1 = (char*)sqlite3_value_text(argv[0]);
+       number2 = (char*)sqlite3_value_text(argv[1]);
+
+       sqlite3_result_int(context, __ctsvc_number_compare(number1, number2));
+       return;
+#endif
+}
+
diff --git a/native/ctsvc_number_utils.h b/native/ctsvc_number_utils.h
new file mode 100644 (file)
index 0000000..cd6125b
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CTSVC_NUMBER_UTILS_H__
+#define __TIZEN_SOCIAL_CTSVC_NUMBER_UTILS_H__
+
+#include <sqlite3.h>
+
+char* ctsvc_get_network_cc(bool reload);
+
+int ctsvc_clean_number(const char *src, char *dest, int dest_size, bool replace_alphabet);
+int ctsvc_normalize_number(const char *src, char *dest, int dest_size, bool replace_alphabet);
+int ctsvc_get_minmatch_number(const char *src, char *dest, int dest_size, int min_match);
+bool ctsvc_is_phonenumber(const char* src);
+void ctsvc_db_phone_number_equal_callback(sqlite3_context * context, int argc, sqlite3_value ** argv);
+
+void* ctsvc_init_tapi_handle_for_cc(void);
+void ctsvc_deinit_tapi_handle_for_cc(void);
+
+#endif /*  __TIZEN_SOCIAL_CTSVC_NUMBER_UTILS_H__ */
diff --git a/native/ctsvc_person.c b/native/ctsvc_person.c
new file mode 100644 (file)
index 0000000..76b1ac9
--- /dev/null
@@ -0,0 +1,1512 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_plugin_person_helper.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+#include "ctsvc_db_access_control.h"
+
+#ifdef ENABLE_LOG_FEATURE
+#include "ctsvc_phonelog.h"
+#endif // ENABLE_LOG_FEATURE
+
+#ifdef _CONTACTS_IPC_SERVER
+#include "ctsvc_server_change_subject.h"
+#endif
+
+enum {
+       CTSVC_GET_PERSON_DEFAULT_NUMBER_VALUE,
+       CTSVC_GET_PERSON_DEFAULT_EMAIL_VALUE,
+       CTSVC_GET_PERSON_DEFAULT_IMAGE_VALUE,
+};
+
+static inline int __ctsvc_get_person_default_number_value(int id, contacts_record_h *record)
+{
+       int ret;
+       cts_stmt stmt;
+       ctsvc_number_s *number;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                               "SELECT data.id, data.is_default, data.data1, data.data2, data.data3, data.data4 "
+                               "FROM %s, %s ON data.is_primary_default=1 AND data.datatype=%d "
+                                       "AND data.contact_id = contacts.contact_id AND contacts.deleted = 0 "
+                               "WHERE contacts.person_id = %d",
+                               CTS_TABLE_CONTACTS, CTS_TABLE_DATA, CTSVC_DATA_NUMBER, id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               ctsvc_stmt_finalize(stmt);
+               CTS_ERR("ctsvc_stmt_step Fail(%d)", ret);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ret = contacts_record_create(_contacts_number._uri, (contacts_record_h*)&number);
+       if (number) {
+               char *temp;
+               number->id = ctsvc_stmt_get_int(stmt, 0);
+               number->is_default = ctsvc_stmt_get_int(stmt, 1);
+               number->type = ctsvc_stmt_get_int(stmt, 2);
+               temp = ctsvc_stmt_get_text(stmt, 3);
+               number->label = SAFE_STRDUP(temp);
+               temp = ctsvc_stmt_get_text(stmt, 4);
+               number->number = SAFE_STRDUP(temp);
+               temp = ctsvc_stmt_get_text(stmt, 5);
+               number->lookup = SAFE_STRDUP(temp);
+
+               *record = (contacts_record_h)number;
+               ret = CONTACTS_ERROR_NONE;
+       }
+       else
+               CTS_ERR("contacts_record_create() Failed");
+
+       ctsvc_stmt_finalize(stmt);
+       return ret;
+}
+
+static inline int __ctsvc_get_person_default_email_value(int id, contacts_record_h *record)
+{
+       int ret;
+       cts_stmt stmt;
+       ctsvc_email_s *email;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                                       "SELECT data.id, data.is_default, data.data1, data.data2, data.data3 "
+                                       "FROM %s, %s ON data.is_primary_default=1 AND data.datatype=%d "
+                                               "AND data.contact_id = contacts.contact_id AND contacts.deleted = 0 "
+                                       "WHERE contacts.person_id = %d",
+                                       CTS_TABLE_CONTACTS, CTS_TABLE_DATA, CTSVC_DATA_EMAIL, id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               ctsvc_stmt_finalize(stmt);
+               CTS_ERR("ctsvc_stmt_step Fail(%d)", ret);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ret = contacts_record_create(_contacts_email._uri, (contacts_record_h*)&email);
+       if (email) {
+               char *temp;
+               email->id = ctsvc_stmt_get_int(stmt, 0);
+               email->is_default = ctsvc_stmt_get_int(stmt, 1);
+               email->type = ctsvc_stmt_get_int(stmt, 2);
+               temp = ctsvc_stmt_get_text(stmt, 3);
+               email->label = SAFE_STRDUP(temp);
+               temp = ctsvc_stmt_get_text(stmt, 4);
+               email->email_addr = SAFE_STRDUP(temp);
+
+               *record = (contacts_record_h)email;
+               ret = CONTACTS_ERROR_NONE;
+       }
+       else
+               CTS_ERR("contacts_record_create() Failed");
+
+       ctsvc_stmt_finalize(stmt);
+       return ret;
+}
+
+static inline int __ctsvc_get_person_default_image_value(int id, contacts_record_h *record)
+{
+       int ret;
+       cts_stmt stmt;
+       ctsvc_image_s *image;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "SELECT data.id, data.is_default, data.data1, data.data2, data.data3 "
+                               "FROM "CTS_TABLE_CONTACTS", "CTS_TABLE_DATA" "
+                               "ON data.is_primary_default=1 AND data.datatype=%d AND data.is_my_profile = 0 "
+                                       "AND data.contact_id = contacts.contact_id AND contacts.deleted = 0 "
+                               "WHERE contacts.person_id = %d",
+                                       CTSVC_DATA_IMAGE, id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ != ret) {
+               ctsvc_stmt_finalize(stmt);
+               CTS_ERR("ctsvc_stmt_step Fail(%d)", ret);
+               if (CONTACTS_ERROR_NONE == ret)
+                       return CONTACTS_ERROR_NO_DATA;
+               else
+                       return ret;
+       }
+
+       ret = contacts_record_create(_contacts_image._uri, (contacts_record_h*)&image);
+       if (image) {
+               char *temp;
+               image->id = ctsvc_stmt_get_int(stmt, 0);
+               image->is_default = ctsvc_stmt_get_int(stmt, 1);
+               image->type = ctsvc_stmt_get_int(stmt, 2);
+               temp = ctsvc_stmt_get_text(stmt, 3);
+               image->label = SAFE_STRDUP(temp);
+               temp = ctsvc_stmt_get_text(stmt, 4);
+               image->path = SAFE_STRDUP(temp);
+
+               *record = (contacts_record_h)image;
+               ret = CONTACTS_ERROR_NONE;
+       }
+       else
+               CTS_ERR("contacts_record_create() Failed");
+
+       ctsvc_stmt_finalize(stmt);
+       return ret;
+}
+
+static int __ctsvc_get_person_value(int op_code,
+               int person_id, contacts_record_h *record)
+{
+       int ret;
+
+       RETV_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER);
+
+       switch (op_code)
+       {
+       case CTSVC_GET_PERSON_DEFAULT_NUMBER_VALUE:
+               ret = __ctsvc_get_person_default_number_value(person_id, record);
+               RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "__ctsvc_get_person_default_number_value() Failed(%d)", ret);
+               break;
+       case CTSVC_GET_PERSON_DEFAULT_EMAIL_VALUE:
+               ret = __ctsvc_get_person_default_email_value(person_id, record);
+               RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "__ctsvc_get_person_default_email_value() Failed(%d)", ret);
+               break;
+       case CTSVC_GET_PERSON_DEFAULT_IMAGE_VALUE:
+               ret = __ctsvc_get_person_default_image_value(person_id, record);
+               RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "__ctsvc_get_person_default_image_value() Failed(%d)", ret);
+               break;
+       default:
+               CTS_ERR("Invalid parameter : The op_code(%d) is not supported", op_code);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (NULL == *record)
+               return CONTACTS_ERROR_NO_DATA;
+
+       return ret;
+}
+
+static inline int __ctsvc_put_person_default_name(int person_id, int contact_id)
+{
+       int ret;
+       int id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                       "SELECT person_id FROM %s WHERE contact_id=%d AND deleted = 0",
+                                       CTS_TABLE_CONTACTS, contact_id);
+
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "ctsvc_query_get_first_int_result() Failed(%d)", ret);
+
+       if (id == person_id) {
+               ret = ctsvc_begin_trans();
+               RETVM_IF(CONTACTS_ERROR_NONE > ret, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret);
+               snprintf(query, sizeof(query),
+                                               "UPDATE %s SET name_contact_id=%d WHERE person_id=%d",
+                                               CTS_TABLE_PERSONS, contact_id, person_id);
+
+               ret = ctsvc_query_exec(query);
+               if( CONTACTS_ERROR_NONE != ret )
+               {
+                       CTS_ERR( "ctsvc_query_exec() Failed(%d)", ret);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+               else
+               {
+                       ret = ctsvc_end_trans(true);
+                       if (ret < CONTACTS_ERROR_NONE)
+                       {
+                               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+                               return ret;
+                       }
+                       else
+                               return CONTACTS_ERROR_NONE;
+               }
+       }
+       else {
+               CTS_ERR("contact(%d) does not belong to person(%d), to person(%d)", contact_id, person_id, ret);
+               ret = CONTACTS_ERROR_NO_DATA;
+       }
+
+       return ret;
+}
+
+static inline int __ctsvc_put_person_default_image(int person_id, int id)
+{
+       int ret;
+       int is_default;
+       int contact_id;
+       cts_stmt stmt;
+       char *image_path;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE > ret, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "SELECT D.is_default, D.contact_id, D.data3 "
+                               "FROM "CTS_TABLE_DATA" D, "CTS_TABLE_CONTACTS" C "
+                               "ON D.contact_id = C.contact_id AND C.deleted = 0 "
+                               "WHERE D.datatype=%d AND D.is_my_profile = 0 AND C.person_id=%d AND D.id=%d",
+                               CTSVC_DATA_IMAGE, person_id, id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("ctsvc_query_prepare failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               ctsvc_stmt_finalize(stmt);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       is_default = ctsvc_stmt_get_int(stmt, 0);
+       contact_id = ctsvc_stmt_get_int(stmt, 1);
+       image_path = SAFE_STRDUP(ctsvc_stmt_get_text(stmt, 2));
+       ctsvc_stmt_finalize(stmt);
+
+       // unset is_primary_default of all data of the person
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_DATA" SET is_primary_default=0 WHERE datatype=%d AND is_my_profile = 0 "
+                               "AND contact_id IN (SELECT contact_id FROM "CTS_TABLE_CONTACTS" "
+                                                                               "WHERE person_id=%d AND deleted = 0) ",
+                               CTSVC_DATA_IMAGE, person_id);
+       ret = ctsvc_query_exec(query);
+       if (ret < CONTACTS_ERROR_NONE) {
+               CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret);
+               free(image_path);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       // unset is_default of all data of person if the data is not default
+       if (!is_default) {
+               snprintf(query, sizeof(query),
+                               "UPDATE "CTS_TABLE_DATA" SET is_default=0 WHERE datatype=%d  AND is_my_profile = 0 "
+                                       "AND contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id=%d) ",
+                                       CTSVC_DATA_IMAGE, id);
+
+               ret = ctsvc_query_exec(query);
+               if(CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret);
+                       free(image_path);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+       }
+
+       // set is_default, is _primary_default
+       snprintf(query, sizeof(query),
+                               "UPDATE "CTS_TABLE_DATA" SET is_primary_default=1, is_default=1 WHERE id=%d ", id);
+       ret = ctsvc_query_exec(query);
+       if( CONTACTS_ERROR_NONE != ret ) {
+               CTS_ERR( "ctsvc_query_exec() Failed(%d)", ret);
+               free(image_path);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       // update person's image_thumbnail_path
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_PERSONS" SET image_thumbnail_path=? WHERE person_id=%d ", person_id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if( NULL == stmt ) {
+               CTS_ERR( "ctsvc_query_prepare() Failed(%d)", ret);
+               free(image_path);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_stmt_bind_text(stmt, 1, image_path);
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               free(image_path);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       // update contact's image_thumbnail_path
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_CONTACTS" SET image_thumbnail_path=? WHERE contact_id=%d ", contact_id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if( NULL == stmt ) {
+               CTS_ERR( "ctsvc_query_prepare() Failed(%d)", ret);
+               free(image_path);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_stmt_bind_text(stmt, 1, image_path);
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               free(image_path);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       free(image_path);
+
+       ret = ctsvc_end_trans(true);
+       return ret;
+}
+
+static inline int __ctsvc_put_person_default_data(int person_id, int id, int datatype)
+{
+       int ret;
+       int is_default = 0;
+       int contact_id = 0;
+       int name_contact_id = 0;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt = NULL;
+       contacts_display_name_source_type_e source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_INVALID;
+
+       snprintf(query, sizeof(query),
+                       "SELECT D.is_default, D.contact_id FROM %s D, %s C "
+                               "ON (D.contact_id=C.contact_id AND C.deleted = 0) "
+                               "WHERE D.datatype=%d AND C.person_id=%d AND D.id=%d",
+                               CTS_TABLE_DATA, CTS_TABLE_CONTACTS, datatype, person_id, id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 != ret) {
+               CTS_ERR("ctsvc_stmt_step Fail(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               return ret;
+       }
+
+       is_default = ctsvc_stmt_get_int(stmt, 0);
+       contact_id = ctsvc_stmt_get_int(stmt, 1);
+
+       ctsvc_stmt_finalize(stmt);
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE > ret, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret);
+
+       // unset is_primary_default of all data of the person
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_DATA" SET is_primary_default=0 WHERE datatype=%d AND is_my_profile = 0 "
+                               "AND contact_id IN (SELECT contact_id FROM "CTS_TABLE_CONTACTS" "
+                                                                               "WHERE person_id=%d AND deleted = 0) ",
+                               datatype, person_id);
+
+       ret = ctsvc_query_exec(query);
+       if (ret < CONTACTS_ERROR_NONE) {
+               CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       // unset is_default of all data of person if the data is not default
+       if (!is_default) {
+               snprintf(query, sizeof(query),
+                               "UPDATE "CTS_TABLE_DATA" SET is_default=0 WHERE datatype=%d AND is_my_profile = 0 "
+                                       "AND contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id=%d) ",
+                                       datatype, id);
+
+               ret = ctsvc_query_exec(query);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+       }
+
+       // set is_default, is _primary_default
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_DATA" SET is_primary_default=1, is_default=1 WHERE id=%d ", id);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR( "ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (datatype == CTSVC_DATA_NUMBER)
+               source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NUMBER;
+       else if (datatype == CTSVC_DATA_EMAIL)
+               source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL;
+
+       if (CONTACTS_DISPLAY_NAME_SOURCE_TYPE_INVALID != source_type)
+               ctsvc_contact_update_display_name(contact_id, source_type);
+
+       snprintf(query, sizeof(query),
+                       "SELECT name_contact_id FROM "CTS_TABLE_PERSONS" WHERE person_id = %d", person_id);
+       ret = ctsvc_query_get_first_int_result(query, &name_contact_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR( "ctsvc_query_get_first_int_result() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (name_contact_id != contact_id) {
+               int org_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_INVALID;
+               snprintf(query, sizeof(query),
+                       "SELECT display_name_source FROM "CTS_TABLE_CONTACTS" WHERE contact_id = %d", name_contact_id);
+               ret = ctsvc_query_get_first_int_result(query, &org_source_type);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR( "ctsvc_query_get_first_int_result() Failed(%d)", ret);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+
+               if (org_source_type <= source_type) {
+                       snprintf(query, sizeof(query),
+                                               "UPDATE %s SET name_contact_id=%d WHERE person_id=%d",
+                                               CTS_TABLE_PERSONS, contact_id, person_id);
+                       ret = ctsvc_query_exec(query);
+                       if (CONTACTS_ERROR_NONE != ret) {
+                               CTS_ERR( "ctsvc_query_exec() Failed(%d)", ret);
+                               ctsvc_end_trans(false);
+                               return ret;
+                       }
+               }
+       }
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+void ctsvc_db_person_delete_callback(sqlite3_context * context,
+               int argc, sqlite3_value ** argv)
+{
+#ifdef _CONTACTS_IPC_SERVER
+       int person_id;
+
+       if (argc < 1) {
+               sqlite3_result_null(context);
+               return;
+       }
+
+       person_id = sqlite3_value_int(argv[0]);
+       ctsvc_change_subject_add_changed_person_id(CONTACTS_CHANGE_DELETED, person_id);
+
+#ifdef ENABLE_LOG_FEATURE
+       // update phonelog
+       // CASE : do not know the proper new person_id
+       ctsvc_db_phone_log_update_person_id(NULL, person_id, -1, false);
+#endif // ENABLE_LOG_FEATURE
+       sqlite3_result_null(context);
+       return;
+#endif
+}
+
+inline static const char* __ctsvc_get_image_filename(const char* src)
+{
+       const char* dir = CTSVC_CONTACT_IMG_FULL_LOCATION;
+       int pos=0;
+       while (dir[pos]==src[pos]) {
+               pos++;
+       }
+
+       if ('/' == src[pos])
+               return src + pos + 1;
+
+       return src+pos;
+}
+
+int ctsvc_person_aggregate(int person_id)
+{
+       int ret, len = 0;
+       int version;
+       int link_count;
+       int id = 0;
+       char *addressbook_ids = NULL;
+       int addressbooks_len = 100;
+       int name_contact_id = 0;
+       int person_name_contact_id = 0;
+       int display_name_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_INVALID;
+       char query[CTS_SQL_MIN_LEN] = {0};
+       char *ringtone_path = NULL;
+       char *image_thumbnail_path = NULL;
+       char *vibration = NULL;
+       char *message_alert = NULL;
+       char *status = NULL;
+       const char *temp;
+       cts_stmt stmt;
+       ctsvc_person_s *person;
+       bool person_is_favorite = false;
+
+       // person aggregation : person link/unlink, contact insert (auto link), contact delete, garbage collection (addressbook delete)
+       // It should be get all contacts of person regardless of permission
+       // Get person info directly instead of contacts_db_get_record( _contacts_person._uri, person_id, (contacts_record_h*)&person);
+       snprintf(query, sizeof(query),
+                       "SELECT person_id, "
+                                       "name_contact_id, "
+                                       "image_thumbnail_path, "
+                                       "ringtone_path, "
+                                       "vibration, "
+                                       "message_alert "
+                               "FROM "CTS_TABLE_PERSONS" "
+                               "WHERE persons.person_id = %d", person_id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       if (1 != ctsvc_stmt_step(stmt)) {
+          CTS_ERR("ctsvc_stmt_step() Failed\n");
+          return CONTACTS_ERROR_DB;
+       }
+       ret = contacts_record_create(_contacts_person._uri, (contacts_record_h*)&person);
+       if (CONTACTS_ERROR_NONE != ret) {
+          CTS_ERR("contacts_record_create() Failed\n");
+          return CONTACTS_ERROR_INTERNAL;
+       }
+       person->person_id = ctsvc_stmt_get_int(stmt, 0);
+       person->name_contact_id = ctsvc_stmt_get_int(stmt, 1);
+       temp = ctsvc_stmt_get_text(stmt, 2);
+       person->image_thumbnail_path = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, 3);
+       person->ringtone_path = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, 4);
+       person->vibration = SAFE_STRDUP(temp);
+       temp = ctsvc_stmt_get_text(stmt, 5);
+       person->message_alert = SAFE_STRDUP(temp);
+       ctsvc_stmt_finalize(stmt);
+
+       // check image_thumbnail_path
+       if (person->image_thumbnail_path) {
+               temp = __ctsvc_get_image_filename(person->image_thumbnail_path);
+               snprintf(query, sizeof(query),
+                       "SELECT D.id FROM "CTS_TABLE_CONTACTS" C, "CTS_TABLE_DATA" D "
+                               "WHERE C.person_id=%d AND C.contact_id=D.contact_id AND C.deleted = 0 "
+                                       "AND D.datatype=%d AND D.is_primary_default = 1 AND D.data3='%s'",
+                               person->person_id, CTSVC_DATA_IMAGE, temp);
+               ret = ctsvc_query_get_first_int_result(query, &id);
+               if(ret == CONTACTS_ERROR_NONE) {
+                       image_thumbnail_path = SAFE_STRDUP(temp);
+               }
+       }
+       else {
+               image_thumbnail_path = NULL;
+       }
+
+       // check name_contact_id
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id FROM %s "
+                       "WHERE person_id=%d AND contact_id=%d AND deleted = 0",
+                       CTS_TABLE_CONTACTS, person->person_id, person->name_contact_id);
+
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       if(ret == CONTACTS_ERROR_NONE) {
+               name_contact_id = person->name_contact_id;
+               person_name_contact_id = person->name_contact_id;
+       }
+       else {
+               name_contact_id = 0;
+               person_name_contact_id = 0;
+       }
+
+       // get status of person
+       snprintf(query, sizeof(query),
+               "SELECT a.status FROM %s c, %s a "
+               "ON c.contact_id = a.contact_id AND c.deleted = 0 "
+               "WHERE c.person_id=%d "
+               "ORDER BY timestamp DESC LIMIT 1",
+               CTS_TABLE_CONTACTS, CTS_TABLE_ACTIVITIES, person->person_id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               free(image_thumbnail_path);
+               contacts_record_destroy((contacts_record_h)person, true);
+               return ret;
+       }
+
+       if (1 == ctsvc_stmt_step(stmt)) {
+               temp = ctsvc_stmt_get_text(stmt, 0);
+               status = SAFE_STRDUP(temp);
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       // check ringtone_path
+       if (person->ringtone_path) {
+               snprintf(query, sizeof(query),
+                       "SELECT C.contact_id FROM "CTS_TABLE_CONTACTS" C "
+                               "WHERE C.person_id=%d AND C.deleted = 0 "
+                                       "AND C.ringtone_path = '%s'",
+                               person->person_id, person->ringtone_path);
+               ret = ctsvc_query_get_first_int_result(query, &id);
+               if(ret == CONTACTS_ERROR_NONE) {
+                       ringtone_path = SAFE_STRDUP(person->ringtone_path);
+               }
+       }
+       else {
+               ringtone_path = NULL;
+       }
+
+       // check vibration
+       if (person->vibration) {
+               snprintf(query, sizeof(query),
+                       "SELECT C.contact_idFROM "CTS_TABLE_CONTACTS" C "
+                               "WHERE C.person_id=%d AND C.deleted = 0 "
+                                       "AND C.vibration = '%s'",
+                               person->person_id, person->vibration);
+               ret = ctsvc_query_get_first_int_result(query, &id);
+               if(ret == CONTACTS_ERROR_NONE) {
+                       vibration = SAFE_STRDUP(person->vibration);
+               }
+       }
+       else {
+               vibration = NULL;
+       }
+
+       // check vibration
+       if (person->message_alert) {
+               snprintf(query, sizeof(query),
+                       "SELECT C.contact_id FROM "CTS_TABLE_CONTACTS" C "
+                               "WHERE C.person_id=%d AND C.deleted = 0 "
+                                       "AND C.message_alert = '%s'",
+                               person->person_id, person->message_alert);
+               ret = ctsvc_query_get_first_int_result(query, &id);
+               if(ret == CONTACTS_ERROR_NONE) {
+                       message_alert = SAFE_STRDUP(person->message_alert);
+               }
+       }
+       else {
+               message_alert = NULL;
+       }
+       contacts_record_destroy((contacts_record_h)person, true);
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, contacts.addressbook_id, display_name_source, "
+                               "image_thumbnail_path, ringtone_path, vibration, message_alert, is_favorite "
+                       "FROM %s "
+                       "WHERE person_id = %d AND contacts.deleted = 0 "
+                       "ORDER BY contact_id",
+                       CTS_TABLE_CONTACTS, person_id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               free(image_thumbnail_path);
+               free(ringtone_path);
+               free(vibration);
+               free(message_alert);
+               free(status);
+               return ret;
+       }
+
+       link_count = 0;
+       len = 0;
+       while ((ret = ctsvc_stmt_step(stmt))) {
+               const char *temp_str;
+               int i = 0;
+               int contact_id;
+               int addressbook_id;
+               int contact_display_name_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_INVALID;
+               char *contact_ringtone_path = NULL;
+               char *contact_image_thumbnail_path = NULL;
+               char *contact_vibration = NULL;
+               char *contact_message_alert = NULL;
+               bool is_favorite = false;
+               char addr[10] = {0};
+               int addr_len = 0;
+
+               contact_id = ctsvc_stmt_get_int(stmt, i++);
+               addressbook_id = ctsvc_stmt_get_int(stmt, i++);
+               contact_display_name_source_type = ctsvc_stmt_get_int(stmt, i++);
+               temp = ctsvc_stmt_get_text(stmt, i++);
+               if (temp)
+                       contact_image_thumbnail_path = strdup(temp);
+               temp = ctsvc_stmt_get_text(stmt, i++);
+               contact_ringtone_path = SAFE_STRDUP(temp);
+               temp = ctsvc_stmt_get_text(stmt, i++);
+               contact_vibration = SAFE_STRDUP(temp);
+               temp = ctsvc_stmt_get_text(stmt, i++);
+               contact_message_alert = SAFE_STRDUP(temp);
+               is_favorite = ctsvc_stmt_get_int(stmt, i++);
+
+               link_count++;
+
+               if (contact_display_name_source_type > display_name_source_type) {
+                       display_name_source_type = contact_display_name_source_type;
+                       name_contact_id = contact_id;
+               }
+               else if (contact_display_name_source_type == display_name_source_type) {
+                       if (name_contact_id != person_name_contact_id && person_name_contact_id != 0)
+                               name_contact_id = person_name_contact_id;
+                       else if (person_name_contact_id == 0 && name_contact_id == 0)
+                               name_contact_id = contact_id;
+               }
+
+               addr_len = snprintf(addr, sizeof(addr), "%d%s", addressbook_id, ADDRESSBOOK_ID_DELIM);
+               if (NULL == addressbook_ids)
+                       addressbook_ids = calloc(addressbooks_len+1, sizeof(char));
+               else if (addressbooks_len <= strlen(addressbook_ids)+addr_len) {
+                       addressbooks_len = MAX(addressbooks_len*2, strlen(addressbook_ids)+addr_len+1);
+                       addressbook_ids = realloc(addressbook_ids, addressbooks_len);
+               }
+
+               len += snprintf(addressbook_ids + len, addressbooks_len -len, "%d%s", addressbook_id, ADDRESSBOOK_ID_DELIM );
+
+               if (!image_thumbnail_path && contact_image_thumbnail_path && *contact_image_thumbnail_path) {
+                       temp = __ctsvc_get_image_filename(contact_image_thumbnail_path);
+                       image_thumbnail_path = SAFE_STRDUP(temp);
+                       // update data table : is_primary_default
+               }
+               free(contact_image_thumbnail_path);
+
+               temp_str = contact_ringtone_path;
+               if (!ringtone_path && temp_str && strlen(temp_str))
+                       ringtone_path = SAFE_STRDUP(temp_str);
+               free(contact_ringtone_path);
+
+               temp_str = contact_vibration;
+               if (!vibration && temp_str && strlen(temp_str))
+                       vibration = SAFE_STRDUP(temp_str);
+               free(contact_vibration);
+
+               temp_str = contact_message_alert;
+               if (!message_alert && temp_str && strlen(temp_str))
+                       message_alert = SAFE_STRDUP(temp_str);
+               free(contact_message_alert);
+
+               if (is_favorite)
+                       person_is_favorite = true;
+       }
+       ctsvc_stmt_finalize(stmt);
+       version = ctsvc_get_next_ver();
+
+       snprintf(query, sizeof(query),
+               "UPDATE "CTS_TABLE_PERSONS" SET dirty=0, name_contact_id = %d, changed_ver = %d, "
+                       "has_phonenumber = EXISTS(SELECT contact_id FROM "CTS_TABLE_CONTACTS" "
+                                                                                       "WHERE person_id = %d AND has_phonenumber = 1 AND deleted = 0), "
+                       "has_email = EXISTS(SELECT contact_id FROM "CTS_TABLE_CONTACTS" "
+                                                                       "WHERE person_id = %d AND has_email = 1 AND deleted = 0), "
+                       "link_count = %d, addressbook_ids = ?, ringtone_path=?, vibration=?, message_alert=?, status=?, image_thumbnail_path=? "
+                       "WHERE person_id = %d ",
+                       name_contact_id, version, person_id,
+                       person_id, link_count, person_id);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       if (NULL == stmt) {
+               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+               free(addressbook_ids);
+               free(image_thumbnail_path);
+               free(ringtone_path);
+               free(vibration);
+               free(message_alert);
+               free(status);
+               return ret;
+       }
+
+       if (addressbook_ids)
+               ctsvc_stmt_bind_text(stmt, 1, addressbook_ids);
+       if (ringtone_path)
+               ctsvc_stmt_bind_text(stmt, 2, ringtone_path);
+       if (vibration)
+               ctsvc_stmt_bind_text(stmt, 3, vibration);
+       if (message_alert)
+               ctsvc_stmt_bind_text(stmt, 4, message_alert);
+       if (status)
+               ctsvc_stmt_bind_text(stmt, 5, status);
+       if (image_thumbnail_path)
+               ctsvc_stmt_bind_text(stmt, 6, image_thumbnail_path);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d)", ret);
+               ctsvc_stmt_finalize(stmt);
+               free(addressbook_ids);
+               free(image_thumbnail_path);
+               free(ringtone_path);
+               free(vibration);
+               free(message_alert);
+               free(status);
+               return ret;
+       }
+
+       ctsvc_stmt_finalize(stmt);
+
+       free(addressbook_ids);
+       free(image_thumbnail_path);
+       free(ringtone_path);
+       free(vibration);
+       free(message_alert);
+       free(status);
+
+       if (!person_is_favorite) {
+               snprintf(query, sizeof(query),
+                               "DELETE FROM "CTS_TABLE_FAVORITES" WHERE person_id = %d", person_id);
+               ret = ctsvc_query_exec(query);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+                       return ret;
+               }
+       }
+
+       ctsvc_set_person_noti();
+#ifdef _CONTACTS_IPC_SERVER
+       ctsvc_change_subject_add_changed_person_id(CONTACTS_CHANGE_UPDATED, person_id);
+#endif
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static bool __ctsvc_get_person_favorite_info(int person_id, double *priority)
+{
+       int ret;
+       cts_stmt stmt;
+       char query[CTS_SQL_MIN_LEN] = {0};
+       snprintf(query, sizeof(query),
+                       "SELECT favorite_prio FROM "CTS_TABLE_FAVORITES" WHERE person_id = %d", person_id);
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (1 == ret) {
+               *priority = ctsvc_stmt_get_dbl(stmt, 0);
+               ctsvc_stmt_finalize(stmt);
+               return true;
+       }
+       ctsvc_stmt_finalize(stmt);
+       return false;
+}
+
+API int contacts_person_link_person(int base_person_id, int person_id)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+       int default_number_id = 0;
+       int default_email_id = 0;
+       int default_image_id = 0;
+       contacts_record_h record = NULL;
+       bool base_is_favorite = false;
+       bool is_favorite = false;
+       double favorite_prio = 0.0;
+
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_WRITE), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact write (person)");
+       RETVM_IF(base_person_id == person_id, CONTACTS_ERROR_INVALID_PARAMETER,
+               "Invalid parameter : base_person_id(%d), person_id(%d)", base_person_id, person_id);
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE > ret, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret);
+
+       ret = __ctsvc_get_person_value(CTSVC_GET_PERSON_DEFAULT_NUMBER_VALUE, base_person_id, &record);
+       if (CONTACTS_ERROR_NONE != ret ) {
+               ret = __ctsvc_get_person_value(CTSVC_GET_PERSON_DEFAULT_NUMBER_VALUE, person_id, &record);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       contacts_record_get_int(record, CTSVC_PROPERTY_NUMBER_ID, &default_number_id);
+                       contacts_record_destroy(record, true);
+               }
+       }
+       else {
+               contacts_record_get_int(record, CTSVC_PROPERTY_NUMBER_ID, &default_number_id);
+               contacts_record_destroy(record, true);
+       }
+
+       ret = __ctsvc_get_person_value(CTSVC_GET_PERSON_DEFAULT_EMAIL_VALUE, base_person_id, &record);
+       if (CONTACTS_ERROR_NONE != ret ) {
+               ret = __ctsvc_get_person_value(CTSVC_GET_PERSON_DEFAULT_EMAIL_VALUE, person_id, &record);
+               if (CONTACTS_ERROR_NONE == ret ) {
+                       contacts_record_get_int(record, CTSVC_PROPERTY_EMAIL_ID, &default_email_id);
+                       contacts_record_destroy(record, true);
+               }
+       }
+       else {
+               contacts_record_get_int(record, CTSVC_PROPERTY_EMAIL_ID, &default_email_id);
+               contacts_record_destroy(record, true);
+       }
+
+       ret = __ctsvc_get_person_value(CTSVC_GET_PERSON_DEFAULT_IMAGE_VALUE, base_person_id, &record);
+       if (CONTACTS_ERROR_NONE != ret ) {
+               ret = __ctsvc_get_person_value(CTSVC_GET_PERSON_DEFAULT_IMAGE_VALUE, person_id, &record);
+               if (CONTACTS_ERROR_NONE == ret ) {
+                       contacts_record_get_int(record, CTSVC_PROPERTY_IMAGE_ID, &default_image_id);
+                       contacts_record_destroy(record, true);
+               }
+       }
+       else {
+               contacts_record_get_int(record, CTSVC_PROPERTY_IMAGE_ID, &default_image_id);
+               contacts_record_destroy(record, true);
+       }
+
+       base_is_favorite = __ctsvc_get_person_favorite_info(base_person_id, &favorite_prio);
+       if (!base_is_favorite)
+               is_favorite = __ctsvc_get_person_favorite_info(person_id, &favorite_prio);
+
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET person_id = %d WHERE person_id = %d AND deleted = 0",
+                       CTS_TABLE_CONTACTS, base_person_id, person_id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_person_aggregate(base_person_id);
+
+       if (default_number_id)
+               __ctsvc_put_person_default_data(base_person_id, default_number_id, CTSVC_DATA_NUMBER);
+
+       if (default_email_id)
+               __ctsvc_put_person_default_data(base_person_id, default_email_id, CTSVC_DATA_EMAIL);
+
+       if (default_image_id)
+               __ctsvc_put_person_default_image(base_person_id, default_image_id);
+
+#ifdef ENABLE_LOG_FEATURE
+       // update phonelog
+       // Updating phonelog person_id before deleting person
+       // Because, when deleting, ctsvc_db_person_delete_callback will be called
+       // the logic takes more time to find proper person_id (base_person_id)
+       ctsvc_db_phone_log_update_person_id(NULL, person_id, base_person_id, true);
+#endif // ENABLE_LOG_FEATURE
+
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE person_id = %d",
+                       CTS_TABLE_PERSONS, person_id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+//#ifdef _CONTACTS_IPC_SERVER
+//     It will be added in ctsvc_db_person_delete_callback
+//     ctsvc_change_subject_add_changed_person_id(CONTACTS_CHANGE_DELETED, person_id);
+//#endif
+
+       if (is_favorite) {
+               snprintf(query, sizeof(query),
+                               "INSERT INTO "CTS_TABLE_FAVORITES" values(%d, %f)", base_person_id, favorite_prio);
+               ret = ctsvc_query_exec(query);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+                       ctsvc_end_trans(false);
+                       return ret;
+               }
+       }
+
+       ctsvc_set_person_noti();
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_update_primary_default_data(int person_id)
+{
+       int ret;
+       contacts_record_h record = NULL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+       cts_stmt stmt;
+
+       ret = __ctsvc_get_person_value(CTSVC_GET_PERSON_DEFAULT_NUMBER_VALUE, person_id, &record);
+       if (CONTACTS_ERROR_NONE != ret ) {
+               snprintf(query, sizeof(query),
+                               "SELECT contact_id "
+                               "FROM %s "
+                               "WHERE person_id = %d AND deleted = 0 "
+                               "ORDER BY contact_id",
+                               CTS_TABLE_CONTACTS, person_id);
+               ret = ctsvc_query_prepare(query, &stmt);
+               RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+               while (1 == ctsvc_stmt_step(stmt)) {
+                       int contact_id = ctsvc_stmt_get_int(stmt, 0);
+                       cts_stmt stmt_number;
+
+                       snprintf(query, sizeof(query),
+                                       "SELECT id, is_default FROM %s "
+                                       "WHERE contact_id = %d AND datatype = %d AND is_default = 1 AND is_my_profile = 0",
+                                       CTS_TABLE_DATA, contact_id, CTSVC_DATA_NUMBER);
+
+                       ret = ctsvc_query_prepare(query, &stmt_number);
+                       if (NULL == stmt_number) {
+                               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+                               ctsvc_stmt_finalize(stmt);
+                               return ret;
+                       }
+
+                       if( 1 == ctsvc_stmt_step(stmt_number) ) {
+                               int default_number_id = ctsvc_stmt_get_int(stmt_number, 0);
+                               __ctsvc_put_person_default_data(person_id, default_number_id, CTSVC_DATA_NUMBER);
+                               ctsvc_stmt_finalize(stmt_number);
+                               break;
+                       }
+                       ctsvc_stmt_finalize(stmt_number);
+               }
+               ctsvc_stmt_finalize(stmt);
+       }
+       else {
+               contacts_record_destroy(record, true);
+       }
+
+       ret = __ctsvc_get_person_value(CTSVC_GET_PERSON_DEFAULT_EMAIL_VALUE, person_id, &record);
+       if (CONTACTS_ERROR_NONE != ret ) {
+               snprintf(query, sizeof(query),
+                               "SELECT contact_id "
+                               "FROM %s "
+                               "WHERE person_id = %d AND deleted = 0 "
+                               "ORDER BY contact_id",
+                               CTS_TABLE_CONTACTS, person_id);
+               ret = ctsvc_query_prepare(query, &stmt);
+               RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+               while (1 == ctsvc_stmt_step(stmt)) {
+                       int contact_id = ctsvc_stmt_get_int(stmt, 0);
+                       cts_stmt stmt_email;
+
+                       snprintf(query, sizeof(query),
+                                       "SELECT id, is_default FROM %s "
+                                       "WHERE contact_id = %d AND datatype = %d AND is_default = 1 AND is_my_profile = 0",
+                                       CTS_TABLE_DATA, contact_id, CTSVC_DATA_EMAIL);
+
+                       ret = ctsvc_query_prepare(query, &stmt_email);
+                       if (NULL == stmt_email) {
+                               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+                               ctsvc_stmt_finalize(stmt);
+                               return ret;
+                       }
+
+                       if( 1 == ctsvc_stmt_step(stmt_email))   {
+                               int default_email_id = ctsvc_stmt_get_int(stmt_email, 0);
+                               __ctsvc_put_person_default_data(person_id, default_email_id, CTSVC_DATA_EMAIL);
+                               ctsvc_stmt_finalize(stmt_email);
+                               break;
+                       }
+                       ctsvc_stmt_finalize(stmt_email);
+               }
+               ctsvc_stmt_finalize(stmt);
+       }
+       else {
+               contacts_record_destroy(record, true);
+       }
+
+       ret = __ctsvc_get_person_value(CTSVC_GET_PERSON_DEFAULT_IMAGE_VALUE, person_id, &record);
+       if (CONTACTS_ERROR_NONE != ret ) {
+               snprintf(query, sizeof(query),
+                               "SELECT contact_id "
+                               "FROM %s "
+                               "WHERE person_id = %d AND deleted = 0 "
+                               "ORDER BY contact_id",
+                               CTS_TABLE_CONTACTS, person_id);
+               ret = ctsvc_query_prepare(query, &stmt);
+               RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+               while ( 1 == ctsvc_stmt_step(stmt)) {
+                       int contact_id = ctsvc_stmt_get_int(stmt, 0);
+                       cts_stmt stmt_image;
+
+                       snprintf(query, sizeof(query),
+                                       "SELECT id, is_default FROM %s "
+                                       "WHERE contact_id = %d AND datatype = %d AND is_default = 1 AND is_my_profile = 0",
+                                       CTS_TABLE_DATA, contact_id, CTSVC_DATA_IMAGE);
+
+                       ret = ctsvc_query_prepare(query, &stmt_image);
+                       if (NULL == stmt_image) {
+                               CTS_ERR("DB error : ctsvc_query_prepare() Failed(%d)", ret);
+                               ctsvc_stmt_finalize(stmt);
+                               return ret;
+                       }
+
+                       if( 1 == ctsvc_stmt_step(stmt_image))   {
+                               int default_image_id = ctsvc_stmt_get_int(stmt_image, 0);
+                               __ctsvc_put_person_default_image(person_id, default_image_id);
+                               ctsvc_stmt_finalize(stmt_image);
+                               break;
+                       }
+                       ctsvc_stmt_finalize(stmt_image);
+               }
+               ctsvc_stmt_finalize(stmt);
+       }
+       else {
+               contacts_record_destroy(record, true);
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_person_unlink_contact(int person_id, int contact_id, int* out_person_id )
+{
+       int ret;
+       int id;
+       int link_count = 0;
+       char query[CTS_SQL_MIN_LEN] = {0};
+       contacts_record_h record = NULL;
+       bool is_favorite = false;
+       double priority = 0.0;
+
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_WRITE), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact write (person)");
+       RETVM_IF(person_id <= 0 || contact_id <= 0 , CONTACTS_ERROR_INVALID_PARAMETER,
+               "Invalid parameter : person_id(%d), person_id(%d)", person_id, person_id);
+
+       if (out_person_id)
+               *out_person_id = 0;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "SELECT link_count FROM "CTS_TABLE_PERSONS" WHERE person_id=%d", person_id);
+       ret = ctsvc_query_get_first_int_result(query, &link_count);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       if (link_count == 1) {
+               CTS_ERR("This person(%d) has one contact(%d)", person_id, contact_id);
+               ctsvc_end_trans(false);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+
+       ret = ctsvc_db_contact_get(contact_id, (contacts_record_h*)&record);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_db_contact_get() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       // create new person
+       id = ctsvc_db_insert_person(record);
+       if (CONTACTS_ERROR_NONE > id) {
+               CTS_ERR("ctsvc_db_insert_person() Failed(%d)", id);
+               ctsvc_end_trans(false);
+               contacts_record_destroy(record, true);
+               return id;
+       }
+
+       // insert statistic info for new person
+       snprintf(query, sizeof(query),
+                       "INSERT INTO %s (person_id, usage_type, times_used) "
+                       "SELECT %d, usage_type, times_used FROM %s WHERE person_id = %d",
+                       CTS_TABLE_CONTACT_STAT, id, CTS_TABLE_CONTACT_STAT, person_id );
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               contacts_record_destroy(record, true);
+               return ret;
+       }
+
+       is_favorite = __ctsvc_get_person_favorite_info(person_id, &priority);
+
+       // update person_id of unlinked contact
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET person_id = %d WHERE contact_id = %d",
+                       CTS_TABLE_CONTACTS, id, contact_id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               contacts_record_destroy(record, true);
+               return ret;
+       }
+
+       // update bsae person info
+       ret = ctsvc_person_aggregate(person_id);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_person_aggregate(%d) Failed(%d)", person_id, ret);
+               ctsvc_end_trans(false);
+               contacts_record_destroy(record, true);
+               return ret;
+       }
+
+       if (is_favorite && ((ctsvc_contact_s*)record)->is_favorite) {
+               snprintf(query, sizeof(query),
+                               "INSERT OR REPLACE INTO "CTS_TABLE_FAVORITES" values(%d, %f)", id, priority);
+               ret = ctsvc_query_exec(query);
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+                       ctsvc_end_trans(false);
+                       contacts_record_destroy(record, true);
+                       return ret;
+               }
+       }
+       contacts_record_destroy(record, true);
+
+       __ctsvc_update_primary_default_data(person_id);
+
+#ifdef ENABLE_LOG_FEATURE
+       // update phonelog
+       ctsvc_db_phone_log_update_person_id(NULL, person_id, id, false);
+#endif // ENABLE_LOG_FEATURE
+
+       if (out_person_id)
+               *out_person_id = id;
+       ctsvc_set_person_noti();
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_person_do_garbage_collection(void)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       snprintf(query, sizeof(query), "SELECT person_id FROM "CTS_TABLE_PERSONS" WHERE dirty=1");
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       while ( 1 /*CTS_TRUE*/ == ctsvc_stmt_step(stmt)) {
+               int person_id;
+               person_id = ctsvc_stmt_get_int(stmt, 0);
+               ctsvc_person_aggregate(person_id);
+#ifdef ENABLE_LOG_FEATURE
+               // update phonelog
+               ctsvc_db_phone_log_update_person_id(NULL, person_id, -1, false);
+#endif // ENABLE_LOG_FEATURE
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_person_reset_usage(int person_id, contacts_usage_type_e type)
+{
+       int ret ;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_WRITE), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact write (person)");
+       RETVM_IF(person_id <= 0, CONTACTS_ERROR_INVALID_PARAMETER,"contact_id should be greater than 0");
+
+       snprintf(query, sizeof(query),
+               "UPDATE %s SET times_used = 0 WHERE person_id = %d AND usage_type = %d",
+               CTS_TABLE_CONTACT_STAT, person_id, type);
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_person_set_favorite_order(int person_id, int front_person_id, int back_person_id)
+{
+       int ret;
+       double front_prio = 0.0;
+       double back_prio = 0.0;
+       double prio;
+       cts_stmt stmt;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_WRITE), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact write");
+
+       snprintf(query, sizeof(query), "SELECT favorite_prio FROM "CTS_TABLE_FAVORITES" WHERE person_id = ?");
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       ctsvc_stmt_bind_int(stmt, 1, front_person_id);
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/  == ret)
+               front_prio = ctsvc_stmt_get_dbl(stmt, 0);
+       ctsvc_stmt_reset(stmt);
+       ctsvc_stmt_bind_int(stmt, 1, back_person_id);
+       ret = ctsvc_stmt_step(stmt);
+       if (1 /*CTS_TRUE*/ == ret)
+               back_prio = ctsvc_stmt_get_dbl(stmt, 0);
+       ctsvc_stmt_finalize(stmt);
+
+       RETVM_IF(0.0 == front_prio && 0.0 == back_prio, CONTACTS_ERROR_INVALID_PARAMETER,
+                       "The indexes for front and back are invalid.");
+
+       if (0.0 == back_prio)
+               prio = front_prio + 1;
+       else
+               prio = (front_prio + back_prio) / 2;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET favorite_prio = %f WHERE person_id = %d",
+                       CTS_TABLE_FAVORITES, prio, person_id);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ctsvc_set_person_noti();
+
+       ret = ctsvc_end_trans(true);
+       if (ret < CONTACTS_ERROR_NONE)
+       {
+               CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret);
+               return ret;
+       }
+       else
+               return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_person_set_default_property(contacts_person_property_e property, int person_id,
+               int id)
+{
+       int ret;
+
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_WRITE), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact write (person)");
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, CONTACTS_ERROR_DB, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       switch(property) {
+       case CONTACTS_PERSON_PROPERTY_NAME_CONTACT:
+               ret = __ctsvc_put_person_default_name(person_id, id);           // contact id
+               break;
+       case CONTACTS_PERSON_PROPERTY_NUMBER:
+               ret = __ctsvc_put_person_default_data(person_id, id, CTSVC_DATA_NUMBER);        // number id
+               break;
+       case CONTACTS_PERSON_PROPERTY_EMAIL:
+               ret = __ctsvc_put_person_default_data(person_id, id, CTSVC_DATA_EMAIL);         // email id
+               break;
+       case CONTACTS_PERSON_PROPERTY_IMAGE:
+               ret = __ctsvc_put_person_default_image(person_id, id);          // image id
+               break;
+       default:
+               ret = CONTACTS_ERROR_INVALID_PARAMETER;
+               break;
+       }
+       if (ret < CONTACTS_ERROR_NONE) {
+               CTS_ERR("contacts_person_set_default_property() Failed(%d) : person property (%d)", ret, property);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+#ifdef _CONTACTS_IPC_SERVER
+       ctsvc_change_subject_add_changed_person_id(CONTACTS_CHANGE_UPDATED, person_id);
+#endif
+       ctsvc_set_person_noti();
+       ret = ctsvc_end_trans(true);
+
+       return ret;
+}
+
+API int contacts_person_get_default_property(contacts_person_property_e property, int person_id,
+               int *id)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       RETVM_IF(person_id <= 0 || id == NULL, CONTACTS_ERROR_INVALID_PARAMETER,"id should be greater than 0");
+       *id = 0;
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_READ), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact read (contact)");
+
+       switch(property) {
+       case CONTACTS_PERSON_PROPERTY_NAME_CONTACT:
+               snprintf(query, sizeof(query),
+                               "SELECT name_contact_id FROM "CTS_TABLE_PERSONS" WHERE person_id = %d",
+                                       person_id);
+               break;
+       case CONTACTS_PERSON_PROPERTY_NUMBER:
+               snprintf(query, sizeof(query),
+                               "SELECT id FROM "CTS_TABLE_DATA" WHERE is_primary_default = 1 AND datatype = %d AND is_my_profile = 0 AND "
+                                       "contact_id in (SELECT contact_id FROM "CTS_TABLE_CONTACTS" "
+                                                                               "WHERE person_id = %d AND deleted = 0)",
+                                       CTSVC_DATA_NUMBER, person_id);
+               break;
+       case CONTACTS_PERSON_PROPERTY_EMAIL:
+               snprintf(query, sizeof(query),
+                               "SELECT id FROM "CTS_TABLE_DATA" WHERE is_primary_default = 1 AND datatype = %d AND is_my_profile = 0 AND "
+                                       "contact_id in (SELECT contact_id FROM "CTS_TABLE_CONTACTS" "
+                                                                               "WHERE person_id = %d AND deleted = 0)",
+                                       CTSVC_DATA_EMAIL, person_id);
+               break;
+       case CONTACTS_PERSON_PROPERTY_IMAGE:
+               snprintf(query, sizeof(query),
+                               "SELECT id FROM "CTS_TABLE_DATA" WHERE is_primary_default = 1 AND datatype = %d AND is_my_profile = 0 AND "
+                                       "contact_id in (SELECT contact_id FROM "CTS_TABLE_CONTACTS" "
+                                                                               "WHERE person_id = %d AND deleted = 0)",
+                                       CTSVC_DATA_IMAGE, person_id);
+               break;
+       default:
+               ret = CONTACTS_ERROR_INVALID_PARAMETER;
+               break;
+       }
+
+       if (*query) {
+               int result = 0;
+               ret = ctsvc_query_get_first_int_result(query, &result);
+               RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "ctsvc_query_get_first_int_result failed(%d)", ret);
+               *id = result;
+       }
+
+       return ret;
+}
+
diff --git a/native/ctsvc_person.h b/native/ctsvc_person.h
new file mode 100644 (file)
index 0000000..677b98d
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CTSVC_PERSON_H__
+#define __TIZEN_SOCIAL_CTSVC_PERSON_H__
+
+#include "ctsvc_sqlite.h"
+
+int ctsvc_person_do_garbage_collection(void);
+int ctsvc_person_aggregate(int person_id);
+void ctsvc_db_person_delete_callback(sqlite3_context * context, int argc, sqlite3_value ** argv);
+
+#endif // __TIZEN_SOCIAL_CTSVC_PERSON_H__
diff --git a/native/ctsvc_phonelog.c b/native/ctsvc_phonelog.c
new file mode 100644 (file)
index 0000000..4b13001
--- /dev/null
@@ -0,0 +1,354 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#include "contacts_phone_log_internal.h"
+
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_number_utils.h"
+#include "ctsvc_localize_utils.h"
+#include "ctsvc_setting.h"
+
+#ifdef _CONTACTS_IPC_SERVER
+#include "ctsvc_server_change_subject.h"
+#ifdef ENABLE_SIM_FEATURE
+#include "ctsvc_server_sim.h"
+#endif // ENABLE_SIM_FEATURE
+#endif
+
+API int contacts_phone_log_reset_statistics()
+{
+       char query[CTS_SQL_MIN_LEN] = {0};
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_PHONELOG_WRITE), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact write (phonelog)");
+       snprintf(query, sizeof(query),"DELETE FROM "CTS_TABLE_PHONELOG_STAT);
+       return ctsvc_query_exec(query);
+}
+
+API int contacts_phone_log_delete(contacts_phone_log_delete_e op, ...)
+{
+       int ret;
+       int extra_data1;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       char *number = NULL;
+       va_list args;
+
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_PHONELOG_WRITE), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact write (phonelog)");
+       switch(op) {
+       case CONTACTS_PHONE_LOG_DELETE_BY_ADDRESS:
+               va_start(args, op);
+               number = va_arg(args, char *);
+               va_end(args);
+               RETV_IF(NULL == number, CONTACTS_ERROR_INVALID_PARAMETER);
+               snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_PHONELOGS" WHERE number = '%s'", number);
+               break;
+       case CONTACTS_PHONE_LOG_DELETE_BY_MESSAGE_EXTRA_DATA1:
+               va_start(args, op);
+               extra_data1 = va_arg(args, int);
+               va_end(args);
+               snprintf(query, sizeof(query),
+                               "DELETE FROM "CTS_TABLE_PHONELOGS" "
+                               "WHERE data1 = %d AND %d <= log_type AND log_type <= %d",
+                                               extra_data1, CONTACTS_PLOG_TYPE_MMS_INCOMMING, CONTACTS_PLOG_TYPE_MMS_BLOCKED);
+               break;
+       case CONTACTS_PHONE_LOG_DELETE_BY_EMAIL_EXTRA_DATA1:
+               va_start(args, op);
+               extra_data1 = va_arg(args, int);
+               va_end(args);
+               snprintf(query, sizeof(query),
+                               "DELETE FROM "CTS_TABLE_PHONELOGS" "
+                               "WHERE data1 = %d AND %d <= log_type AND log_type <= %d",
+                                               extra_data1, CONTACTS_PLOG_TYPE_EMAIL_RECEIVED, CONTACTS_PLOG_TYPE_EMAIL_SENT);
+               break;
+       default:
+               CTS_ERR("Invalid parameter : the operation is not proper (op : %d)", op);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       ret = ctsvc_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret);
+
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_end_trans(false);
+               return ret;
+       }
+       ctsvc_set_phonelog_noti();
+       ret = ctsvc_end_trans(true);
+       return ret;
+}
+
+void ctsvc_db_phone_log_delete_callback(sqlite3_context * context,
+               int argc, sqlite3_value ** argv)
+{
+#ifdef _CONTACTS_IPC_SERVER
+       int phone_log_id;
+
+       if (argc < 1) {
+               sqlite3_result_null(context);
+               return;
+       }
+
+       phone_log_id = sqlite3_value_int(argv[0]);
+       ctsvc_change_subject_add_changed_phone_log_id(CONTACTS_CHANGE_DELETED, phone_log_id);
+
+       sqlite3_result_null(context);
+       return;
+#endif
+}
+
+static int __ctsvc_db_phone_log_find_person_id(char *number, char *normal_num, char *minmatch, int person_id, int *find_number_type)
+{
+       int ret;
+       int find_person_id = -1;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       int i = 0;
+
+       *find_number_type = -1;
+       if (normal_num) {
+               snprintf(query, sizeof(query),
+                               "SELECT person_id, data1 FROM "CTS_TABLE_CONTACTS", "CTS_TABLE_DATA" "
+                                       "ON "CTS_TABLE_CONTACTS".contact_id = "CTS_TABLE_DATA".contact_id "
+                                               "AND datatype = %d AND is_my_profile = 0 AND deleted = 0 "
+                                               "WHERE data4 = ? AND _NUMBER_COMPARE_(data5, ?, NULL, NULL)",
+                                       CTSVC_DATA_NUMBER);
+               bind_text = g_slist_append(bind_text, strdup(minmatch));
+               bind_text = g_slist_append(bind_text, strdup(normal_num));
+       }
+
+       if (*query) {
+               // several person can have same number
+               cts_stmt stmt = NULL;
+               int id;
+               int number_type = -1;
+
+               ret = ctsvc_query_prepare(query, &stmt);
+               if (stmt == NULL) {
+                       CTS_ERR("ctsvc_query_prepare fail(%d)", ret);
+                       if (bind_text) {
+                               for (cursor=bind_text;cursor;cursor=cursor->next)
+                                       free(cursor->data);
+                               g_slist_free(bind_text);
+                       }
+                       return CONTACTS_ERROR_DB;
+               }
+
+               if (bind_text) {
+                       for (cursor=bind_text,i=1;cursor;cursor=cursor->next,i++) {
+                               const char *text = cursor->data;
+                               if (text && *text)
+                                       ctsvc_stmt_bind_text(stmt, i, text);
+                       }
+               }
+
+               while ((ret = ctsvc_stmt_step(stmt))) {
+                       id = ctsvc_stmt_get_int(stmt, 0);
+                       number_type = ctsvc_stmt_get_int(stmt, 1);
+                       if (find_person_id <= 0 && id > 0) {
+                               find_person_id = id;            // find first match person_id
+                               *find_number_type = number_type;
+                               if (person_id <= 0)
+                                       break;
+                       }
+
+                       if (id == person_id) {
+                               find_person_id = person_id;
+                               *find_number_type = number_type;
+                               break;
+                       }
+               }
+               ctsvc_stmt_finalize(stmt);
+       }
+
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       free(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       return find_person_id;
+}
+
+int ctsvc_db_phone_log_update_person_id(const char *number, int old_person_id, int candidate_person_id, bool person_link)
+{
+       CTS_FN_CALL;
+       int ret;
+       int len = 0;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt get_log = NULL;
+       cts_stmt update_log = NULL;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       int i = 0;
+
+       RETVM_IF(old_person_id <= 0 && NULL == number, CONTACTS_ERROR_INVALID_PARAMETER,
+                               "Invalid parameter : old person_id (%d), numberis NULL", old_person_id);
+
+       len = snprintf(query, sizeof(query),
+                                       "SELECT id, number, normal_num, minmatch FROM "CTS_TABLE_PHONELOGS" "
+                                                                               "WHERE log_type <= %d ",
+                                       CONTACTS_PLOG_TYPE_EMAIL_RECEIVED);
+
+       if (number && *number) {
+               char clean_num[strlen(number)+1];
+               len += snprintf(query+len, sizeof(query)-len, "AND ((number = ? ) ");
+               bind_text = g_slist_append(bind_text, strdup(number));
+
+               ret = ctsvc_clean_number(number, clean_num, sizeof(clean_num), true);
+               if (0 < ret) {
+                       char normal_num[sizeof(clean_num) + 20];
+                       ret = ctsvc_normalize_number(clean_num, normal_num, sizeof(normal_num), true);
+                       if (0 < ret) {
+                               char minmatch[sizeof(normal_num)+1];
+                               ret = ctsvc_get_minmatch_number(normal_num, minmatch, sizeof(minmatch), ctsvc_get_phonenumber_min_match_digit());
+                               if (CONTACTS_ERROR_NONE == ret) {
+                                       len += snprintf(query+len, sizeof(query)-len,
+                                               "OR (minmatch = ? AND _NUMBER_COMPARE_(normal_num, ?, NULL, NULL))) ");
+                                       bind_text = g_slist_append(bind_text, strdup(minmatch));
+                                       bind_text = g_slist_append(bind_text, strdup(normal_num));
+                               }
+                               else
+                                       len += snprintf(query+len, sizeof(query)-len, ") ");
+                       }
+                       else
+                               len += snprintf(query+len, sizeof(query)-len, ") ");
+               }
+               else
+                       len += snprintf(query+len, sizeof(query)-len, ") ");
+       }
+
+       if (old_person_id > 0)
+               len += snprintf(query+len, sizeof(query)-len, "AND person_id = %d ", old_person_id);
+       else
+               len += snprintf(query+len, sizeof(query)-len, "AND person_id IS NULL ");
+
+       ret = ctsvc_query_prepare(query, &get_log);
+       if (get_log == NULL) {
+               CTS_ERR("ctsvc_query_prepare fail(%d)", ret);
+               if (bind_text) {
+                       for (cursor=bind_text;cursor;cursor=cursor->next)
+                               free(cursor->data);
+                       g_slist_free(bind_text);
+               }
+               return CONTACTS_ERROR_DB;
+       }
+
+       if (bind_text) {
+               for (cursor=bind_text,i=1;cursor;cursor=cursor->next,i++) {
+                       const char *text = cursor->data;
+                       if (text && *text)
+                               ctsvc_stmt_bind_text(get_log, i, text);
+               }
+       }
+
+       snprintf(query, sizeof(query), "UPDATE "CTS_TABLE_PHONELOGS" SET person_id=?, number_type = ? WHERE id = ?");
+       ret = ctsvc_query_prepare(query, &update_log);
+       if (update_log == NULL) {
+               CTS_ERR("ctsvc_query_prepare fail(%d)", ret);
+               ctsvc_stmt_finalize(get_log);
+
+               if (bind_text) {
+                       for (cursor=bind_text;cursor;cursor=cursor->next)
+                               free(cursor->data);
+                       g_slist_free(bind_text);
+               }
+               return CONTACTS_ERROR_DB;
+       }
+
+       while ((ret = ctsvc_stmt_step(get_log))) {
+               int phonelog_id;
+               int new_person_id = -1;
+               int temp_id;
+               int number_type= -1;
+               char *address;
+               char *normal_address;
+               char *minmatch_address;
+
+               phonelog_id = ctsvc_stmt_get_int(get_log, 0);
+               address = ctsvc_stmt_get_text(get_log, 1);
+               normal_address = ctsvc_stmt_get_text(get_log, 2);
+               minmatch_address = ctsvc_stmt_get_text(get_log, 3);
+
+               //CASE : number is inserted (contact insert/update) => update person_id of phone logs from NULL
+               if (number && old_person_id <= 0 && candidate_person_id > 0) {
+                       __ctsvc_db_phone_log_find_person_id(address, normal_address, minmatch_address, candidate_person_id, &number_type);
+                       new_person_id = candidate_person_id;
+               }
+               //CASE : phonelog insert without person_id
+               else if (number && old_person_id <= 0) {
+                       // address == number
+                       new_person_id = __ctsvc_db_phone_log_find_person_id(address, normal_address, minmatch_address, -1, &number_type);
+                       if (new_person_id <= 0) continue;
+               }
+               // CASE : number update/delete (contact update/delete) => find new_person_id by address
+               // CASE : phonelog insert with person_id
+               else if (number && old_person_id > 0) {
+                       // address == number
+                       // although new_person_id and old_person_id are same, update phonelog for setting number_type
+                       new_person_id = __ctsvc_db_phone_log_find_person_id(address, normal_address, minmatch_address, old_person_id, &number_type);
+               }
+               // CASE : person link => deleted person_id -> new person_id (base_person_id)
+               else if (NULL == number && old_person_id  > 0 && candidate_person_id > 0 && person_link) {
+                       new_person_id = candidate_person_id;
+               }
+               // CASE : person unlink => check person_id of the address,
+               // if person_id is not old_person_id then change person_id to new_person_id
+               else if (NULL == number && old_person_id  > 0 && candidate_person_id > 0) {
+                       temp_id = __ctsvc_db_phone_log_find_person_id(address, normal_address, minmatch_address, candidate_person_id, &number_type);
+                       if (temp_id > 0 && temp_id == old_person_id)
+                               continue;
+                       else if (temp_id > 0 && temp_id != old_person_id)
+                               new_person_id = temp_id;
+               }
+               // CASE : person delete => find new_person_id by address
+               else if (NULL == number && old_person_id  > 0) {
+                       new_person_id = __ctsvc_db_phone_log_find_person_id(address, normal_address, minmatch_address, candidate_person_id, &number_type);
+               }
+               // Already check this case as above : RETVM_IF(old_person_id <= 0 && NULL == number, ...
+//             else
+//                     continue;
+
+               if (new_person_id > 0)
+                       ctsvc_stmt_bind_int(update_log, 1, new_person_id);
+               if (number_type >= 0)
+                       ctsvc_stmt_bind_int(update_log, 2, number_type);
+               ctsvc_stmt_bind_int(update_log, 3, phonelog_id);
+               ctsvc_stmt_step(update_log);
+               ctsvc_stmt_reset(update_log);
+       }
+       ctsvc_stmt_finalize(get_log);
+       ctsvc_stmt_finalize(update_log);
+
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next)
+                       free(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/native/ctsvc_phonelog.h b/native/ctsvc_phonelog.h
new file mode 100644 (file)
index 0000000..6e4afc1
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CTSVC_PHONELOG_H__
+#define __TIZEN_SOCIAL_CTSVC_PHONELOG_H__
+
+#include "ctsvc_sqlite.h"
+void ctsvc_db_phone_log_delete_callback(sqlite3_context * context,
+               int argc, sqlite3_value ** argv);
+int ctsvc_db_phone_log_update_person_id(const char *number, int old_person_id, int candidate_person_id, bool person_link);
+
+#endif // __TIZEN_SOCIAL_CTSVC_PHONELOG_H__
\ No newline at end of file
diff --git a/native/ctsvc_schema.h b/native/ctsvc_schema.h
new file mode 100755 (executable)
index 0000000..3498868
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 __TIZEN_SOCIAL_CTSVC_SCHEMA_H__
+#define __TIZEN_SOCIAL_CTSVC_SCHEMA_H__
+
+#define CTSVC_DB_PATH "/opt/usr/dbspace/.contacts-svc.db"
+#define CTSVC_DB_JOURNAL_PATH "/opt/usr/dbspace/.contacts-svc.db-journal"
+
+// For Security
+#define CTS_SECURITY_FILE_GROUP 5000
+#define CTS_SECURITY_DEFAULT_PERMISSION 0660
+#define CTS_SECURITY_DIR_DEFAULT_PERMISSION 0770
+
+#define CTS_SCHEMA_TABLE_TOTAL 10
+
+// DB Tables
+#define CTS_TABLE_PERSONS "persons"
+#define CTS_TABLE_CONTACTS "contacts"
+#define CTS_TABLE_GROUPS "groups"
+#define CTS_TABLE_ADDRESSBOOKS "addressbooks"
+#define CTS_TABLE_DATA "data"     // This is the data table for contact all fields
+#define CTS_TABLE_FAVORITES "favorites"
+#define CTS_TABLE_PHONELOGS "phonelogs"
+#define CTS_TABLE_PHONELOG_ACC "phonelog_accumulation"
+#define CTS_TABLE_PHONELOG_STAT "phonelog_stat"
+#define CTS_TABLE_GROUP_RELATIONS "group_relations"
+#define CTS_TABLE_DELETEDS "contact_deleteds"
+#define CTS_TABLE_GROUP_DELETEDS "group_deleteds"
+#define CTS_TABLE_CUSTOM_TYPES "custom_types"
+#define CTS_TABLE_SDN "sdn"
+#define CTS_TABLE_SPEEDDIALS "speeddials"
+#define CTS_TABLE_VERSION "cts_version"
+#define CTS_TABLE_MY_PROFILES "my_profiles"
+#define CTS_TABLE_CONTACT_STAT "contact_stat"
+#define CTS_TABLE_NAME_LOOKUP "name_lookup"
+#define CTS_TABLE_PHONE_LOOKUP "phone_lookup"
+#define CTS_TABLE_SEARCH_INDEX "search_index"
+#define CTS_TABLE_SIM_INFO "sim_info"
+
+#define CTS_TABLE_ACTIVITIES "activities"
+#define CTS_TABLE_ACTIVITY_PHOTOS "activity_photos"
+
+// DB views /////////////////////////////////////////////////////////////////////
+#define CTSVC_DB_VIEW_PERSON                                   "view_person"
+#define CTSVC_DB_VIEW_CONTACT                                  "view_contact"
+#define CTSVC_DB_VIEW_MY_PROFILE                               "view_my_profile"
+
+#define CTSVC_DB_VIEW_NAME                                             "view_name"
+#define CTSVC_DB_VIEW_NUMBER                                   "view_number"
+#define CTSVC_DB_VIEW_EMAIL                                            "view_email"
+#define CTSVC_DB_VIEW_ADDRESS                                  "view_address"
+#define CTSVC_DB_VIEW_URL                                              "view_url"
+#define CTSVC_DB_VIEW_EVENT                                            "view_event"
+#define CTSVC_DB_VIEW_RELATIONSHIP                             "view_relationship"
+#define CTSVC_DB_VIEW_IMAGE                                            "view_image"
+#define CTSVC_DB_VIEW_COMPANY                                  "view_company"
+#define CTSVC_DB_VIEW_GROUP_RELATION                   "view_group_relation"
+#define CTSVC_DB_VIEW_NICKNAME                                 "view_nickname"
+#define CTSVC_DB_VIEW_MESSENGER                                        "view_messenger"
+#define CTSVC_DB_VIEW_NOTE                                             "view_note"
+#define CTSVC_DB_VIEW_PROFILE                                  "view_profile"
+#define CTSVC_DB_VIEW_EXTENSION                                        "view_extension"
+
+#define CTSVC_DB_VIEW_ACTIVITY                                 "view_activity"
+#define CTSVC_DB_VIEW_ACTIVITY_PHOTOS                  "view_activity_photos"
+#define CTSVC_DB_VIEW_SPEEDIDAL                                        "view_speeddial"
+
+//#define CTSVC_DB_VIEW_GROUPS_UPDATED_INFO            "view_group_changes"
+//#define CTSVC_DB_VIEW_GROUPS_MEMBER_UPDATED_INFO     "view_group_member_changes"
+//#define CTSVC_DB_VIEW_CONTACTS_UPDATED_INFO          "view_contacts_changes"
+
+#define CTSVC_DB_VIEW_PERSON_CONTACT                   "view_person_contact"
+#define CTSVC_DB_VIEW_PERSON_NUMBER            "view_person_contact_number"
+#define CTSVC_DB_VIEW_PERSON_EMAIL             "view_person_contact_email"
+#define CTSVC_DB_VIEW_PERSON_GROUP                     "view_person_contact_group"
+#define CTSVC_DB_VIEW_PERSON_GROUP_ASSIGNED    "view_person_contact_group_assigned"
+#define CTSVC_DB_VIEW_PERSON_GROUP_NOT_ASSIGNED        "view_person_contact_group_not_assigned"
+
+#define CTSVC_DB_VIEW_PERSON_PHONELOG  "view_person_contact_phonelog"
+#define CTSVC_DB_VIEW_PERSON_USAGE                             "view_person_usage"
+
+#define CTSVC_DB_VIEW_CONTACT_NUMBER           "view_contact_number"
+#define CTSVC_DB_VIEW_CONTACT_EMAIL                    "view_contact_email"
+#define CTSVC_DB_VIEW_CONTACT_GROUP                    "view_contact_group"
+
+#define CTSVC_DB_VIEW_CONTACT_ACTIVITY                 "view_contact_activity"
+
+/////////////////////////////////////////////////////////////////////////////////
+
+#define CTS_SCHEMA_DATA_NAME_LANG_INFO "data1"
+#define CTS_SCHEMA_DATA_NAME_LOOKUP "data7"
+#define CTS_SCHEMA_DATA_NAME_REVERSE_LOOKUP "data8"
+
+#define CTS_SCHEMA_SQLITE_SEQ "sqlite_sequence"
+
+#define CTS_SCHEMA_DISPLAY_NAME "display_name"
+#define CTS_SCHEMA_REVERSE_DISPLAY_NAME "reverse_display_name"
+#define CTS_SCHEMA_SORTKEY  "sortkey"
+#define CTS_SCHEMA_REVERSE_SORTKEY  "reverse_sortkey"
+
+
+#endif /* __TIZEN_SOCIAL_CTSVC_SCHEMA_H__ */
diff --git a/native/ctsvc_service.c b/native/ctsvc_service.c
new file mode 100644 (file)
index 0000000..d256f22
--- /dev/null
@@ -0,0 +1,335 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#ifdef _CONTACTS_NATIVE
+#include <security-server.h>
+#endif
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_socket.h"
+#include "ctsvc_mutex.h"
+#include "ctsvc_inotify.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_setting.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_number_utils.h"
+
+static int _ctsvc_connection = 0;
+static __thread int thread_connection = 0;
+
+#ifdef _CONTACTS_NATIVE
+void __ctsvc_addressbook_deleted_cb(const char* view_uri, void* user_data)
+{
+       // access control update
+       ctsvc_reset_all_client_access_info();
+}
+#endif
+
+API int contacts_connect()
+{
+       CTS_FN_CALL;
+       int ret;
+
+       ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
+       if (0 == _ctsvc_connection) {
+#ifdef _CONTACTS_NATIVE
+               ret = ctsvc_socket_init();
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_socket_init() Failed(%d)", ret);
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return ret;
+               }
+#endif
+               ret = ctsvc_inotify_init();
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_inotify_init() Failed(%d)", ret);
+#ifdef _CONTACTS_NATIVE
+                       ctsvc_socket_final();
+#endif
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return ret;
+               }
+               ctsvc_db_plugin_init();
+               ctsvc_view_uri_init();
+               ctsvc_register_vconf();
+#ifdef _CONTACTS_NATIVE
+               contacts_db_add_changed_cb(_contacts_address_book._uri, __ctsvc_addressbook_deleted_cb, NULL);
+#endif
+       }
+       else
+               CTS_DBG("System : Contacts service has been already connected");
+
+       _ctsvc_connection++;
+
+       if (0 == thread_connection) {
+               ret = ctsvc_db_init();
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_db_init() Failed(%d)", ret);
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return ret;
+               }
+#ifdef _CONTACTS_NATIVE
+               // Access control : get cookie from security-server
+               char *smack_label = NULL;
+               size_t cookie_size = security_server_get_cookie_size();
+
+               if (cookie_size <= 0) {
+                       CTS_ERR("security_server_get_cookie_size : cookie_size is %d", cookie_size);
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return CONTACTS_ERROR_SYSTEM;
+               }
+
+               char cookie[cookie_size];
+               cookie[0] = '\0';
+               ret = security_server_request_cookie(cookie, cookie_size);
+               if(ret < 0) {
+                       CTS_ERR("security_server_request_cookie fail (%d)", ret);
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return CONTACTS_ERROR_SYSTEM;
+               }
+
+               smack_label = security_server_get_smacklabel_cookie(cookie);
+               if (NULL == smack_label) {
+                       CTS_ERR("security_server_get_smacklabel_cookie fail");
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return CONTACTS_ERROR_SYSTEM;
+               }
+
+               // In case of server, set SMACK label in ctsvc_ipc_server_connect()
+               ctsvc_set_client_access_info(smack_label, cookie);
+               free(smack_label);
+#endif
+       }
+       thread_connection++;
+
+       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_disconnect()
+{
+       ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
+
+       if (1 == thread_connection) {
+               ctsvc_db_deinit();
+#ifdef _CONTACTS_NATIVE
+               ctsvc_unset_client_access_info();
+#endif
+       }
+       else if (thread_connection <= 0) {
+               CTS_DBG("System : please call contacts_connect_on_thread(), thread_connection count is (%d)", thread_connection);
+               ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       thread_connection--;
+
+       if (1 == _ctsvc_connection) {
+#ifdef _CONTACTS_NATIVE
+               ctsvc_socket_final();
+#endif
+               ctsvc_inotify_close();
+               ctsvc_deregister_vconf();
+               ctsvc_view_uri_deinit();
+               ctsvc_db_plugin_deinit();
+               ctsvc_deinit_tapi_handle_for_cc();
+#ifdef _CONTACTS_NATIVE
+               contacts_db_remove_changed_cb(_contacts_address_book._uri, __ctsvc_addressbook_deleted_cb, NULL);
+#endif
+       }
+       else if (1 < _ctsvc_connection)
+               CTS_DBG("System : connection count is %d", _ctsvc_connection);
+       else {
+               CTS_DBG("System : please call contacts_connect(), connection count is (%d)", _ctsvc_connection);
+               ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       _ctsvc_connection--;
+       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_contacts_internal_disconnect()
+{
+       ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
+
+       if (1 == thread_connection) {
+               ctsvc_db_deinit();
+               thread_connection--;
+
+               if (1 <= _ctsvc_connection) {
+                       _ctsvc_connection--;
+               }
+       }
+
+       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+       return CONTACTS_ERROR_NONE;
+}
+
+#ifdef _CONTACTS_NATIVE
+API int contacts_connect_with_flags(unsigned int flags)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+
+       ret = contacts_connect();
+       if (ret == CONTACTS_ERROR_NONE)
+               return ret;
+
+       if (flags & CONTACTS_CONNECT_FLAG_RETRY) {
+               int i;
+               int waiting_time = 500;
+               for (i=0;i<9;i++) {
+                       usleep(waiting_time * 1000);
+                       CTS_DBG("retry cnt=%d, ret=%x, %d",(i+1), ret, waiting_time);
+                       ret = contacts_connect();
+                       if (ret == CONTACTS_ERROR_NONE)
+                               break;
+                       if (6 < i)
+                               waiting_time += 30000;
+                       else
+                               waiting_time *= 2;
+               }
+       }
+       return ret;
+}
+
+API int contacts_connect_on_thread()
+{
+       int ret;
+
+       ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
+
+       if (0 == thread_connection) {
+#ifdef _CONTACTS_NATIVE
+               ret = ctsvc_socket_init();
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_socket_init() Failed(%d)", ret);
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return ret;
+               }
+#endif
+               ret = ctsvc_inotify_init();
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_inotify_init() Failed(%d)", ret);
+#ifdef _CONTACTS_NATIVE
+                       ctsvc_socket_final();
+#endif
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return ret;
+               }
+               ctsvc_db_plugin_init();
+               ctsvc_view_uri_init();
+               ctsvc_register_vconf();
+               contacts_db_add_changed_cb(_contacts_address_book._uri, __ctsvc_addressbook_deleted_cb, NULL);
+               ret = ctsvc_db_init();
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_db_init() Failed(%d)", ret);
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return ret;
+               }
+
+               // Access control : get cookie from security-server
+               char *smack_label = NULL;
+               size_t cookie_size = security_server_get_cookie_size();
+
+               if (cookie_size <= 0) {
+                       CTS_ERR("security_server_get_cookie_size : cookie_size is %d", cookie_size);
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return CONTACTS_ERROR_SYSTEM;
+               }
+
+               char cookie[cookie_size];
+               cookie[0] = '\0';
+               ret = security_server_request_cookie(cookie, cookie_size);
+               if(ret < 0) {
+                       CTS_ERR("security_server_request_cookie fail (%d)", ret);
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return CONTACTS_ERROR_SYSTEM;
+               }
+
+               smack_label = security_server_get_smacklabel_cookie(cookie);
+               if (NULL == smack_label) {
+                       CTS_ERR("security_server_get_smacklabel_cookie fail");
+                       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+                       return CONTACTS_ERROR_SYSTEM;
+               }
+
+               // In case of server, set SMACK label in ctsvc_ipc_server_connect()
+               ctsvc_set_client_access_info(smack_label, cookie);
+               free(smack_label);
+       }
+       else
+       {
+               CTS_DBG("System : db connection on thread already exist");
+       }
+       thread_connection++;
+
+       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_disconnect_on_thread()
+{
+       int ret;
+       ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
+
+       if (1 == thread_connection) {
+               ctsvc_db_deinit();
+               ctsvc_unset_client_access_info();
+#ifdef _CONTACTS_NATIVE
+               ctsvc_socket_final();
+#endif
+               ctsvc_inotify_close();
+               ctsvc_deregister_vconf();
+               ctsvc_view_uri_deinit();
+               ctsvc_db_plugin_deinit();
+               ctsvc_deinit_tapi_handle_for_cc();
+               contacts_db_remove_changed_cb(_contacts_address_book._uri, __ctsvc_addressbook_deleted_cb, NULL);
+       }
+       else if (thread_connection <= 0) {
+               CTS_DBG("System : please call contacts_connect_on_thread(), connection count is (%d)", thread_connection);
+               ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+       }
+       else
+       {
+               CTS_DBG("System : db connection on thread count is (%d)", thread_connection);
+       }
+
+       thread_connection--;
+
+       ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
+
+       return CONTACTS_ERROR_NONE;
+}
+#endif
+
diff --git a/native/ctsvc_service.h b/native/ctsvc_service.h
new file mode 100644 (file)
index 0000000..c8022db
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 __TIZEN_SOCIAL_CTSVC_SERVICE_H__
+#define __TIZEN_SOCIAL_CTSVC_SERVICE_H__
+
+int ctsvc_contacts_internal_disconnect();
+
+#endif /*  __TIZEN_SOCIAL_CTSVC_SERVICE_H__ */
+
diff --git a/native/ctsvc_setting.c b/native/ctsvc_setting.c
new file mode 100644 (file)
index 0000000..897737d
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 <glib.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_notify.h"
+#include "ctsvc_setting.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_localize.h"
+#include "ctsvc_db_access_control.h"
+
+#ifdef _CONTACTS_IPC_SERVER
+#include "ctsvc_server_change_subject.h"
+#endif
+
+#ifdef _CONTACTS_NATIVE
+static int __ctsvc_vconf_ref_count = 0;
+#endif
+
+static int primary_sort = -1;
+static int secondary_sort = -1;
+
+static int name_display_order = -1;
+static int name_sorting_order = -1;
+static int phonenumber_min_match_digit = -1;
+
+static const char *CTSVC_VCONF_DISPLAY_ORDER = VCONFKEY_CONTACTS_SVC_NAME_DISPLAY_ORDER;
+static const char *CTSVC_VCONF_SORTING_ORDER = VCONFKEY_CONTACTS_SVC_NAME_SORTING_ORDER;
+static const char *CTSVC_VCONF_PHONENUMBER_MIN_MATCH_DIGIT = VCONFKEY_CONTACTS_SVC_PHONENUMBER_MIN_MATCH_DIGIT;
+
+API int contacts_setting_get_name_display_order(contacts_name_display_order_e *order)
+{
+       int ret;
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_READ), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact read");
+
+       if (name_display_order < 0) {
+               ret = vconf_get_int(CTSVC_VCONF_DISPLAY_ORDER, &name_display_order);
+               RETVM_IF(ret<0, CONTACTS_ERROR_SYSTEM, "System : vconf_get_int() Failed(%d)", ret);
+       }
+
+       *order = name_display_order;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_setting_set_name_display_order(contacts_name_display_order_e order)
+{
+       int ret;
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_WRITE), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact write");
+       RETVM_IF(CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST != order && CONTACTS_NAME_DISPLAY_ORDER_LASTFIRST != order,
+                       CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : The parameter(order:%d) is Invalid", name_display_order);
+
+       if (order == name_display_order)
+               return CONTACTS_ERROR_NONE;
+
+       ret = vconf_set_int(CTSVC_VCONF_DISPLAY_ORDER, order);
+       RETVM_IF(ret<0, CONTACTS_ERROR_SYSTEM, "System : vconf_set_int(display order) Failed(%d)", ret);
+
+       name_display_order = order;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_setting_get_name_sorting_order(contacts_name_sorting_order_e *order)
+{
+       int ret;
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_READ), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact read");
+       if (name_sorting_order < 0)
+       {
+               ret = vconf_get_int(CTSVC_VCONF_SORTING_ORDER, &name_sorting_order);
+               RETVM_IF(ret<0, CONTACTS_ERROR_SYSTEM, "System : vconf_get_int(sort order) Failed(%d)", ret);
+       }
+
+       *order = name_sorting_order;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+API int contacts_setting_set_name_sorting_order(contacts_name_sorting_order_e order)
+{
+       int ret;
+       RETVM_IF(!ctsvc_have_permission(CTSVC_PERMISSION_CONTACT_WRITE), CONTACTS_ERROR_PERMISSION_DENIED,
+                               "Permission denied : contact write");
+       RETVM_IF(CONTACTS_NAME_SORTING_ORDER_FIRSTLAST != order && CONTACTS_NAME_SORTING_ORDER_LASTFIRST != order,
+                       CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : The parameter(order:%d) is Invalid", name_sorting_order);
+
+       if (order == name_sorting_order)
+               return CONTACTS_ERROR_NONE;
+
+       ret = vconf_set_int(CTSVC_VCONF_SORTING_ORDER, order);
+       RETVM_IF(ret<0, CONTACTS_ERROR_SYSTEM, "System : vconf_set_int(sort order) Failed(%d)", ret);
+
+       name_sorting_order = order;
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static void ctsvc_vconf_display_order_cb(keynode_t *key, void *data)
+{
+       name_display_order = vconf_keynode_get_int(key);
+
+#ifdef _CONTACTS_IPC_SERVER
+       // publish display order changed
+       ctsvc_change_subject_publish_setting(CTSVC_SETTING_DISPLAY_ORDER_CHANGED, name_display_order);
+#endif
+}
+
+static void ctsvc_vconf_sorting_order_cb(keynode_t *key, void *data)
+{
+       name_sorting_order = vconf_keynode_get_int(key);
+
+#ifdef _CONTACTS_IPC_SERVER
+       // publish sort order changed
+       ctsvc_change_subject_publish_setting(CTSVC_SETTING_SORTING_ORDER_CHANGED, name_sorting_order);
+#endif
+}
+
+void ctsvc_set_sort_memory(int sort_type)
+{
+       primary_sort = sort_type;
+       secondary_sort = CTSVC_SORT_WESTERN;
+}
+
+static void ctsvc_vconf_sort_change_cb(keynode_t *key, void *data)
+{
+       int sort = vconf_keynode_get_int(key);
+       ctsvc_set_sort_memory(sort);
+}
+
+int ctsvc_register_vconf(void)
+{
+       int ret;
+
+#ifdef _CONTACTS_NATIVE
+       __ctsvc_vconf_ref_count++;
+       if (__ctsvc_vconf_ref_count != 1)
+               return;
+#endif
+
+       // display order
+       ret = vconf_get_int(CTSVC_VCONF_DISPLAY_ORDER, &name_display_order);
+       if (ret < 0) {
+               CTS_ERR("vconf_get_int() Failed(%d)", ret);
+               name_display_order = CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST;
+       }
+       ret = vconf_notify_key_changed(CTSVC_VCONF_DISPLAY_ORDER,
+                       ctsvc_vconf_display_order_cb, NULL);
+       RETVM_IF(ret<0, CONTACTS_ERROR_SYSTEM, "vconf_notify_key_changed(display order) Failed(%d)", ret);
+
+       // sorting order
+       ret = vconf_get_int(CTSVC_VCONF_SORTING_ORDER, &name_sorting_order);
+       if (ret < 0) {
+               CTS_ERR("vconf_get_int() Failed(%d)", ret);
+               name_sorting_order = CONTACTS_NAME_SORTING_ORDER_FIRSTLAST;
+       }
+       ret = vconf_notify_key_changed(CTSVC_VCONF_SORTING_ORDER,
+                       ctsvc_vconf_sorting_order_cb, NULL);
+       RETVM_IF(ret<0, CONTACTS_ERROR_SYSTEM, "vconf_notify_key_changed(sort order) Failed(%d)", ret);
+
+       // phonenumber min match digit
+       ret = vconf_get_int(CTSVC_VCONF_PHONENUMBER_MIN_MATCH_DIGIT, &phonenumber_min_match_digit);
+       if (ret < 0) {
+               CTS_ERR("vconf_get_int() Failed(%d)", ret);
+               phonenumber_min_match_digit = 8;
+       }
+
+       ret = vconf_get_int(ctsvc_get_default_sort_vconfkey(), &primary_sort);
+       WARN_IF(ret < 0, "vconf_get_int() Failed(%d)", ret);
+       ctsvc_set_sort_memory(primary_sort);
+
+       ret = vconf_notify_key_changed(ctsvc_get_default_sort_vconfkey(),
+                       ctsvc_vconf_sort_change_cb, NULL);
+       RETVM_IF(ret<0, CONTACTS_ERROR_SYSTEM, "vconf_notify_key_changed(deafult lang) Failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+void ctsvc_deregister_vconf(void)
+{
+       int ret;
+
+#ifdef _CONTACTS_NATIVE
+       __ctsvc_vconf_ref_count--;
+       if (__ctsvc_vconf_ref_count != 0)
+               return;
+#endif
+
+       ret = vconf_ignore_key_changed(CTSVC_VCONF_DISPLAY_ORDER, ctsvc_vconf_display_order_cb);
+       RETM_IF(ret<0,"vconf_ignore_key_changed(display order) Failed(%d)", ret);
+       ret = vconf_ignore_key_changed(CTSVC_VCONF_SORTING_ORDER, ctsvc_vconf_sorting_order_cb);
+       RETM_IF(ret<0,"vconf_ignore_key_changed(sort order) Failed(%d)", ret);
+
+       ret = vconf_ignore_key_changed(ctsvc_get_default_sort_vconfkey(), ctsvc_vconf_sort_change_cb);
+       RETM_IF(ret<0,"vconf_ignore_key_changed(default_lang) Failed(%d)", ret);
+}
+
+int ctsvc_get_phonenumber_min_match_digit(void)
+{
+       return phonenumber_min_match_digit;
+}
+
+const char* ctsvc_get_default_sort_vconfkey(void)
+{
+       return "file/private/contacts-service/default_lang";
+}
+
+int ctsvc_get_primary_sort(void)
+{
+       if (primary_sort < 0) {
+               int ret;
+               ret = vconf_get_int(ctsvc_get_default_sort_vconfkey(), &primary_sort);
+               WARN_IF(ret < 0, "vconf_get_int() Failed(%d)", ret);
+               ctsvc_set_sort_memory(primary_sort);
+       }
+       return primary_sort;
+}
+
+int ctsvc_get_secondary_sort(void)
+{
+       return secondary_sort;
+}
+
+#ifdef _CONTACTS_NATIVE
+API int contacts_setting_add_name_display_order_changed_cb(
+       contacts_setting_name_display_order_changed_cb cb, void* user_data)
+{
+       CTS_ERR("Please use contacts-service2 instead of contacts-service3");
+       return CONTACTS_ERROR_INTERNAL;
+}
+
+API int contacts_setting_remove_name_display_order_changed_cb(
+       contacts_setting_name_display_order_changed_cb cb, void* user_data)
+{
+       CTS_ERR("Please use contacts-service2 instead of contacts-service3");
+       return CONTACTS_ERROR_INTERNAL;
+
+}
+
+API int contacts_setting_add_name_sorting_order_changed_cb(
+       contacts_setting_name_sorting_order_changed_cb cb, void* user_data)
+{
+       CTS_ERR("Please use contacts-service2 instead of contacts-service3");
+       return CONTACTS_ERROR_INTERNAL;
+}
+
+
+API int contacts_setting_remove_name_sorting_order_changed_cb(
+       contacts_setting_name_sorting_order_changed_cb cb, void* user_data)
+{
+       CTS_ERR("Please use contacts-service2 instead of contacts-service3");
+       return CONTACTS_ERROR_INTERNAL;
+}
+
+#endif
diff --git a/native/ctsvc_setting.h b/native/ctsvc_setting.h
new file mode 100644 (file)
index 0000000..3c4468f
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CTSVC_SETTING_H__
+#define __TIZEN_SOCIAL_CTSVC_SETTING_H__
+
+int ctsvc_register_vconf(void);
+void ctsvc_deregister_vconf(void);
+
+int ctsvc_get_phonenumber_min_match_digit(void);
+int ctsvc_get_primary_sort(void);
+int ctsvc_get_secondary_sort(void);
+const char *ctsvc_get_default_sort_vconfkey(void);
+void ctsvc_set_sort_memory(int sort_type);
+
+
+#endif /*  __TIZEN_SOCIAL_CTSVC_SETTING_H__ */
+
diff --git a/native/ctsvc_sqlite.c b/native/ctsvc_sqlite.c
new file mode 100755 (executable)
index 0000000..0be7cd6
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <string.h>
+#include <db-util.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_number_utils.h"
+
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_plugin_person_helper.h"
+#include "ctsvc_db_plugin_image_helper.h"
+#include "ctsvc_db_plugin_company_helper.h"
+#include "ctsvc_db_plugin_group_helper.h"
+
+#ifdef ENABLE_LOG_FEATURE
+#include "ctsvc_phonelog.h"
+#endif // ENABLE_LOG_FEATURE
+#include "ctsvc_person.h"
+
+#define CTSVC_QUERY_RETRY_TIME 4
+#define CTSVC_QUERY_RETRY_INTERVAL     50*1000
+
+static __thread sqlite3 *ctsvc_db = NULL;
+
+int ctsvc_db_open(void) {
+       CTS_FN_CALL;
+       int ret;
+
+       if (!ctsvc_db) {
+               ret = db_util_open(CTSVC_DB_PATH, &ctsvc_db, 0);
+               RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB /*CTS_ERR_DB_NOT_OPENED*/,
+                               "DB error : db_util_open() Failed(%d)", ret);
+               ret = sqlite3_create_function(ctsvc_db, "_DATA_DELETE_", 2, SQLITE_UTF8, NULL,
+                                       ctsvc_db_data_delete_callback, NULL, NULL);
+               RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB,
+                                               "sqlite3_create_function() Failed(%d)", ret);
+               ret = sqlite3_create_function(ctsvc_db, "_DATA_IMAGE_DELETE_", 1, SQLITE_UTF8, NULL,
+                                       ctsvc_db_image_delete_callback, NULL, NULL);
+               RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB,
+                                               "sqlite3_create_function() Failed(%d)", ret);
+               ret = sqlite3_create_function(ctsvc_db, "_DATA_COMPANY_DELETE_", 1, SQLITE_UTF8, NULL,
+                                       ctsvc_db_company_delete_callback, NULL, NULL);
+               RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB,
+                                               "sqlite3_create_function() Failed(%d)", ret);
+               ret = sqlite3_create_function(ctsvc_db, "_NORMALIZE_INDEX_", 2, SQLITE_UTF8, NULL,
+                                       ctsvc_db_normalize_str_callback, NULL, NULL);
+               RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB,
+                                               "sqlite3_create_function() Failed(%d)", ret);
+#ifdef ENABLE_LOG_FEATURE
+               ret = sqlite3_create_function(ctsvc_db, "_PHONE_LOG_DELETE_", 1, SQLITE_UTF8, NULL,
+                                       ctsvc_db_phone_log_delete_callback, NULL, NULL);
+               RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB,
+                                               "sqlite3_create_function() Failed(%d)", ret);
+#endif // ENABLE_LOG_FEATURE
+               ret = sqlite3_create_function(ctsvc_db, "_PERSON_DELETE_", 1, SQLITE_UTF8, NULL,
+                                       ctsvc_db_person_delete_callback, NULL, NULL);
+               RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB,
+                                               "sqlite3_create_function() Failed(%d)", ret);
+               ret = sqlite3_create_function(ctsvc_db, "_GROUP_DELETE_", 1, SQLITE_UTF8, NULL,
+                                       ctsvc_db_group_delete_callback, NULL, NULL);
+               RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB,
+                                               "sqlite3_create_function() Failed(%d)", ret);
+               ret = sqlite3_create_function(ctsvc_db, "_NUMBER_COMPARE_", 4, SQLITE_UTF8, NULL,
+                                       ctsvc_db_phone_number_equal_callback, NULL, NULL);
+               RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB,
+                                               "sqlite3_create_function() Failed(%d)", ret);
+       }
+
+       return CONTACTS_ERROR_NONE /*CTS_SUCCESS*/;
+}
+
+int ctsvc_db_close(void) {
+       int ret = 0;
+
+       if (ctsvc_db) {
+               ret = db_util_close(ctsvc_db);
+               WARN_IF(SQLITE_OK != ret, "db_util_close() Failed(%d)", ret);
+               ctsvc_db = NULL;
+               CTS_DBG("The database disconnected really.");
+       }
+
+       return CONTACTS_ERROR_NONE /*CTS_SUCCESS*/;
+}
+
+int ctsvc_db_change(void) {
+       return sqlite3_changes(ctsvc_db);
+}
+
+int ctsvc_db_get_last_insert_id(void) {
+       return sqlite3_last_insert_rowid(ctsvc_db);
+}
+
+int ctsvc_db_get_next_id(const char *table) {
+       int id;
+       int ret;
+       char query[CTS_SQL_MAX_LEN] = { 0 };
+
+       snprintf(query, sizeof(query), "SELECT seq FROM %s WHERE name = '%s'",
+                       CTS_SCHEMA_SQLITE_SEQ, table);
+
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       if (ret != CONTACTS_ERROR_NONE /*CTS_SUCCESS*/) {
+               if (CONTACTS_ERROR_NO_DATA /*CONTACTS_ERR_DB_RECORD_NOT_FOUND*/ == ret)
+                       return 1;
+               else
+                       return id;
+       } else {
+               return (1 + id);
+       }
+}
+
+int ctsvc_query_get_first_int_result(const char *query, int *result) {
+       int ret;
+       struct timeval from, now, diff;
+       bool retry = false;
+       cts_stmt stmt = NULL;
+       RETVM_IF(NULL == ctsvc_db, CONTACTS_ERROR_DB /*CTS_ERR_DB_NOT_OPENED*/, "DB error : Database is not opended");
+
+       gettimeofday(&from, NULL);
+       do {
+               ret = sqlite3_prepare_v2(ctsvc_db, query, strlen(query), &stmt, NULL);
+               if (ret != SQLITE_OK)
+                       CTS_ERR("DB error : sqlite3_prepare_v2() Failed(%d, %s)", ret, sqlite3_errmsg(ctsvc_db));
+
+               if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED) {
+                       gettimeofday(&now, NULL);
+                       timersub(&now, &from, &diff);
+                       retry = (diff.tv_sec < CTSVC_QUERY_RETRY_TIME)? true:false;
+                       if (retry)
+                               usleep(CTSVC_QUERY_RETRY_INTERVAL);
+               } else
+                       retry = false;
+       }while(retry);
+
+       if (SQLITE_OK != ret) {
+               CTS_ERR("DB error : sqlite3_prepare_v2() Failed(%s)", sqlite3_errmsg(ctsvc_db));
+               if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED)
+                       return CONTACTS_ERROR_DB_LOCKED;
+               else
+                       return CONTACTS_ERROR_DB;
+       }
+
+       retry = false;
+       gettimeofday(&from, NULL);
+       do {
+               ret = sqlite3_step(stmt);
+               if (ret != SQLITE_ROW && SQLITE_DONE != ret)
+                       CTS_ERR("DB error : sqlite3_step() Failed(%d, %s, %d)", ret, sqlite3_errmsg(ctsvc_db),
+                                       sqlite3_extended_errcode(ctsvc_db));
+
+               if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED) {
+                       gettimeofday(&now, NULL);
+                       timersub(&now, &from, &diff);
+                       retry = (diff.tv_sec < CTSVC_QUERY_RETRY_TIME)? true:false;
+                       if (retry)
+                               usleep(CTSVC_QUERY_RETRY_INTERVAL);
+               }
+               else
+                       retry = false;
+       }while(retry);
+
+       if (SQLITE_ROW != ret) {
+               sqlite3_finalize(stmt);
+               if (SQLITE_DONE == ret) {
+                       CTS_INFO("sqlite3_step() return with SQLITE_DONE (it means NO_DATA) (%d, %s)",
+                               ret, sqlite3_errmsg(ctsvc_db));
+                       return CONTACTS_ERROR_NO_DATA /*CONTACTS_ERR_DB_RECORD_NOT_FOUND*/;
+               }
+               CTS_ERR("sqlite3_step() Failed(%d, %s, %d)", ret, sqlite3_errmsg(ctsvc_db),
+                               sqlite3_extended_errcode(ctsvc_db));
+               if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED)
+                       return CONTACTS_ERROR_DB_LOCKED;
+               else
+                       return CONTACTS_ERROR_DB;
+       }
+
+       *result = sqlite3_column_int(stmt, 0);
+       sqlite3_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_query_exec(const char *query) {
+       int ret;
+       cts_stmt stmt = NULL;
+       char *err_msg = NULL;
+
+       RETVM_IF(NULL == ctsvc_db, CONTACTS_ERROR_DB, "DB error : Database is not opended");
+
+       ret = ctsvc_query_prepare((char*)query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "ctsvc_query_prepare fail(%d)", ret);
+
+       ret = ctsvc_stmt_step(stmt);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_stmt_step() Failed(%d, %s)", ret, err_msg);
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       return ret;
+}
+
+int ctsvc_query_prepare(char *query, cts_stmt *stmt) {
+       int ret = -1;
+       struct timeval from, now, diff;
+       bool retry = false;
+       *stmt = NULL;
+
+       RETVM_IF(NULL == ctsvc_db, CONTACTS_ERROR_DB, "DB error : Database is not opened");
+
+       gettimeofday(&from, NULL);
+       do {
+               ret = sqlite3_prepare_v2(ctsvc_db, query, strlen(query), stmt, NULL);
+
+               if (ret != SQLITE_OK)
+                       CTS_ERR("DB error : sqlite3_prepare_v2() Failed(%d, %s)", ret, sqlite3_errmsg(ctsvc_db));
+
+               if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED) {
+                       gettimeofday(&now, NULL);
+                       timersub(&now, &from, &diff);
+                       retry = (diff.tv_sec < CTSVC_QUERY_RETRY_TIME)? true:false;
+                       if (retry)
+                               usleep(CTSVC_QUERY_RETRY_INTERVAL);
+               } else
+                       retry = false;
+       }while(retry);
+
+       if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED)
+               return CONTACTS_ERROR_DB_LOCKED;
+       else if (ret == SQLITE_OK)
+               return CONTACTS_ERROR_NONE;
+       else
+               return CONTACTS_ERROR_DB;
+}
+
+int ctsvc_stmt_get_first_int_result(cts_stmt stmt, int *result) {
+       int ret;
+       struct timeval from, now, diff;
+       bool retry = false;
+       RETVM_IF(NULL == ctsvc_db, CONTACTS_ERROR_DB /*CTS_ERR_DB_NOT_OPENED*/, "DB error : Database is not opened");
+
+       gettimeofday(&from, NULL);
+       do {
+               ret = sqlite3_step(stmt);
+               if (SQLITE_ROW != ret && SQLITE_DONE != ret)
+                       CTS_ERR("sqlite3_step() Failed(%d, %s, %d)", ret, sqlite3_errmsg(ctsvc_db),
+                                       sqlite3_extended_errcode(ctsvc_db));
+
+               if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED) {
+                       gettimeofday(&now, NULL);
+                       timersub(&now, &from, &diff);
+                       retry = (diff.tv_sec < CTSVC_QUERY_RETRY_TIME)? true:false;
+                       if (retry)
+                               usleep(CTSVC_QUERY_RETRY_INTERVAL);
+               }
+               else
+                       retry = false;
+       }while(retry);
+
+       if (SQLITE_ROW != ret) {
+               CTS_ERR("sqlite3_step() Failed(%d, %s, %d)", ret, sqlite3_errmsg(ctsvc_db),
+                                       sqlite3_extended_errcode(ctsvc_db));
+               sqlite3_finalize(stmt);
+               if (SQLITE_DONE == ret)
+                       return CONTACTS_ERROR_NO_DATA /*CONTACTS_ERR_DB_RECORD_NOT_FOUND*/;
+               if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED)
+                       return CONTACTS_ERROR_DB_LOCKED;
+               else
+                       return CONTACTS_ERROR_DB;
+       }
+
+       *result = sqlite3_column_int(stmt, 0);
+       sqlite3_finalize(stmt);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_stmt_step(cts_stmt stmt) {
+       int ret = CONTACTS_ERROR_NONE;
+       struct timeval from, now, diff;
+       bool retry = false;
+
+       gettimeofday(&from, NULL);
+       do {
+               ret = sqlite3_step(stmt);
+
+               if (ret != SQLITE_ROW && ret != SQLITE_DONE)
+                       CTS_ERR("DB error : sqlite3_step() Failed(%d, %s, %d)", ret,
+                                       sqlite3_errmsg(ctsvc_db), sqlite3_extended_errcode(ctsvc_db));
+
+               if (ret == SQLITE_BUSY || ret == SQLITE_LOCKED) {
+                       gettimeofday(&now, NULL);
+                       timersub(&now, &from, &diff);
+                       retry = (diff.tv_sec < CTSVC_QUERY_RETRY_TIME)? true:false;
+                       if (retry)
+                               usleep(CTSVC_QUERY_RETRY_INTERVAL);
+               }
+               else
+                       retry = false;
+       }while(retry);
+
+       switch (ret) {
+       case SQLITE_BUSY:
+       case SQLITE_LOCKED:
+               ret = CONTACTS_ERROR_DB_LOCKED /*CTS_ERR_DB_LOCK*/;
+               break;
+       case SQLITE_IOERR:
+               ret = CONTACTS_ERROR_DB /*CTS_ERR_IO_ERR*/;
+               break;
+       case SQLITE_FULL:
+               ret = CONTACTS_ERROR_FILE_NO_SPACE /*CTS_ERR_NO_SPACE*/;
+               break;
+       case SQLITE_CONSTRAINT:
+               ret = CONTACTS_ERROR_DB /*CTS_ERR_ALREADY_EXIST*/;
+               break;
+       case SQLITE_ROW:
+               ret = 1 /*CTS_TRUE*/;
+               break;
+       case SQLITE_DONE:
+               ret = CONTACTS_ERROR_NONE /*CTS_SUCCESS*/;
+               break;
+       case SQLITE_CORRUPT:
+               ASSERT_NOT_REACHED("the database disk image is malformed");
+               ret = CONTACTS_ERROR_DB;
+               break;
+       default:
+               CTS_ERR("sqlite3_step() Failed(%d)", ret);
+               ret = CONTACTS_ERROR_DB;
+               break;
+       }
+       return ret;
+}
+
+void ctsvc_stmt_reset(cts_stmt stmt) {
+       sqlite3_reset(stmt);
+       sqlite3_clear_bindings(stmt);
+}
+
+void ctsvc_stmt_finalize(cts_stmt stmt) {
+       int ret;
+
+       if (NULL == stmt)
+               return;
+
+       ret = sqlite3_finalize(stmt);
+       WARN_IF(ret != SQLITE_OK, "sqlite3_finalize Failed(%d, %s, %d)",
+                       ret, sqlite3_errmsg(ctsvc_db), sqlite3_extended_errcode(ctsvc_db));
+}
+
diff --git a/native/ctsvc_sqlite.h b/native/ctsvc_sqlite.h
new file mode 100755 (executable)
index 0000000..71381f4
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Dohyung Jin <dh.jin@samsung.com>
+ *                 Jongwon Lee <gogosing.lee@samsung.com>
+ *                 Donghee Ye <donghee.ye@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 __TIZEN_SOCIAL_CTSVC_SQLITE_H__
+#define __TIZEN_SOCIAL_CTSVC_SQLITE_H__
+
+#include <sqlite3.h>
+
+#define CTS_SQL_MAX_LEN   2048 //normal string length
+#define CTS_SQL_MIN_LEN  1024 //short sql string length
+
+typedef sqlite3_stmt* cts_stmt;
+
+int ctsvc_db_open(void);
+int ctsvc_db_close(void);
+int ctsvc_db_change();
+int ctsvc_db_get_last_insert_id(void);
+int ctsvc_db_get_next_id(const char *table);
+
+int ctsvc_query_get_first_int_result(const char *query, int *result);
+int ctsvc_query_exec(const char *query);
+int ctsvc_query_prepare(char *query, cts_stmt *stmt);
+
+int ctsvc_stmt_step(cts_stmt stmt);
+void ctsvc_stmt_reset(cts_stmt stmt);
+void ctsvc_stmt_finalize(cts_stmt stmt);
+
+int ctsvc_stmt_get_first_int_result(cts_stmt stmt, int *result);
+
+
+static inline double ctsvc_stmt_get_dbl(cts_stmt stmt, int pos) {
+       return sqlite3_column_double(stmt, pos);
+}
+static inline int ctsvc_stmt_get_int(cts_stmt stmt, int pos) {
+       return sqlite3_column_int(stmt, pos);
+}
+static inline char* ctsvc_stmt_get_text(cts_stmt stmt, int pos) {
+       return (char *)sqlite3_column_text(stmt, pos);
+}
+static inline long long int ctsvc_stmt_get_int64(cts_stmt stmt, int pos) {
+       return sqlite3_column_int64(stmt, pos);
+}
+
+static inline int ctsvc_stmt_bind_int(cts_stmt stmt, int pos, int num) {
+       return sqlite3_bind_int(stmt, pos, num);
+}
+static inline int ctsvc_stmt_bind_text(cts_stmt stmt, int pos, const char *str) {
+       return sqlite3_bind_text(stmt, pos, str, strlen(str), SQLITE_STATIC);
+}
+static inline int ctsvc_stmt_bind_copy_text(cts_stmt stmt, int pos,
+               const char *str, int strlen){
+       return sqlite3_bind_text(stmt, pos, str, strlen, SQLITE_TRANSIENT);
+}
+
+int ctsvc_stmt_bind_copy_text(cts_stmt stmt, int pos, const char *str, int strlen);
+
+
+#endif //__TIZEN_SOCIAL_CTSVC_SQLITE_H__
diff --git a/native/ctsvc_utils.c b/native/ctsvc_utils.c
new file mode 100644 (file)
index 0000000..210dbcb
--- /dev/null
@@ -0,0 +1,607 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/vfs.h>
+#include <image_util.h>
+#include <image_util_internal.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+#include <unicode/ulocdata.h>
+#include <unicode/uset.h>
+#include <unicode/ustring.h>
+#include <libexif/exif-data.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_mutex.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_notification.h"
+#include "ctsvc_struct.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_localize.h"
+#include "ctsvc_localize_utils.h"
+#include "ctsvc_setting.h"
+
+#ifdef _CONTACTS_IPC_SERVER
+#include "ctsvc_server_change_subject.h"
+#endif
+
+static __thread int transaction_count = 0;
+static __thread int transaction_ver = 0;
+static __thread bool version_up = false;
+
+#define CTS_SECURITY_IMAGE_PERMISSION 0440
+#define CTS_IMAGE_ENCODE_QUALITY       50
+
+#define CTS_COMMIT_TRY_MAX 500000 // For 3second
+
+int ctsvc_begin_trans(void)
+{
+       int ret = -1, progress;
+
+#ifndef _CONTACTS_IPC_SERVER
+       ctsvc_mutex_lock(CTS_MUTEX_TRANSACTION);
+#endif
+       if (transaction_count <= 0) {
+               ret = ctsvc_query_exec("BEGIN IMMEDIATE TRANSACTION");
+               progress = 100000;
+               while (CONTACTS_ERROR_DB == ret && progress < CTS_COMMIT_TRY_MAX) {
+                       usleep(progress);
+                       ret = ctsvc_query_exec("BEGIN IMMEDIATE TRANSACTION");
+                       progress *= 2;
+               }
+               if(CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+#ifndef _CONTACTS_IPC_SERVER
+                       ctsvc_mutex_unlock(CTS_MUTEX_TRANSACTION);
+#endif
+                       return ret;
+               }
+
+               transaction_count = 0;
+
+               const char *query = "SELECT ver FROM "CTS_TABLE_VERSION;
+               ret = ctsvc_query_get_first_int_result(query, &transaction_ver);
+               version_up = false;
+       }
+       transaction_count++;
+       INFO("transaction_count : %d.", transaction_count);
+#ifndef _CONTACTS_IPC_SERVER
+       ctsvc_mutex_unlock(CTS_MUTEX_TRANSACTION);
+#endif
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_end_trans(bool is_success)
+{
+       int ret = -1, progress;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+#ifndef _CONTACTS_IPC_SERVER
+       ctsvc_mutex_lock(CTS_MUTEX_TRANSACTION);
+#endif
+
+       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);
+#ifndef _CONTACTS_IPC_SERVER
+               ctsvc_mutex_unlock(CTS_MUTEX_TRANSACTION);
+#endif
+               return CONTACTS_ERROR_NONE;
+       }
+
+       if (false == is_success) {
+               ctsvc_nofitication_cancel();
+#ifdef _CONTACTS_IPC_SERVER
+               ctsvc_change_subject_clear_changed_info();
+#endif
+               ret = ctsvc_query_exec("ROLLBACK TRANSACTION");
+
+#ifndef _CONTACTS_IPC_SERVER
+               ctsvc_mutex_unlock(CTS_MUTEX_TRANSACTION);
+#endif
+               return CONTACTS_ERROR_NONE;
+       }
+
+       if (version_up) {
+               transaction_ver++;
+               snprintf(query, sizeof(query), "UPDATE %s SET ver = %d",
+                               CTS_TABLE_VERSION, transaction_ver);
+               ret = ctsvc_query_exec(query);
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_query_exec(version up) Failed(%d)", ret);
+       }
+
+       INFO("start commit");
+       progress = 100000;
+       ret = ctsvc_query_exec("COMMIT TRANSACTION");
+       while (CONTACTS_ERROR_DB == ret && progress<CTS_COMMIT_TRY_MAX) {
+               usleep(progress);
+               ret = ctsvc_query_exec("COMMIT TRANSACTION");
+               progress *= 2;
+       }
+       INFO("%s", (CONTACTS_ERROR_NONE == ret)?"commit": "rollback");
+
+       if (CONTACTS_ERROR_NONE != ret) {
+               int tmp_ret;
+               CTS_ERR("ctsvc_query_exec() Failed(%d)", ret);
+               ctsvc_nofitication_cancel();
+#ifdef _CONTACTS_IPC_SERVER
+               ctsvc_change_subject_clear_changed_info();
+#endif
+               tmp_ret = ctsvc_query_exec("ROLLBACK TRANSACTION");
+               WARN_IF(CONTACTS_ERROR_NONE != tmp_ret, "ctsvc_query_exec(ROLLBACK) Failed(%d)", tmp_ret);
+#ifndef _CONTACTS_IPC_SERVER
+               ctsvc_mutex_unlock(CTS_MUTEX_TRANSACTION);
+#endif
+               return ret;
+       }
+
+       ctsvc_notification_send();
+#ifdef _CONTACTS_IPC_SERVER
+       ctsvc_change_subject_publish_changed_info();
+#endif
+
+#ifndef _CONTACTS_IPC_SERVER
+       ctsvc_mutex_unlock(CTS_MUTEX_TRANSACTION);
+#endif
+
+       CTS_DBG("Transaction shut down! : (%d)\n", transaction_ver);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+const char* ctsvc_get_display_column(void)
+{
+       contacts_name_display_order_e order;
+
+       contacts_setting_get_name_display_order(&order);
+       if (CONTACTS_NAME_DISPLAY_ORDER_FIRSTLAST == order)
+               return "display_name";
+       else
+               return "reverse_display_name";
+}
+
+const char* ctsvc_get_sort_name_column(void)
+{
+       contacts_name_sorting_order_e order;
+
+       contacts_setting_get_name_sorting_order(&order);
+       if (CONTACTS_NAME_SORTING_ORDER_FIRSTLAST == order)
+               return "sort_name, display_name_language";
+       else
+               return "reverse_sort_name, reverse_display_name_language";
+}
+
+const char* ctsvc_get_sort_column(void)
+{
+       contacts_name_sorting_order_e order;
+
+       contacts_setting_get_name_sorting_order(&order);
+       if (CONTACTS_NAME_SORTING_ORDER_FIRSTLAST == order)
+               return "display_name_language, sortkey";
+       else
+               return "reverse_display_name_language, reverse_sortkey";
+}
+
+void ctsvc_utils_make_image_file_name(int parent_id, int id, char *src_img, char *dest, int dest_size)
+{
+       char *ext;
+       char *temp;
+       char *lower_ext;
+
+       ext = strrchr(src_img, '.');
+       if (NULL == ext || strchr(ext, '/'))
+               ext = "";
+
+       lower_ext = strdup(ext);
+       RETM_IF(NULL == lower_ext, "strdup() return NULL");
+
+       temp = lower_ext;
+       while (*temp) {
+               *temp = tolower(*temp);
+               temp++;
+       }
+
+       if (parent_id > 0)
+               snprintf(dest, dest_size, "%d_%d%s", parent_id, id, lower_ext);
+       else
+               snprintf(dest, dest_size, "%d%s", id, ext);
+       free(lower_ext);
+}
+
+static inline bool ctsvc_check_available_image_space(void){
+       int ret;
+       struct statfs buf;
+       long long size;
+       ret = statfs(CTSVC_IMG_FULL_LOCATION, &buf);
+
+       RETVM_IF(ret!=0, false, "statfs Failed(%d)", ret);
+
+       size = (long long)buf.f_bavail * (buf.f_bsize);
+
+       if (size > 1024*1024) // if available space to copy a image is larger than 1M
+               return true;
+       return false;
+}
+
+static image_util_rotation_e __ctsvc_get_rotation_info(const char *path)
+{
+       ExifData *ed = NULL;
+       ExifEntry *entry;
+       image_util_rotation_e rotation = IMAGE_UTIL_ROTATION_NONE;
+       int orientation = 0;
+
+       ed = exif_data_new_from_file(path);
+       if (ed == NULL) {
+               CTS_ERR("exif_data_new_from_file : ExifData is NULL");
+               return IMAGE_UTIL_ROTATION_NONE;
+       }
+
+       entry = exif_data_get_entry(ed, EXIF_TAG_ORIENTATION);
+       if (entry) {
+               ExifByteOrder mByteOrder = exif_data_get_byte_order(ed);
+               orientation = (int)exif_get_short(entry->data, mByteOrder);
+               if (orientation < 0 || orientation > 8)
+                       orientation = 0;
+       }
+
+       if (ed)
+               exif_data_unref(ed);
+
+       switch(orientation) {
+       case 1: // Top-left
+               rotation = IMAGE_UTIL_ROTATION_NONE;
+               break;
+       case 2: // Top-right
+               rotation = IMAGE_UTIL_ROTATION_FLIP_HORZ;
+               break;
+       case 3: // Bottom-right
+               rotation = IMAGE_UTIL_ROTATION_180;
+               break;
+       case 4: // Bottom-left
+               rotation = IMAGE_UTIL_ROTATION_FLIP_VERT;
+               break;
+       case 6:         // Right-top
+               rotation = IMAGE_UTIL_ROTATION_90;
+               break;
+       case 8: // Left-bottom
+               rotation = IMAGE_UTIL_ROTATION_270;
+               break;
+       case 5: // Left-top
+       case 7: // Right-bottom
+       case 0:
+       default:
+               break;
+       };
+
+       return rotation;
+}
+
+static int image_size = 480;
+
+typedef struct {
+       const char *src;
+       const char *dest;
+       int ret;
+}image_info;
+
+static bool __ctsvc_image_util_supported_jpeg_colorspace_cb(image_util_colorspace_e colorspace, void *user_data)
+{
+       image_info *info = (image_info*)user_data;
+       image_util_error_e ret;
+       int width = 0, height = 0;
+       unsigned int size_decode = 0;
+       int resized_width, resized_height;
+       unsigned char * img_target = 0;
+       unsigned char * img_source = 0;
+       int dest_fd;
+       image_util_rotation_e rotation;
+
+       // temporary code
+       if (colorspace == IMAGE_UTIL_COLORSPACE_YV12 || colorspace == IMAGE_UTIL_COLORSPACE_I420) {
+               info->ret = CONTACTS_ERROR_SYSTEM;
+               return true;
+       }
+
+       rotation = __ctsvc_get_rotation_info(info->src);
+
+       // load jpeg sample file
+       CTS_DBG("colorspace %d src : %s, dest : %s", colorspace, info->src, info->dest);
+       ret = image_util_decode_jpeg( info->src, colorspace, &img_source, &width, &height, &size_decode );
+       if (ret!=IMAGE_UTIL_ERROR_NONE) {
+               info->ret = CONTACTS_ERROR_SYSTEM;
+               return true;
+       }
+
+#if 0
+       if (0>image_size) {
+               int w,h;
+               ecore_x_window_size_get(
+                               ecore_x_window_root_get(ecore_x_window_focus_get())
+                               , &w, &h);
+
+               if (w>h)
+                       image_size = h;
+               else
+                       image_size = w;
+
+       }
+#endif
+
+       if (width > image_size || height > image_size) {
+               // image resize
+               if (image_size<=0 || width <=0 || height <= 0) {
+                       free(img_source);
+                       CTS_ERR("image size error(%d)", image_size);
+                       info->ret = CONTACTS_ERROR_SYSTEM;
+                       return false;
+               }
+
+               if (width>height) {
+                       resized_width = image_size;
+                       resized_height = height*image_size/width;
+               }
+               else {
+                       resized_height = image_size;
+                       resized_width = width*image_size/height;
+               }
+
+               if (resized_height%8)
+                       resized_height += 8 - (resized_height%8);
+               if (resized_width%8)
+                       resized_width += 8 - (resized_width%8);
+
+               CTS_DBG("size(%d, %d) -> resize(%d,%d)", width, height, resized_width, resized_height);
+
+               image_util_calculate_buffer_size(resized_width, resized_height, colorspace , &size_decode);
+
+               img_target = malloc( size_decode );
+
+               // do resize
+               ret = image_util_resize( img_target, &resized_width, &resized_height,
+                               img_source, width, height, colorspace );
+               if (ret!=IMAGE_UTIL_ERROR_NONE) {
+                       CTS_ERR("image_util_resize failed(%d)", ret);
+                       free( img_target );
+                       free( img_source );
+                       info->ret = CONTACTS_ERROR_SYSTEM;
+                       return false;
+               }
+               free( img_source );
+       }
+       else {
+               resized_width = width;
+               resized_height = height;
+               img_target = img_source;
+       }
+
+       // image rotation
+       if (IMAGE_UTIL_ROTATION_NONE != rotation) {
+               int rotated_width, rotated_height;
+               unsigned char *img_rotate = 0;
+               img_rotate = malloc( size_decode );
+               ret= image_util_rotate(img_rotate, &rotated_width, &rotated_height,
+                                       rotation, img_target, resized_width, resized_height, colorspace);
+               free(img_target);
+               if (IMAGE_UTIL_ERROR_NONE != ret) {
+                       CTS_ERR("image_util_rotate failed(%d)", ret);
+                       info->ret = CONTACTS_ERROR_SYSTEM;
+                       free(img_rotate);
+                       return false;
+               }
+               resized_width = rotated_width;
+               resized_height = rotated_height;
+               img_target = img_rotate;
+       }
+
+       // image encode
+       ret = image_util_encode_jpeg(img_target, resized_width, resized_height, colorspace, CTS_IMAGE_ENCODE_QUALITY, info->dest );
+       free( img_target );
+       if(ret != IMAGE_UTIL_ERROR_NONE) {
+               CTS_ERR("image_util_encode_jpeg failed(%d)", ret);
+               info->ret = CONTACTS_ERROR_SYSTEM;
+               return false;
+       }
+
+       dest_fd = open(info->dest, O_RDONLY);
+       if (dest_fd < 0) {
+               CTS_ERR("System : Open Failed(%d)", errno);
+               info->ret = CONTACTS_ERROR_SYSTEM;
+               return false;
+       }
+
+       ret = fchown(dest_fd, getuid(), CTS_SECURITY_FILE_GROUP);
+       if (0 != ret) {
+               CTS_ERR("fchown Failed(%d)", errno);
+               info->ret = CONTACTS_ERROR_SYSTEM;
+               close(dest_fd);
+               return false;
+       }
+
+       ret = fchmod(dest_fd, CTS_SECURITY_IMAGE_PERMISSION);
+       if (0 != ret) {
+               CTS_ERR("fchmod Failed(%d)", errno);
+               info->ret = CONTACTS_ERROR_SYSTEM;
+               close(dest_fd);
+               return false;
+       }
+       close(dest_fd);
+
+       info->ret = CONTACTS_ERROR_NONE;
+       return false;
+}
+
+static int __ctsvc_resize_and_copy_image(const char *src, const char *dest)
+{
+       int ret;
+       image_info info = {.src = src, .dest = dest, ret = CONTACTS_ERROR_SYSTEM};
+
+       ret = image_util_foreach_supported_jpeg_colorspace(__ctsvc_image_util_supported_jpeg_colorspace_cb, &info);
+
+       if (ret != IMAGE_UTIL_ERROR_NONE)
+               return CONTACTS_ERROR_SYSTEM;
+
+       return info.ret;
+}
+
+#define CTSVC_COPY_SIZE_MAX 4096
+int ctsvc_utils_copy_image(const char *dir, const char *src, const char *file)
+{
+       int ret;
+       int size;
+       int src_fd, dest_fd;
+       char buf[CTSVC_COPY_SIZE_MAX] = {0};
+
+       if (NULL == file || *file == '\0')
+               return CONTACTS_ERROR_INVALID_PARAMETER;
+
+       char dest[strlen(dir) + strlen(file) + 2];
+       snprintf(dest, sizeof(dest), "%s/%s", dir, file);
+
+       if (!ctsvc_check_available_image_space())
+               return CONTACTS_ERROR_FILE_NO_SPACE;
+
+       ret = __ctsvc_resize_and_copy_image(src, dest);
+       if (CONTACTS_ERROR_NONE == ret) {
+               return ret;
+       }
+       else
+               CTS_ERR("__ctsvc_resize_and_copy_image Failed(%d)", ret);
+
+       src_fd = open(src, O_RDONLY);
+       RETVM_IF(src_fd < 0, CONTACTS_ERROR_SYSTEM, "System : Open(src:%s) Failed(%d)", src, errno);
+       dest_fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0660);
+       if (dest_fd < 0) {
+               CTS_ERR("Open Failed(%d)", errno);
+               close(src_fd);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       while ((size = read(src_fd, buf, CTSVC_COPY_SIZE_MAX)) > 0) {
+               ret = write(dest_fd, buf, size);
+               if (ret <= 0) {
+                       if (EINTR == errno)
+                               continue;
+                       else {
+                               CTS_ERR("write() Failed(%d)", errno);
+                               if (ENOSPC == errno)
+                                       ret = CONTACTS_ERROR_FILE_NO_SPACE;     // No space
+                               else
+                                       ret = CONTACTS_ERROR_SYSTEM;                    // IO error
+                               close(src_fd);
+                               close(dest_fd);
+                               unlink(dest);
+                               return ret;
+                       }
+               }
+       }
+
+       ret = fchown(dest_fd, getuid(), CTS_SECURITY_FILE_GROUP);
+       if (0 != ret) {
+               CTS_ERR("fchown() Failed(%d)", ret);
+       }
+       ret = fchmod(dest_fd, CTS_SECURITY_IMAGE_PERMISSION);
+       if (0 != ret) {
+               CTS_ERR("fchmod() Failed(%d)", ret);
+       }
+       close(src_fd);
+       close(dest_fd);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_get_next_ver(void)
+{
+       const char *query;
+       int version;
+       int ret;
+
+       if (0 < transaction_count) {
+               version_up = true;
+               return transaction_ver + 1;
+       }
+
+       query = "SELECT ver FROM "CTS_TABLE_VERSION;
+       ret = ctsvc_query_get_first_int_result(query, &version);
+
+       // In this case, contacts-service already works abnormally.
+       if (CONTACTS_ERROR_NONE != ret)
+               CTS_ERR("ctsvc_query_get_first_int_result : get version error(%d)", ret);
+
+       return (1 + version);
+}
+
+int ctsvc_get_current_version( int* out_current_version ){
+       if (transaction_count <= 0) {
+               int ret;
+               int version = 0;
+               const char *query = "SELECT ver FROM "CTS_TABLE_VERSION;
+               ret = ctsvc_query_get_first_int_result(query, &version);
+               RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_get_first_int_result() Failed(%d)", ret);
+               *out_current_version = version;
+       }
+       else
+               *out_current_version = transaction_ver;
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_get_transaction_ver(void)
+{
+       return transaction_ver;
+}
+
+int SAFE_SNPRINTF(char **buf, int *buf_size, int len, const char *src)
+{
+       int remain;
+       int temp_len;
+
+       if (len < 0)
+               return -1;
+
+       remain = *buf_size - len;
+       if (remain > strlen(src) + 1) {
+               temp_len = snprintf((*buf)+len, remain, "%s", src);
+               return temp_len;
+       }
+       else {
+               char *temp;
+               while(1) {
+                       temp = realloc(*buf, *buf_size*2);
+                       if (NULL == temp)
+                               return -1;
+                       *buf = temp;
+                       *buf_size = *buf_size * 2;
+                       remain = *buf_size - len;
+                       if (remain > strlen(src) + 1)
+                               break;
+               }
+               temp_len = snprintf((*buf)+len, remain, "%s", src);
+               return temp_len;
+       }
+}
+
diff --git a/native/ctsvc_utils.h b/native/ctsvc_utils.h
new file mode 100644 (file)
index 0000000..bc6de7e
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __TIZEN_SOCIAL_CTSVC_UTILS_H__
+#define __TIZEN_SOCIAL_CTSVC_UTILS_H__
+
+const char* ctsvc_get_display_column(void);
+const char* ctsvc_get_sort_column(void);
+const char* ctsvc_get_sort_name_column(void);
+
+int ctsvc_begin_trans(void);
+int ctsvc_end_trans(bool is_success);
+int ctsvc_get_next_ver(void);
+int ctsvc_get_current_version( int* out_current_version );
+int ctsvc_get_transaction_ver(void);
+
+int ctsvc_utils_copy_image(const char *dir, const char *src, const char *file);
+void ctsvc_utils_make_image_file_name(int parent_id, int id, char *src_img, char *dest, int dest_size);
+
+int SAFE_SNPRINTF(char **buf, int *buf_size, int len, const char *src);
+
+#endif /* __TIZEN_SOCIAL_CTSVC_UTILS_H__ */
diff --git a/packaging/contacts-service.service b/packaging/contacts-service.service
new file mode 100644 (file)
index 0000000..c36487e
--- /dev/null
@@ -0,0 +1,13 @@
+[Unit]
+Description=Start the Contacts service helper service
+After=tizen-runtime.target
+Requires=tizen-runtime.target
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/contacts-service-ipcd
+Restart=always
+RestartSec=1
+
+[Install]
+WantedBy=multi-user.target
diff --git a/packaging/contacts-service.socket b/packaging/contacts-service.socket
new file mode 100644 (file)
index 0000000..8f70c0f
--- /dev/null
@@ -0,0 +1,11 @@
+[Unit]
+Description=Contacts Service socket
+
+[Socket]
+ListenStream=/tmp/.contacts_svc_ipc
+SmackLabelIPIn=contacts-service
+SmackLabelIPOut=contacts-service
+Service=contacts-service.service
+
+[Install]
+WantedBy=sockets.target
index 123ba70..1cb201c 100644 (file)
@@ -1,14 +1,12 @@
 Name:       contacts-service
 Summary:    Contacts Service
-Version: 0.6.12
+Version:    0.13.11
 Release:    1
 Group:      TO_BE/FILLED_IN
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
-Requires(post): /sbin/ldconfig
-Requires(post): /usr/bin/sqlite3
-Requires(post): /usr/bin/vconftool
-Requires(postun): /sbin/ldconfig
+Source1:    contacts-service.service
+Source2:    contacts-service.socket
 BuildRequires:  cmake
 BuildRequires:  vconf-keys-devel
 BuildRequires:  pkgconfig(db-util)
@@ -18,74 +16,125 @@ BuildRequires:  pkgconfig(sqlite3)
 BuildRequires:  pkgconfig(tapi)
 BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(icu-i18n)
-BuildRequires:  pkgconfig(libsystemd-daemon)
+BuildRequires:  pkgconfig(capi-base-common)
+BuildRequires:  pkgconfig(capi-media-image-util)
+BuildRequires:  pkgconfig(pims-ipc)
+BuildRequires:  pkgconfig(capi-system-info)
+%if "%{?tizen_profile_name}" == "mobile"
+BuildRequires:  pkgconfig(accounts-svc)
+%endif
+BuildRequires:  pkgconfig(libexif)
+BuildRequires:  pkgconfig(libsmack)
+BuildRequires:  pkgconfig(security-server)
+Requires(post): /usr/bin/sqlite3, /bin/chmod, /bin/chown
+Requires(post): /usr/bin/vconftool
+Requires(post): /sbin/ldconfig
+Requires(post): telephony-daemon
+Requires(postun): /sbin/ldconfig
+Requires: sys-assert
 
 %description
 Contacts Service Library
 
-%package devel
-Summary:    Contacts Service  (devel)
+%package -n contacts-service2
+Summary:       New Contacts service library
+Group: Development/Libraries
+Requires: sys-assert
+Requires: security-server
+Requires(post): telephony-daemon
+Requires(post): libprivilege-control-conf
+
+%description -n contacts-service2
+New Contact Serivce Library
+
+
+%package -n contacts-service2-devel
+Summary:    New Contacts Service  (devel)
 Group:      Development/Libraries
-Requires:   %{name} = %{version}-%{release}
+Requires:   %{name}2 = %{version}-%{release}
 
-%description devel
-Contacts Service Library (devel)
+%description -n contacts-service2-devel
+New Contacts Service Library (devel)
 
 %prep
 %setup -q
 
 
 %build
-cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix}
+export CFLAGS="$CFLAGS -DTIZEN_ENGINEER_MODE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_ENGINEER_MODE"
+export FFLAGS="$FFLAGS -DTIZEN_ENGINEER_MODE"
+
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} \
+%if "%{?tizen_profile_name}" == "mobile"
+       -DCTS_MOBILE:BOOL=ON \
+%endif
+       -DENABLE_SIM_FEATURE:BOOL=ON \
+       -DENABLE_LOG_FEATURE:BOOL=ON \
+       -DMAJORVER=${MAJORVER} \
+       -DFULLVER=%{version}
 
+make %{?_smp_mflags}
 
-make %{?jobs:-j%jobs}
 
 %install
 rm -rf %{buildroot}
 %make_install
 
-mkdir -p %{buildroot}/etc/rc.d/rc3.d/
-mkdir -p %{buildroot}/etc/rc.d/rc5.d/
-ln -s ../init.d/contacts-svc-helper.sh %{buildroot}/etc/rc.d/rc3.d/S50contacts-svc-helper
-ln -s ../init.d/contacts-svc-helper.sh %{buildroot}/etc/rc.d/rc5.d/S50contacts-svc-helper
+mkdir -p %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants
+install -m 0644 %SOURCE1 %{buildroot}%{_libdir}/systemd/system/contacts-service.service
+ln -s ../contacts-service.service %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/contacts-service.service
 
-%post
+mkdir -p %{buildroot}%{_libdir}/systemd/system/sockets.target.wants
+install -m 0644 %SOURCE2 %{buildroot}%{_libdir}/systemd/system/contacts-service.socket
+ln -s ../contacts-service.socket %{buildroot}%{_libdir}/systemd/system/sockets.target.wants/contacts-service.socket
+
+mkdir -p %{buildroot}/usr/share/license
+cp LICENSE.APLv2 %{buildroot}/usr/share/license/contacts-service2
+cp LICENSE.APLv2 %{buildroot}/usr/share/license/contacts-service2-devel
+
+%post -n contacts-service2
 /sbin/ldconfig
 
-# from contacts-service-bin.postinst
-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_*_CHANGED
+chown :5000 /opt/usr/data/contacts-svc
+chown :5000 /opt/usr/dbspace/.contacts-svc.db
+chown :5000 /opt/usr/dbspace/.contacts-svc.db-journal
+chown :5000 -R /opt/usr/data/contacts-svc/img
+chown :5000 /opt/usr/data/contacts-svc/.CONTACTS_SVC_*
 
-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 file/private/contacts-service/default_lang 1
+chmod 660 /opt/usr/dbspace/.contacts-svc.db
+chmod 660 /opt/usr/dbspace/.contacts-svc.db-journal
+chmod 775 /opt/usr/data/contacts-svc
+chmod 770 -R /opt/usr/data/contacts-svc/img/
+chmod 660 /opt/usr/data/contacts-svc/.CONTACTS_SVC_*
 
-# from libcontacts-service.postinst
-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
+vconftool set -t int file/private/contacts-service/default_lang 0 -g 5000 -s contacts-service::vconf-private
+vconftool set -t int db/contacts-svc/name_sorting_order 0 -g 5000 -s contacts-service::vconf
+vconftool set -t int db/contacts-svc/name_display_order 0 -g 5000 -s contacts-service::vconf
+vconftool set -t int db/contacts-svc/phonenumber_min_match_digit 8 -g 5000 -s contacts-service::vconf
 
 
 %postun -p /sbin/ldconfig
 
-
-%files
+%files -n contacts-service2
+%manifest contacts-service2.manifest
 %defattr(-,root,root,-)
-%{_libdir}/libcontacts-service.so*
-%{_bindir}/contacts-svc-helper*
-%attr(0755,root,root) /etc/rc.d/init.d/contacts-svc-helper.sh
-/etc/rc.d/rc*.d/S50contacts-svc-helper
-/opt/data/contacts-svc/.CONTACTS_SVC_*
-/opt/data/contacts-svc/img/*
-
-%files devel
+%{_libdir}/libcontacts-service2.so.*
+%{_bindir}/contacts-service-ipcd*
+/opt/usr/data/contacts-svc/.CONTACTS_SVC_*
+/opt/usr/data/contacts-svc/img/*
+%{_libdir}/systemd/system/contacts-service.service
+%{_libdir}/systemd/system/multi-user.target.wants/contacts-service.service
+%{_libdir}/systemd/system/sockets.target.wants/contacts-service.socket
+%{_libdir}/systemd/system/contacts-service.socket
+%config(noreplace) /opt/usr/dbspace/.contacts-svc.db*
+/usr/share/license/%{name}2
+
+%files -n contacts-service2-devel
 %defattr(-,root,root,-)
-%{_libdir}/*.so
-%{_libdir}/pkgconfig/contacts-service.pc
-%{_includedir}/contacts-svc/*.h
+%{_libdir}/libcontacts-service2.so
+%{_libdir}/pkgconfig/contacts-service2.pc
+%{_includedir}/contacts-svc/contacts.h
+%{_includedir}/contacts-svc/contacts_*.h
+/usr/share/license/contacts-service2-devel
diff --git a/res/.CONTACTS_SVC_EMAIL_CHANGED b/res/.CONTACTS_SVC_EMAIL_CHANGED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/res/.CONTACTS_SVC_EVENT_CHANGED b/res/.CONTACTS_SVC_EVENT_CHANGED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/res/.CONTACTS_SVC_GROUP_RELATION_CHANGED b/res/.CONTACTS_SVC_GROUP_RELATION_CHANGED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/res/.CONTACTS_SVC_IMAGE_CHANGED b/res/.CONTACTS_SVC_IMAGE_CHANGED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/res/.CONTACTS_SVC_IPC_READY b/res/.CONTACTS_SVC_IPC_READY
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/res/.CONTACTS_SVC_MESSENGER_CHANGED b/res/.CONTACTS_SVC_MESSENGER_CHANGED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/res/.CONTACTS_SVC_MY_PROFILE_CHANGED b/res/.CONTACTS_SVC_MY_PROFILE_CHANGED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/res/.CONTACTS_SVC_NAME_CHANGED b/res/.CONTACTS_SVC_NAME_CHANGED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/res/.CONTACTS_SVC_NICKNAME_CHANGED b/res/.CONTACTS_SVC_NICKNAME_CHANGED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/res/.CONTACTS_SVC_NOTE_CHANGED b/res/.CONTACTS_SVC_NOTE_CHANGED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/res/.CONTACTS_SVC_NUMBER_CHANGED b/res/.CONTACTS_SVC_NUMBER_CHANGED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/res/.CONTACTS_SVC_PERSON_CHANGED b/res/.CONTACTS_SVC_PERSON_CHANGED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/res/.CONTACTS_SVC_PROFILE_CHANGED b/res/.CONTACTS_SVC_PROFILE_CHANGED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/res/.CONTACTS_SVC_RELATIONSHIP_CHANGED b/res/.CONTACTS_SVC_RELATIONSHIP_CHANGED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/res/.CONTACTS_SVC_SDN_CHANGED b/res/.CONTACTS_SVC_SDN_CHANGED
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/res/.CONTACTS_SVC_URL_CHANGED b/res/.CONTACTS_SVC_URL_CHANGED
new file mode 100644 (file)
index 0000000..e69de29
index 7714c11..e1fa401 100755 (executable)
@@ -3,7 +3,7 @@
 --
 -- Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
 --
--- Contact: Youngjae Shin <yj99.shin@samsung.com>
+-- Contact: Jongwon Lee <gogosing.lee@samsung.com>
 --
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
 
 --PRAGMA journal_mode = PERSIST;
 --PRAGMA journal_mode = TRUNCATE;
+PRAGMA user_version = 101;
 
 CREATE TABLE persons
 (
-person_id INTEGER PRIMARY KEY AUTOINCREMENT,
-outgoing_count INTEGER DEFAULT 0
+       person_id                       INTEGER PRIMARY KEY AUTOINCREMENT,
+       name_contact_id         INTEGER NOT NULL,
+       has_phonenumber         INTEGER,
+       has_email                       INTEGER,
+       created_ver                     INTEGER NOT NULL,
+       changed_ver                     INTEGER NOT NULL,
+       ringtone_path                   TEXT,
+       vibration                       TEXT,
+       message_alert           TEXT,
+       image_thumbnail_path            TEXT,
+       image_path                      TEXT,
+       link_count                      INTEGER,
+       addressbook_ids                 TEXT,
+       dirty                           INTEGER,
+       status                          TEXT
 );
 
+CREATE TRIGGER trg_person_del AFTER DELETE ON persons
+ BEGIN
+       DELETE FROM favorites WHERE person_id = old.person_id;
+       SELECT _PERSON_DELETE_(old.person_id);
+ END;
+
 CREATE TABLE addressbooks
 (
-addrbook_id INTEGER PRIMARY KEY AUTOINCREMENT,
-addrbook_name TEXT,
-acc_id INTEGER,
-acc_type INTEGER DEFAULT 0,
-mode INTEGER, -- permission
-last_sync_ver INTEGER
+       addressbook_id          INTEGER PRIMARY KEY AUTOINCREMENT,
+       addressbook_name        TEXT NOT NULL,
+       account_id                      INTEGER,
+       mode                                            INTEGER, -- permission
+       last_sync_ver   INTEGER,
+       smack_label             TEXT NOT NULL,          -- smack label
+       UNIQUE(addressbook_name)
 );
---CREATE TRIGGER trg_addressbook_sync AFTER UPDATE OF last_sync_ver ON addressbooks
--- BEGIN
---   DELETE FROM deleteds WHERE addrbook_id = new.addrbook_id and deleted_time <= new.last_sync_ver;
--- END;
+
+INSERT INTO addressbooks(addressbook_id, addressbook_name, mode, account_id, smack_label) values(0, 'http://tizen.org/addressbook/phone', 0, 0, 'org.tizen.contacts');
+
 CREATE TRIGGER trg_addressbook_del AFTER DELETE ON addressbooks
  BEGIN
-   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;
+   DELETE FROM groups WHERE addressbook_id = old.addressbook_id;
+   UPDATE contacts SET deleted = 1, person_id = 0, changed_ver = ((SELECT ver FROM cts_version) + 1) WHERE addressbook_id = old.addressbook_id;
+   DELETE FROM my_profiles WHERE addressbook_id = old.addressbook_id;
+   DELETE FROM contact_deleteds WHERE addressbook_id = old.addressbook_id;
+   DELETE FROM group_deleteds WHERE addressbook_id = old.addressbook_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,
-default_addr INTEGER,
-is_favorite INTEGER DEFAULT 0,
-created_ver INTEGER NOT NULL,
-changed_ver INTEGER NOT NULL,
-changed_time INTEGER NOT NULL,
-uid TEXT,
-ringtone TEXT,
-note TEXT,
-image0 TEXT, -- normal image
-image1 TEXT -- full image
+       contact_id                      INTEGER PRIMARY KEY AUTOINCREMENT,
+       person_id                       INTEGER NOT NULL,
+       addressbook_id                  INTEGER NOT NULL DEFAULT 0,
+       has_phonenumber         INTEGER,
+       has_email                       INTEGER,
+       is_favorite                     INTEGER DEFAULT 0,
+       deleted                         INTEGER DEFAULT 0,
+       display_name                    TEXT,
+       reverse_display_name            TEXT,
+       display_name_source             INTEGER,
+       display_name_language           INTEGER,
+       reverse_display_name_language           INTEGER,
+       sort_name                       TEXT,
+       reverse_sort_name               TEXT,
+       sortkey                         TEXT,
+       reverse_sortkey                 TEXT,
+       created_ver                     INTEGER NOT NULL,
+       changed_ver                     INTEGER NOT NULL,
+       changed_time                    INTEGER NOT NULL,
+       link_mode               INTEGER NOT NULL,
+       image_changed_ver       INTEGER NOT NULL,
+       uid                             TEXT,
+       ringtone_path                   TEXT,
+       vibration                       TEXT,
+       message_alert           TEXT,
+       image_thumbnail_path            TEXT,
+       image_path                      TEXT
 );
-CREATE INDEX contacts_ver_idx ON contacts(changed_ver);
-CREATE INDEX contacts_person_idx ON contacts(person_id);
+
+CREATE INDEX contacts_idx1 ON contacts(changed_ver);
+CREATE INDEX contacts_idx2 ON contacts(person_id);
+CREATE INDEX contacts_idx3 ON contacts(display_name_language, sortkey);
+CREATE INDEX contacts_idx4 ON contacts(reverse_display_name_language, reverse_sortkey);
+CREATE INDEX contacts_idx5 ON contacts(addressbook_id);
+
+-- There are three case of deleting contact logically
+--   Case 1 : delete contact
+--   Case 2 : delete addressbook
+--   Case 3 : delete person
+-- In all Case, the deleted contacts(deleted=1) are really deleted in the background.
 CREATE TRIGGER trg_contacts_del AFTER DELETE ON contacts
- BEGIN
-   DELETE FROM data WHERE contact_id = old.contact_id;
-   DELETE FROM group_relations WHERE old.addrbook_id != -1 AND contact_id = old.contact_id;
-   DELETE FROM favorites WHERE type = 0 AND related_id = old.contact_id;
- END;
+       BEGIN
+               DELETE FROM data WHERE contact_id = old.contact_id AND is_my_profile = 0;
+               DELETE FROM group_relations WHERE old.addressbook_id != -1 AND contact_id = old.contact_id;
+               DELETE FROM activities WHERE contact_id = old.contact_id;
+               DELETE FROM persons WHERE person_id = old.person_id AND link_count = 1;
+               DELETE FROM search_index WHERE contact_id = old.contact_id;
+               DELETE FROM name_lookup WHERE contact_id = old.contact_id;
+               DELETE FROM phone_lookup WHERE contact_id = old.contact_id;
+               UPDATE persons SET dirty=1 WHERE person_id = old.person_id AND link_count > 1;
+       END;
 
-CREATE TABLE deleteds
+-- It is triggered during really deleting contact in the background (deleted = 1).
+-- Deleted version(changed_ver) is already set when updating deleted field as 1.
+CREATE TRIGGER trg_contacts_del2 AFTER DELETE ON contacts
+       WHEN old.addressbook_id = (SELECT addressbook_id from addressbooks WHERE addressbook_id = old.addressbook_id) AND old.deleted = 1
+       BEGIN
+               INSERT INTO contact_deleteds VALUES(old.contact_id, old.addressbook_id, old.created_ver, old.changed_ver);
+       END;
+
+-- CREATE TRIGGER trg_contacts_del3 AFTER DELETE ON contacts
+--     WHEN old.addressbook_id = (SELECT addressbook_id from addressbooks WHERE addressbook_id = old.addressbook_id) AND old.deleted = 0
+--     BEGIN
+--             INSERT INTO contact_deleteds VALUES(old.contact_id, old.addressbook_id, old.created_ver, (SELECT ver FROM cts_version) + 1);
+--     END;
+
+CREATE TRIGGER trg_contacts_update AFTER UPDATE ON contacts
+       WHEN new.deleted = 1
+       BEGIN
+               SELECT _DATA_DELETE_(data.id, data.datatype) FROM data WHERE contact_id = old.contact_id AND is_my_profile = 0;
+               DELETE FROM group_relations WHERE old.addressbook_id != -1 AND contact_id = old.contact_id;
+               DELETE FROM persons WHERE person_id = old.person_id AND link_count = 1;
+               UPDATE persons SET dirty=1 WHERE person_id = old.person_id AND link_count > 1;
+               DELETE FROM speeddials WHERE number_id IN (SELECT id FROM data WHERE data.contact_id = old.contact_id AND datatype = 8);
+       END;
+
+CREATE TABLE contact_deleteds
 (
-contact_id INTEGER PRIMARY KEY,
-addrbook_id INTEGER,
-deleted_ver INTEGER
+       contact_id                      INTEGER PRIMARY KEY,
+       addressbook_id          INTEGER NOT NULL,
+       created_ver                     INTEGER NOT NULL,
+       deleted_ver                     INTEGER NOT NULL
 );
-CREATE INDEX deleteds_ver_idx ON deleteds(deleted_ver);
+CREATE INDEX contact_deleteds_idx1 ON contact_deleteds(deleted_ver);
 
 CREATE TABLE cts_version
 (
-ver INTEGER PRIMARY KEY
+       ver                             INTEGER PRIMARY KEY
 );
+
 INSERT INTO cts_version VALUES(0);
 
-CREATE TABLE sim_services
+CREATE TABLE sdn
 (
-id INTEGER PRIMARY KEY AUTOINCREMENT,
-type INTEGER,
-name TEXT,
-number TEXT
+       id                              INTEGER PRIMARY KEY AUTOINCREMENT,
+       name                            TEXT,
+       number                          TEXT,
+       sim_slot_no             INTEGER
 );
 
-CREATE TABLE custom_types
-(
-id INTEGER PRIMARY KEY AUTOINCREMENT,
-class INTEGER,
-name TEXT,
-UNIQUE(class, name)
-);
-CREATE INDEX idx_custom_type ON custom_types(class, name);
-CREATE TRIGGER trg_custom_types_del AFTER DELETE ON custom_types
- BEGIN
-        UPDATE data SET data1 = 0 WHERE old.class = 1 AND number_type = old.id AND datatype = 8;
- END;
-
 CREATE TABLE data
 (
-id INTEGER PRIMARY KEY AUTOINCREMENT,
-contact_id INTEGER NOT NULL,
-is_restricted INTEGER,
-datatype INTEGER NOT NULL,
-data1 INTEGER,
-data2 TEXT,
-data3 TEXT,
-data4 TEXT,
-data5 TEXT,
-data6 TEXT,
-data7 TEXT,
-data8 TEXT,
-data9 TEXT,
-data10 TEXT
+       id                              INTEGER PRIMARY KEY AUTOINCREMENT,
+       contact_id                      INTEGER NOT NULL,
+       datatype                        INTEGER NOT NULL,
+       is_my_profile           INTEGER,
+       is_primary_default              INTEGER,
+       is_default                      INTEGER,
+       data1                           INTEGER,
+       data2                           TEXT,
+       data3                           TEXT,
+       data4                           TEXT,
+       data5                           TEXT,
+       data6                           TEXT,
+       data7                           TEXT,
+       data8                           TEXT,
+       data9                           TEXT,
+       data10                          TEXT,
+       data11                          TEXT,
+       data12                          TEXT
 );
+
+CREATE TRIGGER trg_data_image_del AFTER DELETE ON data
+       WHEN old.datatype = 13
+               BEGIN
+                       SELECT _DATA_IMAGE_DELETE_(old.data3);
+               END;
+
+CREATE TRIGGER trg_data_company_del AFTER DELETE ON data
+       WHEN old.datatype = 6
+               BEGIN
+                       SELECT _DATA_COMPANY_DELETE_(old.data8);
+               END;
+
 CREATE TRIGGER trg_data_number_del AFTER DELETE ON data
- WHEN old.datatype = 8
- BEGIN
-   DELETE FROM favorites WHERE  type = 1 AND related_id = old.id;
-   DELETE FROM speeddials WHERE  number_id = old.id;
- END;
-CREATE INDEX data_contact_idx ON data(contact_id);
      WHEN old.datatype = 8
              BEGIN
+                       DELETE FROM speeddials WHERE  number_id = old.id;
+               END;
+
+CREATE INDEX data_contact_idx1 ON data(contact_id);
 CREATE INDEX data_contact_idx2 ON data(datatype, contact_id);
 CREATE INDEX data_idx1 ON data(data1);
 CREATE INDEX data_idx2 ON data(data2);
@@ -148,114 +226,206 @@ CREATE INDEX data_idx10 ON data(data10);
 
 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)
+       group_id                        INTEGER PRIMARY KEY AUTOINCREMENT,
+       addressbook_id                  INTEGER,
+       group_name                      TEXT,
+       extra_data                      TEXT,
+       is_read_only                    INTEGER DEFAULT 0,
+       created_ver                     INTEGER NOT NULL,
+       changed_ver                     INTEGER NOT NULL,
+       ringtone_path                   TEXT,
+       vibration                       TEXT,
+       image_thumbnail_path            TEXT,
+       message_alert           TEXT,
+       member_changed_ver              INTEGER,
+       group_prio                      REAL
 );
+
+INSERT INTO groups(addressbook_id, group_name, extra_data, is_read_only, created_ver, changed_ver, group_prio)
+       VALUES(0, 'Co-workers', 'coworkers', 0, 0, 0, 1);
+INSERT INTO groups(addressbook_id, group_name, extra_data, is_read_only, created_ver, changed_ver, group_prio)
+       VALUES(0, 'Family', 'family', 0, 0, 0, 2);
+INSERT INTO groups(addressbook_id, group_name, extra_data, is_read_only, created_ver, changed_ver, group_prio)
+       VALUES(0, 'Friends', 'friends',0, 0, 0, 3);
+
 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;
+       UPDATE contacts SET changed_ver=((SELECT ver FROM cts_version) + 1) WHERE deleted = 0 AND contact_id IN (SELECT contact_id FROM group_relations WHERE group_id=old.group_id);
+       DELETE FROM group_relations WHERE group_id = old.group_id;
+       SELECT _GROUP_DELETE_(old.image_thumbnail_path);
  END;
 
+CREATE TRIGGER trg_groups_del2 AFTER DELETE ON groups
+       WHEN old.addressbook_id IN (SELECT addressbook_id from addressbooks WHERE addressbook_id = old.addressbook_id)
+       BEGIN
+               INSERT INTO group_deleteds VALUES(old.group_id, old.addressbook_id, old.created_ver, (SELECT ver FROM cts_version) + 1);
+       END;
+
 CREATE TABLE group_deleteds
 (
-group_id INTEGER PRIMARY KEY,
-addrbook_id INTEGER,
-deleted_ver INTEGER
+       group_id                                INTEGER PRIMARY KEY,
+       addressbook_id          INTEGER NOT NULL,
+       created_ver                     INTEGER NOT NULL,
+       deleted_ver                     INTEGER NOT NULL
 );
-CREATE INDEX grp_deleteds_ver_idx ON group_deleteds(deleted_ver);
+
+CREATE INDEX group_deleteds_idx1 ON group_deleteds(deleted_ver);
 
 CREATE TABLE group_relations
 (
-group_id INTEGER NOT NULL,
-contact_id INTEGER NOT NULL,
-UNIQUE(group_id, contact_id)
+       group_id                        INTEGER NOT NULL,
+       contact_id                      INTEGER NOT NULL,
+       ver INTEGER NOT NULL,
+       deleted INTEGER DEFAULT 0,
+       UNIQUE(group_id, contact_id)
 );
-CREATE INDEX group_idx1 ON group_relations(contact_id);
+CREATE INDEX groups_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,
-number_id INTEGER UNIQUE
+       speed_number                    INTEGER PRIMARY KEY NOT NULL,
+       number_id                       INTEGER UNIQUE
 );
 
 CREATE TABLE favorites
 (
-id INTEGER PRIMARY KEY AUTOINCREMENT,
-type INTEGER NOT NULL,
-related_id INTEGER NOT NULL,
-favorite_prio REAL,
-UNIQUE(type, related_id)
+       person_id                       INTEGER PRIMARY KEY,
+       favorite_prio                   REAL
+);
+CREATE INDEX favorites_idx1 ON favorites(favorite_prio);
+CREATE INDEX favorites_idx2 ON favorites(person_id);
+
+
+CREATE TABLE sim_info
+(
+       sim_id                  INTEGER PRIMARY KEY AUTOINCREMENT,
+       unique_id               TEXT NOT NULL,          -- iccid
+       UNIQUE(unique_id)
 );
-CREATE INDEX idx1_favorites ON favorites(favorite_prio);
-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 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 person_id = new.related_id;
- END;
 
 CREATE TABLE phonelogs
 (
-id INTEGER PRIMARY KEY AUTOINCREMENT,
-number TEXT,
-normal_num TEXT,
-related_id INTEGER, --person_id
-log_type INTEGER,
-log_time INTEGER,
-data1 INTEGER, --duration, message_id
-data2 TEXT  -- short message
+       id                              INTEGER PRIMARY KEY AUTOINCREMENT,
+       number                          TEXT,
+       number_type                     INTEGER,
+       normal_num                      TEXT,
+       clean_num                               TEXT,
+       minmatch                                TEXT,
+       sim_id                  INTEGER,
+       person_id                       INTEGER, --person_id
+       log_type                        INTEGER,
+       log_time                        INTEGER,
+       data1                           INTEGER, --duration, message_id
+       data2                           TEXT  -- short message
 );
-CREATE INDEX idx1_phonelogs ON phonelogs(log_type);
-CREATE INDEX idx2_phonelogs ON phonelogs(log_time);
+
+CREATE INDEX phonelogs_idx1 ON phonelogs(log_type);
+CREATE INDEX phonelogs_idx2 ON phonelogs(log_time);
 CREATE TRIGGER trg_phonelogs_del AFTER DELETE ON phonelogs
- WHEN old.log_type = 2 OR old.log_type = 4
- BEGIN
-   DELETE FROM phonelog_accumulation WHERE log_time < (old.log_time - 3456000); -- 40 days
-   INSERT INTO phonelog_accumulation VALUES(NULL, 1, old.log_time, old.data1);
- END;
+       BEGIN
+               SELECT _PHONE_LOG_DELETE_(old.id);
+       END;
 
-CREATE TABLE phonelog_accumulation
+CREATE TABLE phonelog_stat
 (
-id INTEGER PRIMARY KEY AUTOINCREMENT,
-log_cnt INTEGER,
-log_time INTEGER,
-duration INTEGER
+       log_type                        INTEGER PRIMARY KEY,
+       log_count                       INTEGER
 );
-INSERT INTO phonelog_accumulation VALUES(1, 0, NULL, 0);
-INSERT INTO phonelog_accumulation VALUES(2, 0, NULL, 0); --total
+
+CREATE TRIGGER trg_phonelogs_insert AFTER INSERT ON phonelogs
+       BEGIN
+               INSERT OR REPLACE INTO phonelog_stat values(new.log_type, coalesce((SELECT log_count+1 FROM phonelog_stat WHERE log_type=new.log_type), 1));
+       END;
+
+CREATE TABLE contact_stat
+(
+       id                              INTEGER PRIMARY KEY AUTOINCREMENT,
+       person_id                       INTEGER,
+       usage_type                      INTEGER,
+       times_used                      INTEGER
+);
+
+CREATE TABLE activities
+(
+       id                              INTEGER PRIMARY KEY AUTOINCREMENT,
+       contact_id                      INTEGER NOT NULL,
+       source_name                     TEXT,
+       status                          TEXT,
+       timestamp                       INTEGER,
+       service_operation       TEXT,
+       uri                                     TEXT
+);
+
+CREATE TABLE activity_photos
+(
+       id                              INTEGER PRIMARY KEY AUTOINCREMENT,
+       activity_id                     INTEGER NOT NULL,
+       photo_url                       TEXT,
+       sort_index                      INTEGER
+);
+
+CREATE TRIGGER trg_activities_insert AFTER INSERT ON activities
+       BEGIN
+               UPDATE persons SET status=(SELECT status FROM activities WHERE contact_id IN (SELECT contact_id FROM contacts WHERE person_id = (select person_id FROM contacts WHERE contact_id = new.contact_id)) ORDER BY timestamp DESC LIMIT 1)  WHERE person_id = (SELECT person_id FROM contacts WHERE contact_id = new.contact_id);
+       END;
+
+CREATE TRIGGER trg_activities_delete AFTER DELETE ON activities
+       BEGIN
+               UPDATE persons SET status=(SELECT status FROM activities WHERE contact_id IN (SELECT contact_id FROM contacts WHERE person_id = (select person_id FROM contacts WHERE contact_id = old.contact_id)) ORDER BY timestamp DESC LIMIT 1)  WHERE person_id = (SELECT person_id FROM contacts WHERE contact_id = old.contact_id);
+               DELETE FROM activity_photos WHERE activity_id = old.id;
+       END;
+
+CREATE VIRTUAL TABLE search_index USING FTS4
+(
+       contact_id INTEGER NOT NULL,
+       data TEXT,
+       name TEXT,
+       number TEXT,
+       UNIQUE(contact_id)
+);
+
+CREATE TABLE name_lookup
+(
+       data_id INTEGER NOT NULL,
+       contact_id INTEGER NOT NULL,
+       name TEXT,
+       type INTEGER
+);
+CREATE INDEX name_lookup_idx1 ON name_lookup(contact_id);
+
+CREATE TABLE phone_lookup
+(
+       data_id INTEGER NOT NULL,
+       contact_id INTEGER NOT NULL,
+       number TEXT,
+       min_match TEXT
+);
+CREATE INDEX phone_lookup_idx1 ON phone_lookup(contact_id);
 
 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
+       my_profile_id                   INTEGER PRIMARY KEY AUTOINCREMENT,
+       addressbook_id                  INTEGER NOT NULL DEFAULT 0,
+       display_name                    TEXT,
+       reverse_display_name            TEXT,
+       created_ver                     INTEGER NOT NULL,
+       changed_ver                     INTEGER NOT NULL,
+       changed_time                    INTEGER NOT NULL,
+       uid                             TEXT,
+       image_thumbnail_path            TEXT,
+       deleted                         INTEGER DEFAULT 0,
+       UNIQUE(addressbook_id)
+);
+
+CREATE TRIGGER trg_my_profiles_del AFTER DELETE ON my_profiles
+       BEGIN
+               DELETE FROM data WHERE contact_id = old.my_profile_id AND is_my_profile = 1;
+       END;
+
+CREATE TRIGGER trg_my_profile_update AFTER UPDATE ON my_profiles
+       WHEN new.deleted = 1
+       BEGIN
+               DELETE FROM data WHERE contact_id = old.my_profile_id AND is_my_profile = 1;
+       END;
+
diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..3f2aeda
--- /dev/null
@@ -0,0 +1,206 @@
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/server)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/native)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common/ipc)
+LINK_DIRECTORIES(${CMAKE_BINARY_DIR})
+LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/server)
+
+SET(DAEMON contacts-service-ipcd)
+
+SET(SRCS
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_marshal.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_addressbook.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_contact.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_my_profile.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_group.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_person.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_result.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_simple_contact.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_result.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_updated_info.c
+
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_activity.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_activity_photo.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_address.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_company.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_email.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_event.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_grouprelation.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_messenger.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_name.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_nickname.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_note.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_number.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_relationship.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_url.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_extension.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_profile.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_image.c
+
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_filter.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_db_notification.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_inotify.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_list.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_localize_utils.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_mutex.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_query.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_addressbook.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_contact.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_my_profile.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_group.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_person.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_result.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_updated_info.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_socket.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_vcard.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_view.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_activity.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_access_control.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_init.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_activity.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_activity_photo.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_activity_photo_helper.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_address_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_address.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_addressbook.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_addressbook_helper.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_company_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_company.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_contact_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_contact.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_my_profile.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_email_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_email.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_event_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_event.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_extension_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_extension.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_group.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_group_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_grouprelation.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_image_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_image.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_messenger_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_messenger.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_name_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_name.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_nickname_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_nickname.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_note_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_note.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_number_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_number.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_person_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_person.c
+
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_profile_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_profile.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_relationship_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_relationship.c
+
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_simple_contact.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_url_helper.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_url.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_query.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_group.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_person.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_service.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_sqlite.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_utils.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_number_utils.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_notification.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_setting.c
+
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_localize_jp.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_localize_kor.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_localize_ch.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_localize.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_normalize.c
+
+       ctsvc_ipc_server.c
+       ctsvc_ipc_server2.c
+       ctsvc_server_sqlite.c
+       ctsvc_server_utils.c
+       ctsvc_server_change_subject.c
+       ctsvc_server_socket.c
+       ctsvc_schema_recovery.c
+       ctsvc_server_update.c
+       ctsvc_server_bg.c
+       ctsvc_server.c
+)
+
+IF( ENABLE_SIM_FEATURE )
+SET(SRCS ${SRCS}
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_sdn.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_sdn.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_sdn.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_speeddial.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_speeddial.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_speeddial.c
+       ctsvc_server_sim.c
+)
+ENDIF( ENABLE_SIM_FEATURE )
+
+IF( ENABLE_LOG_FEATURE )
+SET(SRCS ${SRCS}
+       ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_phonelog.c
+       ${CMAKE_SOURCE_DIR}/common/ctsvc_record_phonelog.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_phonelog.c
+       ${CMAKE_SOURCE_DIR}/native/ctsvc_phonelog.c
+)
+ENDIF( ENABLE_LOG_FEATURE )
+
+
+INCLUDE(FindPkgConfig)
+IF (CTS_MOBILE)
+       ADD_DEFINITIONS("-DCTS_MOBILE")
+       pkg_check_modules(ctsvc_server_pkgs REQUIRED    glib-2.0 pims-ipc gobject-2.0 tapi dlog capi-media-image-util libexif libsmack icu-i18n capi-system-info accounts-svc)
+ELSE (CTS_MOBILE)
+       pkg_check_modules(ctsvc_server_pkgs REQUIRED    glib-2.0 pims-ipc gobject-2.0 tapi dlog capi-media-image-util libexif libsmack icu-i18n capi-system-info)
+ENDIF (CTS_MOBILE)
+
+FOREACH(flag ${ctsvc_server_pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -Wall -g -fPIC -std=c++0x -fPIE")
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie")
+SET(ctsvc_server_pkgs_LDFLAGS "${pkgs_LDFLAGS} ${ctsvc_server_pkgs_LDFLAGS}")
+
+ADD_DEFINITIONS("-D_CONTACTS_IPC_SERVER")
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+
+#cmake_policy(SET CMP0002 OLD)
+ADD_EXECUTABLE(${DAEMON} ${SRCS})
+SET_TARGET_PROPERTIES(${DAEMON} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS})
+TARGET_LINK_LIBRARIES(${DAEMON} ${ctsvc_server_pkgs_LDFLAGS})
+
+INSTALL(TARGETS ${DAEMON} DESTINATION bin)
diff --git a/server/ctsvc_ipc_server.c b/server/ctsvc_ipc_server.c
new file mode 100644 (file)
index 0000000..a91237a
--- /dev/null
@@ -0,0 +1,1918 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <security-server.h>
+
+#include "contacts.h"
+
+#include "ctsvc_service.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_access_control.h"
+
+#include "ctsvc_ipc_marshal.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_ipc_server.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_server_utils.h"
+
+void ctsvc_ipc_server_connect(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+       size_t cookie_size = 0;
+       char *smack_label = NULL;
+       char *cookie = NULL;
+       char *buf = NULL;
+       gsize buf_len;
+
+       if (indata) {
+               // Access control : get cookie from indata
+               ret = ctsvc_ipc_unmarshal_unsigned_int(indata, &cookie_size);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_marshal_int fail");
+                       goto ERROR_RETURN;
+               }
+
+               if (cookie_size <= 0) {
+                       CTS_ERR("cookie size is %d", cookie_size);
+                       ret = CONTACTS_ERROR_IPC;
+                       goto ERROR_RETURN;
+               }
+
+               ret = ctsvc_ipc_unmarshal_string(indata, &buf);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_string fail");
+                       goto ERROR_RETURN;
+               }
+               cookie = (char*)g_base64_decode((const gchar*)buf, &buf_len);
+
+               smack_label = security_server_get_smacklabel_cookie(cookie);
+               if (NULL == smack_label) {
+                       CTS_ERR("security_server_get_smacklabel_cookie fail");
+                       ret = CONTACTS_ERROR_SYSTEM;
+                       goto ERROR_RETURN;
+               }
+       }
+       else {
+               CTS_ERR("There is no indata fail");
+               ret = CONTACTS_ERROR_SYSTEM;
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_connect();
+
+       if (CONTACTS_ERROR_NONE == ret)
+               ctsvc_set_client_access_info(smack_label, cookie);
+
+ERROR_RETURN:
+       if (outdata) {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata) {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else {
+               CTS_ERR("outdata is NULL");
+       }
+DATA_FREE:
+       free(smack_label);
+       free(cookie);
+       free(buf);
+}
+
+void ctsvc_ipc_server_disconnect(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+
+       ret = contacts_disconnect();
+
+       // related data will be freed in __ctsvc_client_disconnected_cb
+//     if (ret == CONTACTS_ERROR_NONE)
+//             ctsvc_unset_client_access_info();
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       return;
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+       return;
+}
+
+void ctsvc_ipc_server_check_permission(pims_ipc_h ipc, pims_ipc_data_h indata,
+               pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int permission;
+       bool result;
+
+       if (NULL == indata) {
+               ret = CONTACTS_ERROR_INVALID_PARAMETER;
+               CTS_ERR("check permission fail.");
+               goto ERROR_RETURN;
+       }
+
+       ret = ctsvc_ipc_unmarshal_int(indata, &permission);
+       if (ret != CONTACTS_ERROR_NONE) {
+               CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+               goto ERROR_RETURN;
+       }
+
+       result = ctsvc_have_permission(permission);
+
+ERROR_RETURN:
+       *outdata = pims_ipc_data_create(0);
+       if (!*outdata) {
+               CTS_ERR("pims_ipc_data_create fail");
+               return;
+       }
+
+       if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0) {
+               pims_ipc_data_destroy(*outdata);
+               *outdata = NULL;
+               CTS_ERR("pims_ipc_data_put fail (return value)");
+               return;
+       }
+
+       if (ret == CONTACTS_ERROR_NONE) {
+               if (pims_ipc_data_put(*outdata, (void*)&result, sizeof(bool)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail (id)");
+                       return;
+               }
+       }
+}
+
+void ctsvc_ipc_server_db_insert_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int id = 0;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_record(indata,&record);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_record fail");
+                       record = NULL;
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_server_db_insert_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_db_insert_record(record, &id);
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                               goto ERROR_RETURN;
+                       }
+                       if (ctsvc_ipc_marshal_int(id,*outdata) != CONTACTS_ERROR_NONE)
+                       {
+                               pims_ipc_data_destroy(*outdata);
+                               CTS_ERR("ctsvc_ipc_marshal fail");
+                               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                               goto ERROR_RETURN;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+       goto DATA_FREE;
+
+ERROR_RETURN:
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+
+DATA_FREE:
+       if (record)
+       {
+               contacts_record_destroy(record,true);
+       }
+       return;
+}
+
+void ctsvc_ipc_server_db_get_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       char* view_uri = NULL;
+       int id = 0;
+       contacts_record_h record = NULL;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_string(indata,&view_uri);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_string fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata,&id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_server_db_insert_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_db_get_record(view_uri,id,&record);
+
+ERROR_RETURN:
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+
+               if ( CONTACTS_ERROR_NO_DATA == ret )
+               {
+                       CTS_DBG("no data");
+               }
+               else if( CONTACTS_ERROR_NONE == ret )
+               {
+                       if( ctsvc_ipc_marshal_record(record, *outdata) != CONTACTS_ERROR_NONE )
+                       {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_record fail");
+                               goto DATA_FREE;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+DATA_FREE:
+       if (record)
+       {
+               contacts_record_destroy(record,true);
+       }
+       CONTACTS_FREE(view_uri);
+       return;
+}
+
+void ctsvc_ipc_server_db_update_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_record(indata,&record);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_record fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_server_db_insert_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_db_update_record(record);
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                               goto ERROR_RETURN;
+                       }
+               }
+       }
+
+       goto DATA_FREE;
+
+ERROR_RETURN:
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+DATA_FREE:
+       if (record)
+       {
+               contacts_record_destroy(record,true);
+       }
+       return;
+}
+
+void ctsvc_ipc_server_db_delete_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       char* view_uri = NULL;
+       int id = 0;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_string(indata,&view_uri);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_record fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata,&id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_server_db_insert_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_db_delete_record(view_uri,id);
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                               goto ERROR_RETURN;
+                       }
+               }
+       }
+
+       goto DATA_FREE;
+
+ERROR_RETURN:
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+
+DATA_FREE:
+
+       CONTACTS_FREE(view_uri);
+       return;
+}
+
+void ctsvc_ipc_server_db_replace_record(pims_ipc_h ipc, pims_ipc_data_h indata,
+               pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_record_h record = NULL;
+       int id = 0;
+
+       if (indata) {
+               ret = ctsvc_ipc_unmarshal_record(indata, &record);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_record fail");
+                       record = NULL;
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata, &id);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else {
+               CTS_ERR("ctsvc_ipc_server_db_replace_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_db_replace_record(record, id);
+
+       if (outdata) {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata) {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                               goto ERROR_RETURN;
+                       }
+               }
+       }
+       else {
+               CTS_ERR("outdata is NULL");
+       }
+       goto DATA_FREE;
+
+ERROR_RETURN:
+       if (outdata) {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata) {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else {
+               CTS_ERR("outdata is NULL");
+       }
+
+DATA_FREE:
+       if (record)
+               contacts_record_destroy(record, true);
+
+       return;
+}
+
+void ctsvc_ipc_server_db_get_all_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       char* view_uri = NULL;
+       int offset = 0;
+       int limit = 0;
+       contacts_list_h list = NULL;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_string(indata,&view_uri);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_record fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata,&offset);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata,&limit);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_server_db_insert_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_db_get_all_records(view_uri,offset,limit,&list);
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+
+               if ( CONTACTS_ERROR_NO_DATA == ret )
+               {
+                       CTS_DBG("no data");
+               }
+               else if( CONTACTS_ERROR_NONE == ret )
+               {
+                       ret = ctsvc_ipc_marshal_list(list,*outdata);
+
+                       if (ret != CONTACTS_ERROR_NONE)
+                       {
+                               CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                               goto DATA_FREE;
+                       }
+               }
+
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+
+       goto DATA_FREE;
+
+ERROR_RETURN:
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+DATA_FREE:
+
+       if (list)
+       {
+               contacts_list_destroy(list,true);
+       }
+       CONTACTS_FREE(view_uri);
+       return;
+}
+
+void ctsvc_ipc_server_db_get_records_with_query(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_query_h query = NULL;
+       int offset = 0;
+       int limit = 0;
+       contacts_list_h list = NULL;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_query(indata,&query);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_record fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata,&offset);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata,&limit);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_server_db_insert_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_db_get_records_with_query(query,offset,limit,&list);
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+
+               if ( CONTACTS_ERROR_NO_DATA == ret )
+               {
+                       CTS_DBG("no data");
+               }
+               else if( CONTACTS_ERROR_NONE == ret )
+               {
+                       ret = ctsvc_ipc_marshal_list(list,*outdata);
+
+                       if (ret != CONTACTS_ERROR_NONE)
+                       {
+                               CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                               goto DATA_FREE;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+       goto DATA_FREE;
+
+ERROR_RETURN:
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+DATA_FREE:
+
+       if (list)
+       {
+               contacts_list_destroy(list,true);
+       }
+       if (query)
+       {
+               contacts_query_destroy(query);
+       }
+       return;
+}
+
+
+void ctsvc_ipc_server_db_get_count(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       char* view_uri = NULL;
+       int count = 0;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_string(indata,&view_uri);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_record fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_server_db_insert_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_db_get_count(view_uri,&count);
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+
+               if ( CONTACTS_ERROR_NO_DATA == ret )
+               {
+                       CTS_DBG("no data");
+               }
+               else if( CONTACTS_ERROR_NONE == ret )
+               {
+                       ret = ctsvc_ipc_marshal_int(count,*outdata);
+
+                       if (ret != CONTACTS_ERROR_NONE)
+                       {
+                               CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                               goto DATA_FREE;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+       goto DATA_FREE;
+
+ERROR_RETURN:
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+DATA_FREE:
+       CONTACTS_FREE(view_uri);
+       return;
+}
+
+void ctsvc_ipc_server_db_get_count_with_query(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_query_h query = NULL;
+       int count = 0;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_query(indata,&query);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_record fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_server_db_insert_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_db_get_count_with_query(query,&count);
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+
+               if ( CONTACTS_ERROR_NO_DATA == ret )
+               {
+                       CTS_DBG("no data");
+               }
+               else if( CONTACTS_ERROR_NONE == ret )
+               {
+                       ret = ctsvc_ipc_marshal_int(count,*outdata);
+
+                       if (ret != CONTACTS_ERROR_NONE)
+                       {
+                               CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                               goto DATA_FREE;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+       goto DATA_FREE;
+
+ERROR_RETURN:
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+DATA_FREE:
+       if (query)
+       {
+               contacts_query_destroy(query);
+       }
+       return;
+}
+
+void ctsvc_ipc_server_db_insert_records(pims_ipc_h ipc, pims_ipc_data_h indata,
+               pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_list_h list = NULL;
+       unsigned int id_count = 0;
+       int *ids = NULL;
+       int i=0;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_list(indata,&list);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_list fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_server_db_insert_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = ctsvc_db_insert_records(list, &ids, &id_count);
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+
+               if(ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                               goto ERROR_RETURN;
+                       }
+                       // marshal : id_count+property_id+[ids]*id_count
+                       // id_count
+                       if (pims_ipc_data_put(*outdata,(void*)&id_count,sizeof(int)) != 0)
+                       {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("pims_ipc_data_put fail");
+                               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                               goto ERROR_RETURN;
+                       }
+
+                       for(i=0;i<id_count;i++)
+                       {
+                               // marshal ids
+                               if (pims_ipc_data_put(*outdata,(void*)&ids[i],sizeof(int)) != 0)
+                               {
+                                       pims_ipc_data_destroy(*outdata);
+                                       *outdata = NULL;
+                                       CTS_ERR("pims_ipc_data_put fail");
+                                       ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                                       goto ERROR_RETURN;
+                               }
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+       goto DATA_FREE;
+
+ERROR_RETURN:
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+DATA_FREE:
+       if (list)
+       {
+               contacts_list_destroy(list,true);
+       }
+       CONTACTS_FREE(ids);
+       return;
+}
+
+void ctsvc_ipc_server_db_update_records(pims_ipc_h ipc, pims_ipc_data_h indata,
+               pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_list_h list = NULL;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_list(indata,&list);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_list fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_server_db_insert_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_db_update_records(list);
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                               goto ERROR_RETURN;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+       goto DATA_FREE;
+
+ERROR_RETURN:
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+DATA_FREE:
+       if (list)
+       {
+               contacts_list_destroy(list,true);
+       }
+       return;
+}
+
+void ctsvc_ipc_server_db_delete_records(pims_ipc_h ipc, pims_ipc_data_h indata,
+               pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int count = 0;
+       int *ids = NULL;
+       char *uri = NULL;
+       int i = 0;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_string(indata,&uri);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_string fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata,&count);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               if (count <=0)
+               {
+                       ret = CONTACTS_ERROR_INVALID_PARAMETER;
+                       goto ERROR_RETURN;
+               }
+               ids = (int*)malloc(sizeof(int)*count);
+               for(i=0;i<count;i++)
+               {
+                       ret = ctsvc_ipc_unmarshal_int(indata,&ids[i]);
+                       if (ret != CONTACTS_ERROR_NONE)
+                       {
+                               CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                               goto ERROR_RETURN;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_server_db_insert_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_db_delete_records(uri, ids, count);
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                               goto ERROR_RETURN;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+
+       goto DATA_FREE;
+
+ERROR_RETURN:
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+DATA_FREE:
+       CONTACTS_FREE(uri);
+       CONTACTS_FREE(ids);
+       return;
+}
+
+void ctsvc_ipc_server_db_replace_records(pims_ipc_h ipc, pims_ipc_data_h indata,
+               pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_list_h list = NULL;
+       int count = 0;
+       int *ids = NULL;
+       int i=0;
+
+       if (indata) {
+               ret = ctsvc_ipc_unmarshal_list(indata, &list);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_list fail");
+                       goto ERROR_RETURN;
+               }
+
+               ret = ctsvc_ipc_unmarshal_int(indata, &count);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+
+               if (count <=0) {
+                       ret = CONTACTS_ERROR_INVALID_PARAMETER;
+                       goto ERROR_RETURN;
+               }
+
+               ids = (int*)malloc(sizeof(int)*count);
+               for(i=0;i<count;i++) {
+                       ret = ctsvc_ipc_unmarshal_int(indata, &ids[i]);
+                       if (ret != CONTACTS_ERROR_NONE) {
+                               CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                               goto ERROR_RETURN;
+                       }
+               }
+       }
+       else {
+               CTS_ERR("ctsvc_ipc_server_db_repalce_records fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = ctsvc_db_replace_records(list, ids, count);
+
+       if (outdata) {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata) {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                               goto ERROR_RETURN;
+                       }
+               }
+       }
+       else {
+               CTS_ERR("outdata is NULL");
+       }
+       goto DATA_FREE;
+
+ERROR_RETURN:
+       if (outdata) {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata) {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else {
+               CTS_ERR("outdata is NULL");
+       }
+DATA_FREE:
+       if (list) {
+               contacts_list_destroy(list,true);
+       }
+       CONTACTS_FREE(ids);
+       return;
+}
+
+void ctsvc_ipc_server_db_get_changes_by_version(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       char* view_uri = NULL;
+       int address_book_id = 0;
+       int contacts_db_version = 0;
+       contacts_list_h record_list = NULL;
+       int current_contacts_db_version = 0;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_string(indata,&view_uri);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_string fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata, &address_book_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata,&contacts_db_version);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_server_db_insert_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_db_get_changes_by_version(view_uri, address_book_id,contacts_db_version,&record_list,&current_contacts_db_version);
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+
+               if ( CONTACTS_ERROR_NO_DATA == ret )
+               {
+                       CTS_DBG("no data");
+               }
+               else if( CONTACTS_ERROR_NONE == ret )
+               {
+                       ret = ctsvc_ipc_marshal_list(record_list,*outdata);
+                       if (ret != CONTACTS_ERROR_NONE)
+                       {
+                               CTS_ERR("ctsvc_ipc_marshal_list fail");
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                               goto ERROR_RETURN;
+                       }
+                       ret = ctsvc_ipc_marshal_int(current_contacts_db_version,*outdata);
+                       if (ret != CONTACTS_ERROR_NONE)
+                       {
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               ret = CONTACTS_ERROR_OUT_OF_MEMORY;
+                               goto ERROR_RETURN;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+       goto DATA_FREE;
+
+ERROR_RETURN:
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+DATA_FREE:
+       if (record_list)
+       {
+               contacts_list_destroy(record_list,true);
+       }
+       CONTACTS_FREE(view_uri);
+       return;
+}
+
+void ctsvc_ipc_server_db_get_current_version(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int contacts_db_version = 0;
+
+       ret = contacts_db_get_current_version(&contacts_db_version);
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       return;
+               }
+
+               if ( CONTACTS_ERROR_NO_DATA == ret )
+               {
+                       CTS_DBG("no data");
+               }
+               else if( CONTACTS_ERROR_NONE == ret )
+               {
+                       ret = ctsvc_ipc_marshal_int(contacts_db_version,*outdata);
+                       if (ret != CONTACTS_ERROR_NONE)
+                       {
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               return;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+       return;
+}
+
+void ctsvc_ipc_server_db_search_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       char* view_uri = NULL;
+       char* keyword = NULL;
+       int offset = 0;
+       int limit = 0;
+       contacts_list_h list = NULL;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_string(indata,&view_uri);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_record fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_string(indata,&keyword);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_record fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata,&offset);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata,&limit);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_server_db_insert_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_db_search_records(view_uri, keyword, offset,limit,&list);
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+
+               if ( CONTACTS_ERROR_NO_DATA == ret )
+               {
+                       CTS_DBG("no data");
+               }
+               else if( CONTACTS_ERROR_NONE == ret )
+               {
+                       ret = ctsvc_ipc_marshal_list(list,*outdata);
+
+                       if (ret != CONTACTS_ERROR_NONE)
+                       {
+                               CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                               goto DATA_FREE;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+       goto DATA_FREE;
+
+ERROR_RETURN:
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+DATA_FREE:
+
+       if (list)
+       {
+               contacts_list_destroy(list,true);
+       }
+       CONTACTS_FREE(view_uri);
+       CONTACTS_FREE(keyword);
+       return;
+}
+
+void ctsvc_ipc_server_db_search_records_with_range(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       char* view_uri = NULL;
+       char* keyword = NULL;
+       int offset = 0;
+       int limit = 0;
+       int range = 0;
+       contacts_list_h list = NULL;
+
+       if (indata) {
+               ret = ctsvc_ipc_unmarshal_string(indata,&view_uri);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_record fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_string(indata,&keyword);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_record fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata,&offset);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata,&limit);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata,&range);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else {
+               CTS_ERR("ctsvc_ipc_server_db_insert_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_db_search_records_with_range(view_uri, keyword, offset,limit,range, &list);
+
+       if (outdata) {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata) {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+
+               if (CONTACTS_ERROR_NO_DATA == ret) {
+                       CTS_DBG("no data");
+               }
+               else if(CONTACTS_ERROR_NONE == ret) {
+                       ret = ctsvc_ipc_marshal_list(list,*outdata);
+
+                       if (ret != CONTACTS_ERROR_NONE) {
+                               CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                               goto DATA_FREE;
+                       }
+               }
+       }
+       else {
+               CTS_ERR("outdata is NULL");
+       }
+       goto DATA_FREE;
+
+ERROR_RETURN:
+       if (outdata) {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata) {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else {
+               CTS_ERR("outdata is NULL");
+       }
+
+DATA_FREE:
+
+       if (list)
+               contacts_list_destroy(list,true);
+       free(view_uri);
+       free(keyword);
+       return;
+}
+
+void ctsvc_ipc_server_db_search_records_with_query(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_query_h query = NULL;
+       char* keyword = NULL;
+       int offset = 0;
+       int limit = 0;
+       contacts_list_h list = NULL;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_query(indata,&query);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_record fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_string(indata,&keyword);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_record fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata,&offset);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata,&limit);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_server_db_insert_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_db_search_records_with_query(query, keyword, offset,limit,&list);
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+
+               if ( CONTACTS_ERROR_NO_DATA == ret )
+               {
+                       CTS_DBG("no data");
+               }
+               else if( CONTACTS_ERROR_NONE == ret )
+               {
+                       ret = ctsvc_ipc_marshal_list(list,*outdata);
+
+                       if (ret != CONTACTS_ERROR_NONE)
+                       {
+                               CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                               goto DATA_FREE;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+       goto DATA_FREE;
+
+ERROR_RETURN:
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+DATA_FREE:
+
+       if (list)
+       {
+               contacts_list_destroy(list,true);
+       }
+       if (query)
+       {
+               contacts_query_destroy(query);
+       }
+       CONTACTS_FREE(keyword);
+
+       return;
+}
+
+void ctsvc_ipc_server_db_get_status(pims_ipc_h ipc, pims_ipc_data_h indata,
+               pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_db_status_e status;
+
+       RETM_IF(outdata == NULL, "outdata is NULL");
+
+       *outdata = pims_ipc_data_create(0);
+       if (!*outdata) {
+               CTS_ERR("pims_ipc_data_create fail");
+               return;
+       }
+
+       ret = contacts_db_get_status(&status);
+       if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0) {
+               pims_ipc_data_destroy(*outdata);
+               *outdata = NULL;
+               CTS_ERR("pims_ipc_data_put fail (return value)");
+               return;
+       }
+
+       if (pims_ipc_data_put(*outdata, (void*)&status, sizeof(int)) != 0) {
+               pims_ipc_data_destroy(*outdata);
+               *outdata = NULL;
+               CTS_ERR("pims_ipc_data_put fail (id)");
+               return;
+       }
+
+       return;
+}
+
diff --git a/server/ctsvc_ipc_server.h b/server/ctsvc_ipc_server.h
new file mode 100644 (file)
index 0000000..febdcb3
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_IPC_SERVER_H__
+#define __CTSVC_IPC_SERVER_H__
+
+#include <pims-ipc-data.h>
+
+// contacts_service.h
+void ctsvc_ipc_server_connect(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_server_disconnect(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_server_check_permission(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+
+// contacts_db_init.h
+void ctsvc_ipc_server_db_insert_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_server_db_get_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_server_db_update_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_server_db_delete_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_server_db_replace_record(pims_ipc_h ipc, pims_ipc_data_h indata,pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_server_db_get_all_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_server_db_get_records_with_query(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+
+void ctsvc_ipc_server_db_get_count(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_server_db_get_count_with_query(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+
+void ctsvc_ipc_server_db_insert_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_server_db_update_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_server_db_delete_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_server_db_replace_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+
+void ctsvc_ipc_server_db_get_changes_by_version(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_server_db_get_current_version(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+
+void ctsvc_ipc_server_db_search_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_server_db_search_records_with_range(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_server_db_search_records_with_query(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+
+void ctsvc_ipc_server_db_get_status(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+
+#endif /*__CTSVC_IPC_SERVER_H__*/
diff --git a/server/ctsvc_ipc_server2.c b/server/ctsvc_ipc_server2.c
new file mode 100644 (file)
index 0000000..bde442a
--- /dev/null
@@ -0,0 +1,1007 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 "contacts.h"
+#ifdef ENABLE_LOG_FEATURE
+#include "contacts_phone_log_internal.h"
+#endif //ENABLE_LOG_FEATURE
+
+#include "ctsvc_service.h"
+#include "ctsvc_db_init.h"
+
+#include "ctsvc_ipc_marshal.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_ipc_server.h"
+#include "ctsvc_utils.h"
+
+
+void ctsvc_ipc_activity_delete_by_contact_id(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int contact_id = 0;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_int(indata, &contact_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_server_db_insert_record fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_activity_delete_by_contact_id(contact_id);
+
+
+ERROR_RETURN:
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       return;
+               }
+
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               return;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+
+       return;
+}
+
+void ctsvc_ipc_activity_delete_by_account_id(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int account_id = 0;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_int(indata, &account_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_activity_delete_by_account_id fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_activity_delete_by_account_id(account_id);
+
+ERROR_RETURN:
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       return;
+               }
+
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               return;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+
+       return;
+}
+
+void ctsvc_ipc_group_add_contact(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int group_id = 0;
+       int contact_id = 0;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_int(indata, &group_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata, &contact_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_group_add_contact fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_group_add_contact(group_id, contact_id);
+
+ERROR_RETURN:
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       return;
+               }
+
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               return;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+
+       return;
+}
+
+void ctsvc_ipc_group_remove_contact(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int group_id = 0;
+       int contact_id = 0;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_int(indata, &group_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata, &contact_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_group_remove_contact fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_group_remove_contact(group_id, contact_id);
+
+ERROR_RETURN:
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       return;
+               }
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               return;
+                       }
+               }
+
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+
+       return;
+}
+
+void ctsvc_ipc_group_set_group_order(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int group_id = 0;
+       int previous_group_id;
+       int next_group_id;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_int(indata, &group_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata, &previous_group_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata, &next_group_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_group_link_group fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_group_set_group_order(group_id, previous_group_id, next_group_id );
+
+ERROR_RETURN:
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       return;
+               }
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               return;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+
+       return;
+}
+
+void ctsvc_ipc_person_link_person(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int base_person_id = 0;
+       int person_id = 0;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_int(indata, &base_person_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata, &person_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_person_link_person fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_person_link_person(base_person_id, person_id);
+
+ERROR_RETURN:
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       return;
+               }
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               return;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+
+       return;
+}
+void ctsvc_ipc_person_unlink_contact(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int person_id = 0;
+       int contact_id = 0;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_int(indata, &person_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata, &contact_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_person_link_person fail");
+               goto ERROR_RETURN;
+       }
+
+       int unlinked_person_id;
+       ret = contacts_person_unlink_contact(person_id, contact_id, &unlinked_person_id);
+
+ERROR_RETURN:
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       return;
+               }
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               return;
+                       }
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&unlinked_person_id, sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+               }
+
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+
+       return;
+}
+void ctsvc_ipc_person_reset_usage(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int person_id = 0;
+       contacts_usage_type_e type;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_int(indata, &person_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               int temp = 0;
+               ret = ctsvc_ipc_unmarshal_int(indata, &temp);
+               type = (int)temp;
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_person_link_person fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_person_reset_usage(person_id, type);
+
+ERROR_RETURN:
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       return;
+               }
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               return;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+
+       return;
+}
+void ctsvc_ipc_person_set_favorite_order(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int person_id = 0;
+       int previous_person_id;
+       int next_person_id;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_int(indata, &person_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata, &previous_person_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata, &next_person_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_person_link_person fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_person_set_favorite_order(person_id, previous_person_id, next_person_id );
+
+ERROR_RETURN:
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       return;
+               }
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               return;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+
+       return;
+}
+
+void ctsvc_ipc_person_set_default_property(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int person_id = 0;
+       int id;
+       contacts_person_property_e property;
+
+       if (indata)
+       {
+               ret = ctsvc_ipc_unmarshal_int(indata, &person_id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_unsigned_int(indata, &property);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_int(indata, &id);
+               if (ret != CONTACTS_ERROR_NONE)
+               {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+       {
+               CTS_ERR("ctsvc_ipc_person_set_default_property fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_person_set_default_property(property, person_id, id );
+
+ERROR_RETURN:
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       return;
+               }
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               return;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+
+       return;
+}
+
+void ctsvc_ipc_person_get_default_property(pims_ipc_h ipc, pims_ipc_data_h indata,
+               pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int person_id = 0;
+       int id;
+       contacts_person_property_e op;
+
+       if (indata) {
+               ret = ctsvc_ipc_unmarshal_int(indata, &person_id);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+               ret = ctsvc_ipc_unmarshal_unsigned_int(indata, &op);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else {
+               CTS_ERR("ctsvc_ipc_person_get_default_property fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_person_get_default_property(op, person_id, &id );
+
+ERROR_RETURN:
+
+       if (outdata) {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata) {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail (return value)");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&id, sizeof(int)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail (id)");
+                       return;
+               }
+       }
+       else {
+               CTS_ERR("outdata is NULL");
+       }
+
+       return;
+}
+
+#ifdef ENABLE_LOG_FEATURE
+void ctsvc_ipc_phone_log_reset_statistics(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = contacts_phone_log_reset_statistics();
+
+       if (outdata)
+       {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata)
+               {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0)
+               {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       return;
+               }
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               return;
+                       }
+               }
+       }
+       else
+       {
+               CTS_ERR("outdata is NULL");
+       }
+
+       return;
+}
+
+void ctsvc_ipc_phone_log_delete(pims_ipc_h ipc, pims_ipc_data_h indata,
+               pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret= CONTACTS_ERROR_NONE;
+       int extra_data1;
+       char *number = NULL;
+       contacts_phone_log_delete_e op;
+
+       if (indata) {
+               ret = ctsvc_ipc_unmarshal_int(indata, (int*)&op);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+
+               switch(op){
+               case CONTACTS_PHONE_LOG_DELETE_BY_ADDRESS:
+                       ret = ctsvc_ipc_unmarshal_string(indata, &number);
+                       if (ret != CONTACTS_ERROR_NONE) {
+                               CTS_ERR("ctsvc_ipc_unmarshal_string fail");
+                               goto ERROR_RETURN;
+                       }
+                       ret = contacts_phone_log_delete(op, number);
+                       break;
+               case CONTACTS_PHONE_LOG_DELETE_BY_MESSAGE_EXTRA_DATA1:
+               case CONTACTS_PHONE_LOG_DELETE_BY_EMAIL_EXTRA_DATA1:
+                       ret = ctsvc_ipc_unmarshal_int(indata, &extra_data1);
+                       if (ret != CONTACTS_ERROR_NONE) {
+                               CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                               goto ERROR_RETURN;
+                       }
+                       ret = contacts_phone_log_delete(op, extra_data1);
+                       break;
+               default:
+                       CTS_ERR("Invalid parameter : the operation is not proper (op : %d)", op);
+                       ret = CONTACTS_ERROR_INVALID_PARAMETER;
+                       break;
+               }
+       }
+
+ERROR_RETURN:
+       if (outdata) {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata) {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       goto DATA_FREE;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       goto DATA_FREE;
+               }
+               if (ret == CONTACTS_ERROR_NONE) {
+                       int transaction_ver = ctsvc_get_transaction_ver();
+                       if (ctsvc_ipc_marshal_int(transaction_ver, *outdata) != CONTACTS_ERROR_NONE) {
+                               pims_ipc_data_destroy(*outdata);
+                               *outdata = NULL;
+                               CTS_ERR("ctsvc_ipc_marshal_int fail");
+                               goto DATA_FREE;
+                       }
+               }
+       }
+DATA_FREE:
+       free(number);
+
+       return;
+}
+#endif // ENABLE_LOG_FEATURE
+
+void ctsvc_ipc_setting_get_name_display_order(pims_ipc_h ipc, pims_ipc_data_h indata,
+               pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_name_display_order_e order;
+
+       ret = contacts_setting_get_name_display_order(&order);
+
+       if (outdata) {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata) {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail (return value)");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&order, sizeof(int)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail (id)");
+                       return;
+               }
+       }
+       else {
+               CTS_ERR("outdata is NULL");
+       }
+
+       return;
+}
+
+void ctsvc_ipc_setting_get_name_sorting_order(pims_ipc_h ipc, pims_ipc_data_h indata,
+               pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       contacts_name_sorting_order_e order;
+
+       ret = contacts_setting_get_name_sorting_order(&order);
+
+       if (outdata) {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata) {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail (return value)");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&order, sizeof(int)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail (id)");
+                       return;
+               }
+       }
+       else {
+               CTS_ERR("outdata is NULL");
+       }
+
+       return;
+}
+
+void ctsvc_ipc_setting_set_name_display_order(pims_ipc_h ipc,
+                       pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int order;
+
+       if (indata) {
+               ret = ctsvc_ipc_unmarshal_int(indata, &order);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else {
+               CTS_ERR("ctsvc_ipc_person_set_default_property fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_setting_set_name_display_order((contacts_name_display_order_e)order);
+
+ERROR_RETURN:
+       if (outdata) {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata) {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       return;
+               }
+       }
+       else {
+               CTS_ERR("outdata is NULL");
+       }
+
+       return;
+}
+
+void ctsvc_ipc_setting_set_name_sorting_order(pims_ipc_h ipc,
+                       pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+       int ret = CONTACTS_ERROR_NONE;
+       int order;
+
+       if (indata) {
+               ret = ctsvc_ipc_unmarshal_int(indata, &order);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_ipc_unmarshal_int fail");
+                       goto ERROR_RETURN;
+               }
+       }
+       else {
+               CTS_ERR("ctsvc_ipc_person_set_default_property fail");
+               goto ERROR_RETURN;
+       }
+
+       ret = contacts_setting_set_name_sorting_order((contacts_name_sorting_order_e)order);
+
+ERROR_RETURN:
+       if (outdata) {
+               *outdata = pims_ipc_data_create(0);
+               if (!*outdata) {
+                       CTS_ERR("pims_ipc_data_create fail");
+                       return;
+               }
+               if (pims_ipc_data_put(*outdata, (void*)&ret, sizeof(int)) != 0) {
+                       pims_ipc_data_destroy(*outdata);
+                       *outdata = NULL;
+                       CTS_ERR("pims_ipc_data_put fail");
+                       return;
+               }
+       }
+       else {
+               CTS_ERR("outdata is NULL");
+       }
+
+       return;
+}
+
diff --git a/server/ctsvc_ipc_server2.h b/server/ctsvc_ipc_server2.h
new file mode 100644 (file)
index 0000000..9d45a5a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_IPC_SERVER2_H__
+#define __CTSVC_IPC_SERVER2_H__
+
+#include <pims-ipc-data.h>
+
+void ctsvc_ipc_activity_delete_by_contact_id(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_activity_delete_by_account_id(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+
+void ctsvc_ipc_group_add_contact(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_group_remove_contact(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_group_set_group_order(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+
+void ctsvc_ipc_person_link_person(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_person_unlink_contact(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+
+void ctsvc_ipc_person_reset_usage(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_person_set_favorite_order(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_person_set_default_property(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_person_get_default_property(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+
+#ifdef ENABLE_LOG_FEATURE
+void ctsvc_ipc_phone_log_reset_statistics(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_phone_log_delete(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+#endif // ENABLE_LOG_FEATURE
+
+void ctsvc_ipc_setting_get_name_display_order(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_setting_set_name_display_order(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_setting_get_name_sorting_order(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void ctsvc_ipc_setting_set_name_sorting_order(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+
+#endif /*__CTSVC_IPC_SERVER2_H__*/
diff --git a/server/ctsvc_schema_recovery.c b/server/ctsvc_schema_recovery.c
new file mode 100755 (executable)
index 0000000..720ecc6
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <sys/stat.h>
+#include <db-util.h>
+#include <sqlite3.h>
+
+#include "contacts.h"
+
+#include "ctsvc_internal.h"
+#include "ctsvc_server_sqlite.h"
+#include "schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_schema_recovery.h"
+#include "ctsvc_schema.h"
+
+// Additional Error
+enum {
+       CTSVC_ERR_NO_DB_FILE = -10000,
+       CTSVC_ERR_NO_TABLE,
+};
+
+static inline int __ctsvc_server_check_db_file(void)
+{
+       int fd = open(CTSVC_DB_PATH, O_RDONLY);
+       RETVM_IF(-1 == fd, CTSVC_ERR_NO_DB_FILE, "DB file is not exist");
+
+       close(fd);
+       return CONTACTS_ERROR_NONE;
+}
+
+static inline int __ctsvc_server_remake_db_file()
+{
+       int ret, fd;
+       char *errmsg;
+       sqlite3 *db;
+
+       ret = ctsvc_server_db_open(&db);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_server_db_open() Failed(%d)", ret);
+
+       ret = sqlite3_exec(db, schema_query, NULL, 0, &errmsg);
+       if (SQLITE_OK != ret) {
+               CTS_ERR("remake contacts DB file is Failed : %s", errmsg);
+               sqlite3_free(errmsg);
+       }
+
+       ctsvc_server_db_close();
+
+       fd = open(CTSVC_DB_PATH, O_CREAT | O_RDWR, 0660);
+       RETVM_IF(-1 == fd, CONTACTS_ERROR_SYSTEM, "open Failed");
+
+       ret = fchown(fd, getuid(), CTS_SECURITY_FILE_GROUP);
+       if (0 != ret)
+               CTS_ERR("fchown(%s) Failed(%d)", CTSVC_DB_PATH, ret);
+       ret = fchmod(fd, CTS_SECURITY_DEFAULT_PERMISSION);
+       if (0 != ret)
+               CTS_ERR("fchown(%s) Failed(%d)", CTSVC_DB_PATH, ret);
+       close(fd);
+
+       fd = open(CTSVC_DB_JOURNAL_PATH, O_CREAT | O_RDWR, 0660);
+       RETVM_IF(-1 == fd, CONTACTS_ERROR_SYSTEM, "open Failed");
+
+       ret = fchown(fd, getuid(), CTS_SECURITY_FILE_GROUP);
+       if (0 != ret)
+               CTS_ERR("fchown(%s) Failed(%d)", CTSVC_DB_JOURNAL_PATH, ret);
+       ret = fchmod(fd, CTS_SECURITY_DEFAULT_PERMISSION);
+       if (0 != ret)
+               CTS_ERR("fchown(%s) Failed(%d)", CTSVC_DB_JOURNAL_PATH, ret);
+       close(fd);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_server_check_table()
+{
+       int ret;
+       sqlite3 *db;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt = NULL;
+
+       ret = ctsvc_server_db_open(&db);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_server_db_open() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query),
+                       "SELECT name FROM sqlite_master WHERE type='table' AND name='%s'",
+                       CTS_TABLE_CONTACTS);
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if (SQLITE_OK != ret) {
+               CTS_ERR("DB error : sqlite3_prepare_v2(%s) Failed(%s)", query, sqlite3_errmsg(db));
+               ctsvc_server_db_close();
+               return CONTACTS_ERROR_DB;
+       }
+
+       ret = sqlite3_step(stmt);
+       if (SQLITE_ROW != ret) {
+               CTS_ERR("contacts table does not exist in contacts DB file : %s", sqlite3_errmsg(db));
+               sqlite3_finalize(stmt);
+               ctsvc_server_db_close();
+               return CTSVC_ERR_NO_TABLE;
+       }
+
+       sqlite3_finalize(stmt);
+       ctsvc_server_db_close();
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_server_check_schema(void)
+{
+       if (CTSVC_ERR_NO_DB_FILE == __ctsvc_server_check_db_file())
+               __ctsvc_server_remake_db_file();
+       else if (CTSVC_ERR_NO_TABLE == __ctsvc_server_check_table())
+               __ctsvc_server_remake_db_file();
+
+       return CONTACTS_ERROR_NONE;
+}
+
similarity index 73%
rename from helper/schema-recovery.h
rename to server/ctsvc_schema_recovery.h
index 9f7a2f8..77ccfc8 100755 (executable)
@@ -1,10 +1,8 @@
 /*
- * Contacts Service Helper
+ * 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
  * limitations under the License.
  *
  */
-#ifndef __CTS_HELPER_SCHEMA_RECOVERY_H__
-#define __CTS_HELPER_SCHEMA_RECOVERY_H__
+#ifndef __CTSVC_SERVER_SCHEMA_RECOVERY_H__
+#define __CTSVC_SERVER_SCHEMA_RECOVERY_H__
 
-int helper_check_schema();
+int ctsvc_server_check_schema();
 
-#endif // __CTS_HELPER_SCHEMA_RECOVERY_H__
+#endif // __CTSVC_SERVER_SCHEMA_RECOVERY_H__
 
 
diff --git a/server/ctsvc_server.c b/server/ctsvc_server.c
new file mode 100755 (executable)
index 0000000..38fc1ca
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Contact Service
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include <pims-ipc.h>
+#include <pims-ipc-svc.h>
+#include <unistd.h>    //getuid
+#include <grp.h>               //setgroups
+#include <glib/gstdio.h>
+
+#include "ctsvc_internal.h"
+#include "ctsvc_db_init.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_schema_recovery.h"
+#include "ctsvc_server_socket.h"
+#include "ctsvc_server_utils.h"
+#include "ctsvc_server_bg.h"
+#include "ctsvc_server_update.h"
+#include "ctsvc_db_access_control.h"
+#include "ctsvc_notification.h"
+
+#include "ctsvc_ipc_define.h"
+#include "ctsvc_ipc_server.h"
+#include "ctsvc_ipc_server2.h"
+
+static gboolean _ctsvc_idler_for_socket_init(gpointer user_data)
+{
+       CTS_FN_CALL;
+       if (g_access(CTSVC_IPC_SOCKET_PATH, F_OK) || g_access(CTSVC_IPC_SOCKET_PATH_FOR_CHANGE_SUBSCRIPTION, F_OK)) {
+               CTS_ERR("No file exists");
+               return TRUE;
+       }
+       ctsvc_noti_publish_socket_initialize();
+       return FALSE;
+}
+
+
+static int __server_main(void)
+{
+       int ret;
+       pims_ipc_svc_init(CTSVC_IPC_SOCKET_PATH, CTS_SECURITY_FILE_GROUP, 0777);
+
+       do {
+               // register handle functions
+               // These functions will be called when requesting from client module depends on module name and function name (pims_ipc_call, ctsvc_ipc_call)
+               // pims_ipc_svc_register(MODULE_NAME, FUNCTION_NAME ...);
+               if (pims_ipc_svc_register(CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_CONNECT, ctsvc_ipc_server_connect, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_DISCONNECT, ctsvc_ipc_server_disconnect, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_CHECK_PERMISSION, ctsvc_ipc_server_check_permission, NULL) != 0) break;
+
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_INSERT_RECORD, ctsvc_ipc_server_db_insert_record, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_RECORD, ctsvc_ipc_server_db_get_record, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_UPDATE_RECORD, ctsvc_ipc_server_db_update_record, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_DELETE_RECORD, ctsvc_ipc_server_db_delete_record, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_REPLACE_RECORD, ctsvc_ipc_server_db_replace_record, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_ALL_RECORDS, ctsvc_ipc_server_db_get_all_records, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_RECORDS_WITH_QUERY, ctsvc_ipc_server_db_get_records_with_query, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_COUNT, ctsvc_ipc_server_db_get_count, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_COUNT_WITH_QUERY, ctsvc_ipc_server_db_get_count_with_query, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_INSERT_RECORDS, ctsvc_ipc_server_db_insert_records, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_UPDATE_RECORDS, ctsvc_ipc_server_db_update_records, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_DELETE_RECORDS, ctsvc_ipc_server_db_delete_records, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_REPLACE_RECORDS, ctsvc_ipc_server_db_replace_records, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_CHANGES_BY_VERSION, ctsvc_ipc_server_db_get_changes_by_version, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_CURRENT_VERSION, ctsvc_ipc_server_db_get_current_version, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_SEARCH_RECORDS, ctsvc_ipc_server_db_search_records, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_SEARCH_RECORDS_WITH_RANGE, ctsvc_ipc_server_db_search_records_with_range, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_SEARCH_RECORDS_WITH_QUERY, ctsvc_ipc_server_db_search_records_with_query, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_STATUS, ctsvc_ipc_server_db_get_status, NULL) != 0) break;
+
+               if (pims_ipc_svc_register(CTSVC_IPC_ACTIVITY_MODULE, CTSVC_IPC_SERVER_ACTIVITY_DELETE_BY_CONTACT_ID, ctsvc_ipc_activity_delete_by_contact_id, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_ACTIVITY_MODULE, CTSVC_IPC_SERVER_ACTIVITY_DELETE_BY_ACCOUNT_ID, ctsvc_ipc_activity_delete_by_account_id, NULL) != 0) break;
+
+               if (pims_ipc_svc_register(CTSVC_IPC_GROUP_MODULE, CTSVC_IPC_SERVER_GROUP_ADD_CONTACT, ctsvc_ipc_group_add_contact, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_GROUP_MODULE, CTSVC_IPC_SERVER_GROUP_REMOVE_CONTACT, ctsvc_ipc_group_remove_contact, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_GROUP_MODULE, CTSVC_IPC_SERVER_GROUP_SET_GROUP_ORDER, ctsvc_ipc_group_set_group_order, NULL) != 0) break;
+
+               if (pims_ipc_svc_register(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_LINK_PERSON, ctsvc_ipc_person_link_person, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_UNLINK_CONTACT, ctsvc_ipc_person_unlink_contact, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_RESET_USAGE, ctsvc_ipc_person_reset_usage, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_SET_FAVORITE_ORDER, ctsvc_ipc_person_set_favorite_order, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_SET_DEFAULT_PROPERTY, ctsvc_ipc_person_set_default_property, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_PERSON_MODULE, CTSVC_IPC_SERVER_PERSON_GET_DEFAULT_PROPERTY, ctsvc_ipc_person_get_default_property, NULL) != 0) break;
+
+#ifdef ENABLE_LOG_FEATURE
+               if (pims_ipc_svc_register(CTSVC_IPC_PHONELOG_MODULE, CTSVC_IPC_SERVER_PHONELOG_RESET_STATISTICS, ctsvc_ipc_phone_log_reset_statistics, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_PHONELOG_MODULE, CTSVC_IPC_SERVER_PHONELOG_DELETE, ctsvc_ipc_phone_log_delete, NULL) != 0) break;
+#endif // ENABLE_LOG_FEATURE
+
+               if (pims_ipc_svc_register(CTSVC_IPC_SETTING_MODULE, CTSVC_IPC_SERVER_SETTING_GET_NAME_DISPLAY_ORDER, ctsvc_ipc_setting_get_name_display_order, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_SETTING_MODULE, CTSVC_IPC_SERVER_SETTING_SET_NAME_DISPLAY_ORDER, ctsvc_ipc_setting_set_name_display_order, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_SETTING_MODULE, CTSVC_IPC_SERVER_SETTING_GET_NAME_SORTING_ORDER, ctsvc_ipc_setting_get_name_sorting_order, NULL) != 0) break;
+               if (pims_ipc_svc_register(CTSVC_IPC_SETTING_MODULE, CTSVC_IPC_SERVER_SETTING_SET_NAME_SORTING_ORDER, ctsvc_ipc_setting_set_name_sorting_order, NULL) != 0) break;
+
+               pims_ipc_svc_init_for_publish(CTSVC_IPC_SOCKET_PATH_FOR_CHANGE_SUBSCRIPTION, CTS_SECURITY_FILE_GROUP, 0660);
+
+               g_idle_add(_ctsvc_idler_for_socket_init, NULL);
+
+               ret = contacts_connect();
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("contacts_connect fail(%d)", ret);
+                       break;
+               }
+               ctsvc_set_client_access_info("contacts-service", NULL);
+
+               ctsvc_server_bg_add_cb();
+               ctsvc_server_bg_delete_start();
+
+               ret = ctsvc_server_init_configuration();
+               CTS_DBG("%d", ret);
+
+               GMainLoop* main_loop;
+               main_loop = g_main_loop_new(NULL, FALSE);
+
+               pims_ipc_svc_run_main_loop(main_loop);
+
+               ctsvc_server_final_configuration();
+
+               ctsvc_server_bg_remove_cb();
+
+               ctsvc_unset_client_access_info();
+
+               ret = contacts_disconnect();
+               if (CONTACTS_ERROR_NONE != ret)
+                       CTS_DBG("%d", ret);
+
+               pims_ipc_svc_deinit_for_publish();
+
+               pims_ipc_svc_deinit();
+
+               return 0;
+
+       } while(0);
+
+       CTS_ERR("pims_ipc_svc_register error");
+       return -1;
+}
+
+int main(int argc, char *argv[])
+{
+       CTS_FN_CALL;
+       INFO("Start contacts-service");
+       int ret;
+
+       if (getuid() == 0) {                    // root
+               gid_t glist[] = {CTS_SECURITY_FILE_GROUP};
+               ret = setgroups(1, glist);              // client and server should have same Groups
+               WARN_IF(ret <0, "setgroups Fail(%d)", ret);
+       }
+
+       ctsvc_server_load_feature_list();
+       ctsvc_server_check_schema();
+       if (2 <= argc && !strcmp(argv[1], "schema"))
+               return CONTACTS_ERROR_NONE;
+
+       // update DB for compatability
+       ctsvc_server_db_update();
+
+       ret = ctsvc_server_socket_init();
+       CTS_DBG("%d", ret);
+
+       __server_main();
+
+       ctsvc_server_socket_deinit();
+
+       return 0;
+}
+
diff --git a/server/ctsvc_server_bg.c b/server/ctsvc_server_bg.c
new file mode 100644 (file)
index 0000000..204f4ec
--- /dev/null
@@ -0,0 +1,513 @@
+/*
+ * Contact Service
+ *
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <glib.h>
+#include <stdlib.h>
+#include <unistd.h>    //sleep
+
+#ifdef CTS_MOBILE
+#include <account.h>
+#endif // CTS_MOBILE
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_server_bg.h"
+#include "ctsvc_server_utils.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_db_plugin_addressbook_helper.h"
+#include "ctsvc_db_access_control.h"
+
+#define CTSVC_SERVER_BG_DELETE_COUNT 50
+#define CTSVC_SERVER_BG_DELETE_STEP_TIME 1
+#define CTSVC_SERVER_BG_DELETE_THREAD "ctsvc_server_bg_delete"
+
+#define CTSVC_SERVER_BG_BASE_CPU_USAGE         10  // Delete contacts when cpu usage is under the value
+
+typedef enum
+{
+       STEP_1, // get contact_ids
+       STEP_2, // delete data
+       STEP_3, // delete activity
+       STEP_4, // delete search_index, contact(image by trigger)
+} __ctsvc_delete_step_e;
+
+typedef struct {
+       GSList *contact_ids;
+       int current_contact_id;
+       __ctsvc_delete_step_e step;
+} __ctsvc_delete_data_s;
+
+GThread *__ctsvc_server_bg_delete_thread = NULL;
+GCond __ctsvc_server_bg_delete_cond;
+GMutex __ctsvc_server_bg_delete_mutex;
+
+#ifdef CTS_MOBILE
+account_subscribe_h account = NULL;
+#endif // CTS_MOBILE
+
+static int __ctsvc_server_bg_contact_delete_step1(__ctsvc_delete_data_s* data)
+{
+       char query[CTS_SQL_MIN_LEN] = {0,};
+       int ret;
+       cts_stmt stmt = NULL;
+       int count = 0;
+       GSList *cursor;
+
+       if (data->contact_ids == NULL) {
+               // get event_list
+               snprintf(query, sizeof(query), "SELECT contact_id FROM "CTS_TABLE_CONTACTS" WHERE deleted = 1");
+               ret = ctsvc_query_prepare(query, &stmt);
+               RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+               while(1 == (ret = ctsvc_stmt_step(stmt))) {
+                       int id = 0;
+                       id = ctsvc_stmt_get_int(stmt, 0);
+                       data->contact_ids = g_slist_append(data->contact_ids, GINT_TO_POINTER(id));
+               }
+               ctsvc_stmt_finalize(stmt);
+               if (ret < CONTACTS_ERROR_NONE)
+                       return ret;
+       }
+
+       count = g_slist_length(data->contact_ids);
+       if (count <= 0)
+               return CONTACTS_ERROR_NO_DATA;
+
+       cursor = g_slist_nth(data->contact_ids, 0);
+       if (cursor) {
+               data->current_contact_id = GPOINTER_TO_INT(cursor->data);
+               data->contact_ids = g_slist_remove(data->contact_ids, GINT_TO_POINTER(data->current_contact_id));
+
+               return CONTACTS_ERROR_NONE;
+       }
+       else {
+               return CONTACTS_ERROR_NO_DATA;
+       }
+}
+
+// remove data
+static int __ctsvc_server_bg_contact_delete_step2(__ctsvc_delete_data_s* data)
+{
+    CTS_FN_CALL;
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+       GSList *list = NULL;
+       cts_stmt stmt = NULL;
+       int count = 0;
+       GSList *cursor;
+
+       // get event_list
+       snprintf(query, sizeof(query),
+               "SELECT id FROM "CTS_TABLE_DATA" WHERE contact_id = %d LIMIT %d",
+               data->current_contact_id, CTSVC_SERVER_BG_DELETE_COUNT);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       while(1 == (ret = ctsvc_stmt_step(stmt))) {
+               int id = 0;
+               id = ctsvc_stmt_get_int(stmt, 0);
+               list = g_slist_append(list, GINT_TO_POINTER(id));
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       count = g_slist_length(list);
+       if (count <= 0)
+               return CONTACTS_ERROR_NO_DATA;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, CONTACTS_ERROR_DB, "DB failed" );
+
+       cursor = g_slist_nth(list, 0);
+       while(cursor) {
+               int id = GPOINTER_TO_INT(cursor->data);
+               snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_DATA" WHERE id = %d", id);
+
+               ret = ctsvc_query_exec(query);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("DB failed");
+                       ctsvc_end_trans(false);
+                       g_slist_free(list);
+                       return ret;
+               }
+               cursor = g_slist_next(cursor);
+       }
+       g_slist_free(list);
+       ret = ctsvc_end_trans(true);
+
+       return ret;
+}
+
+// remove activities
+static int __ctsvc_server_bg_contact_delete_step3(__ctsvc_delete_data_s* data)
+{
+    CTS_FN_CALL;
+
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+       GSList *list = NULL;
+       cts_stmt stmt = NULL;
+       int count = 0;
+       GSList *cursor;
+
+       // get event_list
+       snprintf(query, sizeof(query),
+               "SELECT id FROM "CTS_TABLE_ACTIVITIES" WHERE contact_id = %d LIMIT %d",
+               data->current_contact_id, CTSVC_SERVER_BG_DELETE_COUNT);
+
+       ret = ctsvc_query_prepare(query, &stmt);
+       RETVM_IF(NULL == stmt, ret, "DB error : ctsvc_query_prepare() Failed(%d)", ret);
+
+       while(1 == (ret = ctsvc_stmt_step(stmt))) {
+               int id = 0;
+               id = ctsvc_stmt_get_int(stmt, 0);
+               list = g_slist_append(list, GINT_TO_POINTER(id));
+       }
+       ctsvc_stmt_finalize(stmt);
+
+       count = g_slist_length(list);
+       if (count <= 0)
+               return CONTACTS_ERROR_NO_DATA;
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, CONTACTS_ERROR_DB, "DB failed" );
+
+       cursor = g_slist_nth(list, 0);
+       while(cursor) {
+               int id = GPOINTER_TO_INT(cursor->data);
+               snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_ACTIVITIES" WHERE id = %d", id);
+
+               ret = ctsvc_query_exec(query);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("DB failed");
+                       ctsvc_end_trans(false);
+                       g_slist_free(list);
+                       return ret;
+               }
+               cursor = g_slist_next(cursor);
+       }
+       g_slist_free(list);
+       ret = ctsvc_end_trans(true);
+
+       return ret;
+}
+
+static int __ctsvc_server_bg_contact_delete_step4(__ctsvc_delete_data_s* data)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       ret = ctsvc_begin_trans();
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, CONTACTS_ERROR_DB, "DB failed" );
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_SEARCH_INDEX" WHERE contact_id = %d",
+                                       data->current_contact_id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB failed");
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_CONTACTS" WHERE contact_id = %d",
+                                       data->current_contact_id);
+       ret = ctsvc_query_exec(query);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("DB failed");
+               ctsvc_end_trans(false);
+               return ret;
+       }
+
+       ret = ctsvc_end_trans(true);
+       return ret;
+}
+
+static bool __ctsvc_server_bg_contact_delete_step(int ret, __ctsvc_delete_data_s* data)
+{
+       if (ret != CONTACTS_ERROR_NONE && ret != CONTACTS_ERROR_NO_DATA) {
+               if(data->contact_ids)
+                       g_slist_free(data->contact_ids);
+               CTS_ERR("fail (%d)",ret);
+               return false;
+       }
+
+       switch (data->step) {
+       case STEP_1:
+               if (ret == CONTACTS_ERROR_NO_DATA) {
+                       if(data->contact_ids)
+                               g_slist_free(data->contact_ids);
+                       CTS_ERR("step_1 no_data");
+                       return false;
+               }
+               data->step = STEP_2;
+               break;
+       case STEP_2:
+               if (ret == CONTACTS_ERROR_NO_DATA)
+                       data->step = STEP_3;
+               break;
+       case STEP_3:
+               if (ret == CONTACTS_ERROR_NO_DATA)
+                       data->step = STEP_4;
+               break;
+       case STEP_4:
+               data->step = STEP_1;
+               break;
+       default:
+               data->step = STEP_1;
+               break;
+       }
+
+       return true;
+}
+
+static bool  __ctsvc_server_db_delete_run(__ctsvc_delete_data_s* data)
+{
+       CTS_FN_CALL;
+       int ret = CONTACTS_ERROR_NONE;
+
+       if(data == NULL) {
+               CTS_ERR("data is NULL");
+               return false;
+       }
+
+       switch (data->step) {
+               case STEP_1:
+                       // get deleted contact id list
+                       ret = __ctsvc_server_bg_contact_delete_step1(data);
+                       break;
+               case STEP_2:
+                       // delete data of current contact id (MAX CTSVC_SERVER_BG_DELETE_COUNT)
+                       ret = __ctsvc_server_bg_contact_delete_step2(data);
+                       break;
+               case STEP_3:
+                       // delete activity of current contact id (MAX CTSVC_SERVER_BG_DELETE_COUNT each time)
+                       ret = __ctsvc_server_bg_contact_delete_step3(data);
+                       break;
+               case STEP_4:
+                       // delete search index of current contact id
+                       ret = __ctsvc_server_bg_contact_delete_step4(data);
+                       break;
+               default:
+                       CTS_ERR("invalid step");
+                       if(data->contact_ids)
+                       g_slist_free(data->contact_ids);
+                       return false;
+       }
+
+       return __ctsvc_server_bg_contact_delete_step(ret, data);
+}
+
+typedef struct {
+       unsigned long int cpu_work_time;
+       unsigned long int cpu_total_time;
+}process_stat;
+
+static process_stat* __ctsvc_get_cpu_stat()
+{
+       int i;
+       int ret;
+       long unsigned int cpu_time[10];
+       process_stat *result = NULL;
+
+       FILE *fstat = fopen("/proc/stat", "r");
+       if (fstat == NULL) {
+               return NULL;
+       }
+       memset(cpu_time, 0x0, sizeof(cpu_time));
+       ret = fscanf(fstat, "%*s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
+                       &cpu_time[0], &cpu_time[1], &cpu_time[2], &cpu_time[3],
+                       &cpu_time[4], &cpu_time[5], &cpu_time[6], &cpu_time[7],
+                       &cpu_time[8], &cpu_time[9]);
+       fclose(fstat);
+
+       if (ret < 0) {
+               return NULL;
+       }
+
+       result = calloc(1, sizeof(process_stat));
+       RETVM_IF(NULL == result, NULL, "calloc() return NULL");
+
+       for(i=0; i < 10;i++) {
+               if (i < 3)
+                       result->cpu_work_time += cpu_time[i];
+               result->cpu_total_time += cpu_time[i];
+       }
+
+       return result;
+}
+
+static bool __ctsvc_cpu_is_busy()
+{
+       unsigned long int total_time_diff;
+       unsigned long int work_time_diff;
+       process_stat *result1 = NULL;
+       process_stat *result2 = NULL;
+       double cpu_usage;
+
+       result1 = __ctsvc_get_cpu_stat();
+       sleep(1);
+       result2 = __ctsvc_get_cpu_stat();
+       if (result1 == NULL || result2 == NULL) {
+               free(result1);
+               free(result2);
+               return false;
+       }
+
+       total_time_diff = result2->cpu_total_time - result1->cpu_total_time;
+       work_time_diff = result2->cpu_work_time - result1->cpu_work_time;
+
+       free(result1);
+       free(result2);
+
+       cpu_usage = ((double)work_time_diff/(double)total_time_diff) * 100;
+       CTS_INFO("cpu usage : %.2lf (%ld/%ld)", cpu_usage, work_time_diff, total_time_diff);
+       if (cpu_usage > CTSVC_SERVER_BG_BASE_CPU_USAGE)
+               return true;
+       return false;
+}
+
+static gpointer __ctsvc_server_bg_delete(gpointer user_data)
+{
+       CTS_FN_CALL;
+       int ret;
+       __ctsvc_delete_data_s *callback_data = NULL;
+
+       while(1) {
+               callback_data = calloc(1,sizeof(__ctsvc_delete_data_s));
+               if (callback_data == NULL) {
+                       CTS_ERR("calloc fail");
+                       continue;
+               }
+               callback_data->step = STEP_1;
+
+               ret = contacts_connect();
+               if (CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("contacts_connect() fail(%d)", ret);
+                       free(callback_data);
+                       continue;
+               }
+               ctsvc_set_client_access_info("contacts-service", NULL);
+
+               while(1) {
+//                     sleep(CTSVC_SERVER_BG_DELETE_STEP_TIME); // sleep 1 sec.
+                       if (__ctsvc_cpu_is_busy()) {                            // sleep 1 sec in function
+                               CTS_ERR("Now CPU is busy.. waiting");
+                               sleep(CTSVC_SERVER_BG_DELETE_STEP_TIME*59); // sleep 60 sec(1 min) totally
+                               continue;
+                       }
+                       if (__ctsvc_server_db_delete_run(callback_data) == false) {
+                               CTS_DBG("end");
+                               free(callback_data);
+                               break;
+                       }
+               }
+
+               ctsvc_unset_client_access_info();
+
+               ret = contacts_disconnect();
+               if (CONTACTS_ERROR_NONE != ret)
+                       CTS_ERR("contacts_disconnect Fail(%d)", ret);
+
+               g_mutex_lock(&__ctsvc_server_bg_delete_mutex);
+               CTS_DBG("wait");
+               g_cond_wait(&__ctsvc_server_bg_delete_cond, &__ctsvc_server_bg_delete_mutex);
+               g_mutex_unlock(&__ctsvc_server_bg_delete_mutex);
+       }
+
+       return NULL;
+}
+
+void ctsvc_server_bg_delete_start()
+{
+       CTS_FN_CALL;
+
+       if (__ctsvc_server_bg_delete_thread == NULL) {
+               g_mutex_init(&__ctsvc_server_bg_delete_mutex);
+               g_cond_init(&__ctsvc_server_bg_delete_cond);
+               __ctsvc_server_bg_delete_thread = g_thread_new(CTSVC_SERVER_BG_DELETE_THREAD,
+                               __ctsvc_server_bg_delete, NULL);
+       }
+
+       // don't use mutex.
+       g_cond_signal(&__ctsvc_server_bg_delete_cond);
+}
+
+static void __ctsvc_server_addressbook_deleted_cb(const char *view_uri, void *data)
+{
+       // access control update
+       ctsvc_reset_all_client_access_info();
+
+       ctsvc_server_bg_delete_start();
+}
+
+static void __ctsvc_server_contact_deleted_cb(const char *view_uri, void *data)
+{
+       ctsvc_server_bg_delete_start();
+}
+
+#ifdef CTS_MOBILE
+static bool __ctsvc_server_account_delete_cb(const char* event_type, int account_id, void* user_data)
+{
+       CTS_FN_CALL;
+       CTS_INFO("event_type : %s, account_id : %d", event_type, account_id);
+       if (strcmp(event_type, ACCOUNT_NOTI_NAME_DELETE) == 0)
+               ctsvc_addressbook_delete(account_id);
+       return true;
+}
+#endif // CTS_MOBILE
+
+void ctsvc_server_bg_add_cb()
+{
+       int ret;
+       ret = contacts_db_add_changed_cb(_contacts_address_book._uri, __ctsvc_server_addressbook_deleted_cb, NULL);
+       CTS_DBG("call contacts_db_add_changed_cb (_contacts_address_book)  : return (%d)", ret);
+       ret = contacts_db_add_changed_cb(_contacts_contact._uri, __ctsvc_server_contact_deleted_cb, NULL);
+       CTS_DBG("call contacts_db_add_changed_cb (_contacts_contact): return (%d)", ret);
+
+#ifdef CTS_MOBILE
+       ret = account_subscribe_create(&account);
+       if (ACCOUNT_ERROR_NONE == ret) {
+               ret = account_subscribe_notification(account, __ctsvc_server_account_delete_cb, NULL);
+               if (ACCOUNT_ERROR_NONE != ret) {
+                       CTS_ERR("account_subscribe_notification Failed (%d)", ret);
+               }
+       }
+       else
+               CTS_ERR("account_subscribe_create Failed (%d)", ret);
+#endif // CTS_MOBILE
+}
+
+void ctsvc_server_bg_remove_cb()
+{
+       int ret;
+       ret = contacts_db_remove_changed_cb(_contacts_address_book._uri, __ctsvc_server_addressbook_deleted_cb, NULL);
+       CTS_ERR("call contacts_db_remove_changed_cb (_contacts_address_book): return (%d)", ret);
+       ret = contacts_db_remove_changed_cb(_contacts_contact._uri, __ctsvc_server_contact_deleted_cb, NULL);
+       CTS_ERR("call contacts_db_remove_changed_cb (_contacts_contact) : return (%d)", ret);
+
+#ifdef CTS_MOBILE
+       if (account) {
+               account_unsubscribe_notification(account);              // unsubscirbe & destroy
+               account = NULL;
+       }
+#endif // CTS_MOBILE
+}
+
diff --git a/server/ctsvc_server_bg.h b/server/ctsvc_server_bg.h
new file mode 100644 (file)
index 0000000..bbc51ee
--- /dev/null
@@ -0,0 +1,27 @@
+/*\r
+ * Contact Service\r
+ *\r
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ */\r
+\r
+#ifndef __CTSVC_SERVER_BG_H__\r
+#define __CTSVC_SERVER_BG_H__\r
+\r
+void ctsvc_server_bg_delete_start();\r
+void ctsvc_server_bg_add_cb();\r
+void ctsvc_server_bg_remove_cb();\r
+\r
+#endif /* __CTSVC_SERVER_BG_H__ */\r
diff --git a/server/ctsvc_server_change_subject.c b/server/ctsvc_server_change_subject.c
new file mode 100644 (file)
index 0000000..fdef853
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <pims-ipc.h>
+#include <pims-ipc-svc.h>
+#include <pims-ipc-data.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_ipc_define.h"
+#include "ctsvc_server_change_subject.h"
+
+#define CTSVC_SUBSCRIBE_MAX_LEN        1024
+
+#ifdef ENABLE_LOG_FEATURE
+static __thread char *__phone_log_chanaged_info = NULL;
+static __thread unsigned int __phone_log_buf_size = 0;
+#endif // ENABLE_LOG_FEATURE
+
+static __thread char *__person_changed_info = NULL;
+static __thread unsigned int __person_buf_size = 0;
+
+static gboolean __ctsvc_publish_changes_with_data(const char *view_uri, char *data)
+{
+       pims_ipc_data_h indata = NULL;
+       if( NULL == data )
+               return true;
+
+       indata = pims_ipc_data_create(0);
+       if (!indata) {
+               CTS_ERR("pims_ipc_data_create error\n");
+               return false;
+       }
+
+       if (pims_ipc_data_put(indata, data, strlen(data) + 1) != 0) {
+               CTS_ERR("pims_ipc_data_put error\n");
+               pims_ipc_data_destroy(indata);
+               return false;
+       }
+
+       if (pims_ipc_svc_publish(CTSVC_IPC_SUBSCRIBE_MODULE, (char*)view_uri, indata) != 0) {
+               CTS_ERR("pims_ipc_svc_publish error (%s)\n", view_uri);
+               return false;
+       }
+
+       pims_ipc_data_destroy(indata);
+
+       return true;
+}
+
+void ctsvc_change_subject_publish_changed_info()
+{
+       __ctsvc_publish_changes_with_data(_contacts_person._uri, __person_changed_info);
+#ifdef ENABLE_LOG_FEATURE
+       __ctsvc_publish_changes_with_data(_contacts_phone_log._uri, __phone_log_chanaged_info);
+#endif // ENABLE_LOG_FEATURE
+       ctsvc_change_subject_clear_changed_info();
+}
+
+void ctsvc_change_subject_clear_changed_info()
+{
+#ifdef ENABLE_LOG_FEATURE
+       free(__phone_log_chanaged_info);
+       __phone_log_chanaged_info = NULL;
+       __phone_log_buf_size = 0;
+#endif // ENABLE_LOG_FEATURE
+
+       free(__person_changed_info);
+       __person_changed_info = NULL;
+       __person_buf_size = 0;
+}
+
+#ifdef ENABLE_LOG_FEATURE
+void ctsvc_change_subject_add_changed_phone_log_id(contacts_changed_e type, int id)
+{
+       CTS_FN_CALL;
+       int len = 0;
+       int info_len = 0;
+       char changed_info[30] = {0};
+
+       if (!__phone_log_chanaged_info) {
+               __phone_log_chanaged_info = (char*)calloc(CTSVC_SUBSCRIBE_MAX_LEN, sizeof(char));
+               __phone_log_buf_size = CTSVC_SUBSCRIBE_MAX_LEN;
+               __phone_log_chanaged_info[0] = '\0';
+       }
+
+       len = snprintf(changed_info, sizeof(changed_info), "%d:%d,", type, id);
+       info_len = strlen(__phone_log_chanaged_info);
+       CTS_DBG("%s(len : %d), %s (crrent_len : %d), max_len : %d",
+               changed_info, len, __phone_log_chanaged_info, info_len, __phone_log_buf_size);
+       if (info_len + len > __phone_log_buf_size) {
+               __phone_log_chanaged_info = realloc(__phone_log_chanaged_info, __phone_log_buf_size * 2);
+               __phone_log_buf_size *= 2;
+       }
+       snprintf(__phone_log_chanaged_info + info_len, __phone_log_buf_size - info_len, "%s", changed_info);
+       CTS_DBG("%s", __phone_log_chanaged_info);
+}
+#endif // ENABLE_LOG_FEATURE
+
+void ctsvc_change_subject_add_changed_person_id(contacts_changed_e type, int id)
+{
+       CTS_FN_CALL;
+       int len = 0;
+       int info_len = 0;
+       char changed_info[30] = {0};
+
+       if (!__person_changed_info) {
+               __person_changed_info = (char*)calloc(CTSVC_SUBSCRIBE_MAX_LEN, sizeof(char));
+               __person_buf_size = CTSVC_SUBSCRIBE_MAX_LEN;
+               __person_changed_info[0] = '\0';
+       }
+
+       len = snprintf(changed_info, sizeof(changed_info), "%d:%d,", type, id);
+       info_len = strlen(__person_changed_info);
+       if (info_len + len > __person_buf_size) {
+               __person_changed_info = realloc(__person_changed_info, __person_buf_size * 2);
+               __person_buf_size *= 2;
+       }
+       snprintf(__person_changed_info + info_len, __person_buf_size - info_len, "%s", changed_info);
+}
+
+void ctsvc_change_subject_publish_setting(const char *setting_id, int value)
+{
+       pims_ipc_data_h indata = NULL;
+       indata = pims_ipc_data_create(0);
+       RETM_IF(NULL == indata, "pims_ipc_data_create error");
+
+       if (pims_ipc_data_put(indata, (void*)&value, sizeof(int)) != 0) {
+               CTS_ERR("pims_ipc_data_put error");
+               pims_ipc_data_destroy(indata);
+               return;
+       }
+
+       if (pims_ipc_svc_publish(CTSVC_IPC_SUBSCRIBE_MODULE, (char*)setting_id, indata) != 0)
+               CTS_ERR("pims_ipc_svc_publish error (%s)", setting_id);
+
+       pims_ipc_data_destroy(indata);
+}
+
+void ctsvc_change_subject_publish_status(contacts_db_status_e status)
+{
+       pims_ipc_data_h indata = NULL;
+       indata = pims_ipc_data_create(0);
+       RETM_IF(NULL == indata, "pims_ipc_data_create error");
+
+       if (pims_ipc_data_put(indata, (void*)&status, sizeof(int)) != 0) {
+               CTS_ERR("pims_ipc_data_put error");
+               pims_ipc_data_destroy(indata);
+               return;
+       }
+
+       if (pims_ipc_svc_publish(CTSVC_IPC_SUBSCRIBE_MODULE, CTSVC_IPC_SERVER_DB_STATUS_CHANGED, indata) != 0)
+               CTS_ERR("pims_ipc_svc_publish error(service status)");
+
+       pims_ipc_data_destroy(indata);
+}
+
diff --git a/server/ctsvc_server_change_subject.h b/server/ctsvc_server_change_subject.h
new file mode 100644 (file)
index 0000000..d8ce5a4
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_SERVER_CHANGE_SUBJECT_H__
+#define __CTSVC_SERVER_CHANGE_SUBJECT_H__
+
+#include "contacts_db.h"
+#include "contacts_db_status.h"
+#include "contacts_types.h"
+
+// Publish change info using PIMS-IPC PUB/SUB socket
+// It is only available in client-server architecture
+
+void ctsvc_change_subject_publish_changed_info();
+void ctsvc_change_subject_clear_changed_info();
+
+#ifdef ENABLE_LOG_FEATURE
+void ctsvc_change_subject_add_changed_phone_log_id(contacts_changed_e type, int id);
+#endif // ENABLE_LOG_FEATURE
+void ctsvc_change_subject_add_changed_person_id(contacts_changed_e type, int id);
+
+void ctsvc_change_subject_publish_setting(const char *setting_id, int value);
+void ctsvc_change_subject_publish_status(contacts_db_status_e status);
+
+#endif // __CTSVC_SERVER_CHANGE_SUBJECT_H__
\ No newline at end of file
diff --git a/server/ctsvc_server_sim.c b/server/ctsvc_server_sim.c
new file mode 100755 (executable)
index 0000000..19dc976
--- /dev/null
@@ -0,0 +1,1012 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <glib-object.h>
+#include <string.h>
+#include <tapi_common.h>
+#include <ITapiSim.h>
+#include <ITapiPhonebook.h>
+#include <TapiUtility.h>
+#include <vconf.h>
+#include <vconf-internal-telephony-keys.h>
+
+#include "contacts.h"
+
+#include "ctsvc_internal.h"
+#include "ctsvc_struct.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_server_socket.h"
+#include "ctsvc_server_sqlite.h"
+#include "ctsvc_server_utils.h"
+#include "ctsvc_server_sim.h"
+#include "ctsvc_utils.h"
+#include "ctsvc_list.h"
+#include "ctsvc_db_access_control.h"
+
+//#define CTSVC_SIM_FIELD_FULL_SUPPORT// support ANR,EMAIL2,3,NICK NAME
+#define DEFAULT_ADDRESS_BOOK_ID 0
+
+#define CTSVC_TAPI_SIM_PB_MAX 0xFFFF
+
+#define TAPI_PB_MAX_FILE_CNT TAPI_PB_3G_PBC+1
+
+#define CTSVC_2GSIM_NAME TAPI_PB_3G_NAME
+#define CTSVC_2GSIM_NUMBER TAPI_PB_3G_NUMBER
+
+typedef struct {
+       bool support;
+       unsigned int index_max;
+       unsigned int text_max;
+       unsigned int used_count;
+}sim_file_s;
+
+typedef struct {
+       // SIM slot number
+       int sim_slot_no;
+
+       // SIM info table id
+       // it is used when inserting/seaching phonelog
+       int sim_info_id;
+
+       // SIM slot id
+       char *cp_name;
+
+       // Tapi handle to control each SIM slot
+       TapiHandle *handle;
+
+       // SIM type
+       TelSimPbType_t sim_type;
+
+       // Each sim file info (max index, max text length, used count)
+       sim_file_s file_record[TAPI_PB_MAX_FILE_CNT];
+
+       //To bulk insert SIM contact, Free after insert them
+       GSList *import_contacts;
+
+       // Set true after read SIM meta info
+       // in case of private : set true after reading all SIM contact and save to DB
+       bool initialized;
+
+       // unique info of SIM : iccid
+       // It should be save to phone log table
+       // in order to find which SIM is used to the call/message log
+       char* sim_unique_id;
+
+} ctsvc_sim_info_s;
+
+
+static GSList *__ctsvc_sim_info = NULL;
+static void* greturn_data = NULL;
+static bool __ctsvc_tapi_cb = false;
+static bool __ctsvc_sim_cb = false;
+
+static void __ctsvc_server_sim_get_meta_info_cb(TapiHandle *handle, int result, void *data, void *user_data);
+static int __ctsvc_server_sim_init_info(ctsvc_sim_info_s *info);
+
+static TapiHandle* __ctsvc_server_sim_get_tapi_handle(ctsvc_sim_info_s *info)
+{
+       if (info->handle == NULL) {
+               int bReady = 0;
+               // TODO: it should be changed API
+               vconf_get_bool(VCONFKEY_TELEPHONY_READY, &bReady);
+
+               if (!bReady) {
+                       CTS_ERR("telephony is not ready ");
+                       return NULL;
+               }
+               else {
+                       info->handle = tel_init(info->cp_name);
+                       RETVM_IF(NULL == info->handle, NULL, "tel_init() Failed");
+               }
+       }
+
+       return info->handle;
+}
+
+static inline void __ctsvc_server_sim_set_return_data(void* data)
+{
+       greturn_data = data;
+}
+
+static inline void* __ctsvc_server_sim_get_return_data(void)
+{
+       RETVM_IF(greturn_data == NULL, NULL, "greturn_data is NULL");
+       return greturn_data;
+}
+
+void ctsvc_server_sim_record_destroy(sim_contact_s *record)
+{
+       RETM_IF(record == NULL, "record is NULL");
+
+       free(record->name);
+       free(record->number);
+       free(record->anr1);
+       free(record->anr2);
+       free(record->anr3);
+       free(record->email1);
+       free(record->email2);
+       free(record->email3);
+       free(record->email4);
+       free(record);
+
+       return;
+}
+
+static sim_contact_s * __ctsvc_server_sim_record_clone(TelSimPbRecord_t *sim_record)
+{
+       sim_contact_s *record = calloc(1,sizeof(sim_contact_s));
+       RETVM_IF(NULL == record, NULL, "calloc() return NULL");
+
+       record->sim_index = sim_record->index;
+       record->name = SAFE_STRDUP((char*)sim_record->name);
+       record->nickname = SAFE_STRDUP((char*)sim_record->sne);
+       record->number = SAFE_STRDUP((char*)sim_record->number);
+       record->anr1 = SAFE_STRDUP((char*)sim_record->anr1);
+       record->anr2 = SAFE_STRDUP((char*)sim_record->anr2);
+       record->anr3 = SAFE_STRDUP((char*)sim_record->anr3);
+       record->email1 = SAFE_STRDUP((char*)sim_record->email1);
+       record->email2 = SAFE_STRDUP((char*)sim_record->email2);
+       record->email3 = SAFE_STRDUP((char*)sim_record->email3);
+       record->email4 = SAFE_STRDUP((char*)sim_record->email4);
+
+       return record;
+}
+
+static inline int __ctsvc_server_sim_record_add_num(contacts_record_h *record, char *number)
+{
+       int ret;
+
+       RETVM_IF(number == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "invalid number");
+
+       ret = contacts_record_create(_contacts_number._uri, record);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Failed(%d)", ret);
+       ret = contacts_record_set_str(*record, _contacts_number.number, number);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_set_str() Failed(%d)", ret);
+       ret = contacts_record_set_int(*record, _contacts_number.type, CONTACTS_NUMBER_TYPE_OTHER);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_set_int() Failed(%d)", ret);
+
+       return ret;
+}
+
+static inline int __ctsvc_server_sim_record_add_email(contacts_record_h *record, char *email)
+{
+       int ret;
+
+       RETVM_IF(email == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "invalid email");
+
+       ret = contacts_record_create(_contacts_email._uri, record);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create() Failed(%d)", ret);
+       ret = contacts_record_set_str(*record, _contacts_email.email, email);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_set_str() Failed(%d)", ret);
+       ret = contacts_record_set_int(*record, _contacts_email.type,CONTACTS_EMAIL_TYPE_OTHER);
+       RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_set_int() Failed(%d)", ret);
+
+       return ret;
+}
+
+static int __ctsvc_server_sim_ctsvc_record_clone(sim_contact_s *record,
+       int addressbook_id, contacts_record_h *contact)
+{
+       CTS_FN_CALL;
+       int ret;
+       char sim_id[20] = {0};
+       contacts_record_h name = NULL;
+       contacts_record_h number = NULL;
+       contacts_record_h email = NULL;
+
+       RETVM_IF(contact == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : contact is NULL");
+       *contact = NULL;
+       RETVM_IF(record == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : record is NULL");
+       RETVM_IF(record->sim_index <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "The index(%d) is invalid", record->sim_index);
+
+       CTS_DBG("insert record->sim_index %d", record->sim_index);
+
+       ret = contacts_record_create(_contacts_contact._uri, contact);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create failed(%d)", ret);
+       snprintf(sim_id, sizeof(sim_id), "%d", record->sim_index);
+       contacts_record_set_str(*contact, _contacts_contact.uid, sim_id);
+
+       if (record->name) {
+               contacts_record_create(_contacts_name._uri, &name);
+               if (name) {
+                       contacts_record_set_str(name, _contacts_name.first, (char *)record->name);
+                       contacts_record_add_child_record(*contact, _contacts_contact.name, name);
+               }
+       }
+
+#ifdef CTSVC_SIM_FIELD_FULL_SUPPORT
+       contacts_record_h nick = NULL;
+       if (record->nickname) {
+               contacts_record_create(_contacts_nickname._uri, &nick);
+               if (nick) {
+                       contacts_record_set_str(nick, _contacts_nickname.name, (char *)record->nickname);
+                       contacts_record_add_child_record(*contact, _contacts_contact.nickname, nick);
+               }
+       }
+#endif //CTSVC_SIM_FIELD_FULL_SUPPORT
+
+       ret = __ctsvc_server_sim_record_add_num(&number, (char *)record->number);
+       if (CONTACTS_ERROR_NONE == ret)
+               contacts_record_add_child_record(*contact, _contacts_contact.number, number);
+
+#ifdef CTSVC_SIM_FIELD_FULL_SUPPORT
+       ret = __ctsvc_server_sim_record_add_num(&number, (char *)record->anr1);
+       if (CONTACTS_ERROR_NONE == ret)
+               contacts_record_add_child_record(*contact, _contacts_contact.number, number);
+
+       ret = __ctsvc_server_sim_record_add_num(&number, (char *)record->anr2);
+       if (CONTACTS_ERROR_NONE == ret)
+               contacts_record_add_child_record(*contact, _contacts_contact.number, number);
+
+       ret = __ctsvc_server_sim_record_add_num(&number, (char *)record->anr3);
+       if (CONTACTS_ERROR_NONE == ret)
+               contacts_record_add_child_record(*contact, _contacts_contact.number, number);
+#endif //CTSVC_SIM_FIELD_FULL_SUPPORT
+
+       ret = __ctsvc_server_sim_record_add_email(&email, (char *)record->email1);
+       if (CONTACTS_ERROR_NONE == ret)
+               contacts_record_add_child_record(*contact, _contacts_contact.email, email);
+
+#ifdef CTSVC_SIM_FIELD_FULL_SUPPORT
+       ret = __ctsvc_server_sim_record_add_email(&email, (char *)record->email2);
+       if (CONTACTS_ERROR_NONE == ret)
+               contacts_record_add_child_record(*contact, _contacts_contact.email, email);
+
+       ret = __ctsvc_server_sim_record_add_email(&email, (char *)record->email3);
+       if (CONTACTS_ERROR_NONE == ret)
+               contacts_record_add_child_record(*contact, _contacts_contact.email, email);
+
+       ret = __ctsvc_server_sim_record_add_email(&email, (char *)record->email4);
+       if (CONTACTS_ERROR_NONE == ret)
+               contacts_record_add_child_record(*contact, _contacts_contact.email, email);
+#endif //CTSVC_SIM_FIELD_FULL_SUPPORT
+
+       contacts_record_set_int(*contact, _contacts_contact.address_book_id, addressbook_id);
+
+       return ret;
+}
+
+static ctsvc_sim_info_s* __ctsvc_server_sim_get_handle_by_tapi_handle(TapiHandle *handle)
+{
+       GSList *cursor = NULL;
+       for(cursor=__ctsvc_sim_info;cursor;cursor=cursor->next) {
+               ctsvc_sim_info_s *info = cursor->data;
+               if (info->handle == handle)
+                       return info;
+       }
+       return NULL;
+}
+
+static ctsvc_sim_info_s* __ctsvc_server_sim_get_handle_by_sim_slot_no(int slot_no)
+{
+       GSList *cursor = NULL;
+
+       if (slot_no < 0)
+               return NULL;
+
+       for(cursor=__ctsvc_sim_info;cursor;cursor=cursor->next) {
+               ctsvc_sim_info_s *info = cursor->data;
+               if (info->sim_slot_no == slot_no) {
+                       if (NULL == __ctsvc_server_sim_get_tapi_handle(info))
+                               return NULL;
+                       return info;
+               }
+       }
+       return NULL;
+}
+
+int ctsvc_server_sim_get_info_id_by_sim_slot_no(int slot_no)
+{
+       GSList *cursor = NULL;
+
+       if (slot_no < 0)
+               return -1;
+
+       for(cursor=__ctsvc_sim_info;cursor;cursor=cursor->next) {
+               ctsvc_sim_info_s *info = cursor->data;
+               if (info->sim_slot_no == slot_no) {
+                       if (NULL == __ctsvc_server_sim_get_tapi_handle(info))
+                               return -1;
+                       return info->sim_info_id;
+               }
+       }
+       return -1;
+}
+
+int ctsvc_server_sim_get_sim_slot_no_by_info_id(int sim_info_id)
+{
+       GSList *cursor = NULL;
+       for(cursor=__ctsvc_sim_info;cursor;cursor=cursor->next) {
+               ctsvc_sim_info_s *info = cursor->data;
+               if (info->sim_info_id == sim_info_id) {
+                       if (NULL == __ctsvc_server_sim_get_tapi_handle(info))
+                               return -1;
+                       return info->sim_slot_no;
+               }
+       }
+       return -1;
+}
+
+static int __ctsvc_server_sim_insert_records_to_db(ctsvc_sim_info_s *info)
+{
+       CTS_FN_CALL;
+       int i;
+       int ret = 0;
+       sim_contact_s *record = NULL;
+       contacts_record_h contact = NULL;
+       contacts_list_h list = NULL;
+       GSList *cursor = NULL;
+
+       // insert contacts to DB
+       for (cursor = info->import_contacts, i=0;cursor;i++) {
+               if (list == NULL)
+                       contacts_list_create(&list);
+               ret = __ctsvc_server_sim_ctsvc_record_clone(cursor->data, DEFAULT_ADDRESS_BOOK_ID, &contact);
+               contacts_list_add(list, contact);
+               if (i == 50) {
+                       ret = contacts_db_insert_records(list, NULL, NULL);
+                       WARN_IF(ret < CONTACTS_ERROR_NONE, "contacts_db_insert_records() Failed(%d)", ret);
+                       contacts_list_destroy(list, true);
+                       list = NULL;
+                       i = 0;
+               }
+               cursor = cursor->next;
+               info->import_contacts = g_slist_remove(info->import_contacts, record);
+               ctsvc_server_sim_record_destroy(record);
+       }
+       g_slist_free(info->import_contacts);
+       info->import_contacts = NULL;
+
+       if (list) {
+               ret = contacts_db_insert_records(list, NULL, NULL);
+               WARN_IF(ret < CONTACTS_ERROR_NONE, "contacts_db_insert_records() Failed(%d)", ret);
+               contacts_list_destroy(list, true);
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static void __ctsvc_server_sim_import_contact_cb(TapiHandle *handle, int result, void *data, void* user_data)
+{
+       CTS_FN_CALL;
+       int ret = 0;
+       TelSimPbAccessResult_t access_rt = result;
+       TelSimPbRecord_t *sim_info = data;
+       sim_contact_s *record = NULL;
+       ctsvc_sim_info_s *info;
+
+       if (NULL == sim_info) {
+               CTS_ERR("sim_info is NULL, result = %d", access_rt);
+               ret = CONTACTS_ERROR_SYSTEM;
+               goto ERROR_RETURN;
+       }
+
+       info = __ctsvc_server_sim_get_handle_by_tapi_handle(handle);
+       if (info == NULL) {
+               CTS_ERR("__ctsvc_server_sim_get_handle_by_tapi_handle fail");
+               ret = CONTACTS_ERROR_SYSTEM;
+               goto ERROR_RETURN;
+       }
+
+       if (access_rt == TAPI_SIM_PB_INVALID_INDEX) {
+               int start_index = 0;
+               if (user_data != NULL)
+                       start_index = (int)user_data;
+               CTS_DBG("TAPI_SIM_PB_INVALID_INDEX : start_index = %d",start_index);
+               start_index++;
+               if (start_index > info->file_record[TAPI_PB_3G_NAME].index_max) {
+                       CTS_ERR("start_index is invalid start_index = %d, total = %d", start_index,
+                                               info->file_record[TAPI_PB_3G_NAME].index_max);
+                       ret = CONTACTS_ERROR_SYSTEM;
+                       goto ERROR_RETURN;
+               }
+               ret = tel_read_sim_pb_record(handle, info->sim_type, start_index,
+                                       __ctsvc_server_sim_import_contact_cb, (void*)start_index);
+               if (ret != TAPI_API_SUCCESS) {
+                       CTS_ERR("SIM phonebook access Failed(%d) start_indext(%d)", access_rt,start_index);
+                       ret = CONTACTS_ERROR_SYSTEM;
+                       goto ERROR_RETURN;
+               }
+       }
+
+       if (TAPI_SIM_PB_SUCCESS != access_rt) {
+               CTS_ERR("SIM phonebook access Failed(%d)", access_rt);
+               ret = CONTACTS_ERROR_SYSTEM;
+               goto ERROR_RETURN;
+       }
+
+       switch (sim_info->phonebook_type) {
+       case TAPI_SIM_PB_ADN:
+       case TAPI_SIM_PB_3GSIM:
+               record = __ctsvc_server_sim_record_clone(sim_info);
+               info->import_contacts = g_slist_append(info->import_contacts, (void*)record);
+               break;
+       case TAPI_SIM_PB_FDN:
+       case TAPI_SIM_PB_SDN:
+       default:
+               CTS_ERR("Unknown storage type(%d)", sim_info->phonebook_type);
+               ret = CONTACTS_ERROR_SYSTEM;
+               goto ERROR_RETURN;
+       }
+
+       if (sim_info->next_index && CTSVC_TAPI_SIM_PB_MAX != sim_info->next_index) {
+               CTS_DBG("NextIndex = %d", sim_info->next_index);
+               ret = tel_read_sim_pb_record(__ctsvc_server_sim_get_tapi_handle(info), sim_info->phonebook_type,
+                               sim_info->next_index, __ctsvc_server_sim_import_contact_cb, NULL);
+               if (TAPI_API_SUCCESS != ret) {
+                       CTS_ERR("tel_read_sim_pb_record() Failed(%d)", ret);
+                       ret = CONTACTS_ERROR_SYSTEM;
+                       goto ERROR_RETURN;
+               }
+       }
+       else {
+               // insert imported contact to DB
+               __ctsvc_server_sim_insert_records_to_db(info);
+               if (__ctsvc_server_sim_get_return_data()) {
+                       ret = ctsvc_server_socket_return(__ctsvc_server_sim_get_return_data(), CONTACTS_ERROR_NONE, 0, NULL);
+                       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_server_socket_return() Failed(%d)", ret);
+                       __ctsvc_server_sim_set_return_data(NULL);
+               }
+       }
+       return;
+
+ERROR_RETURN:
+       if (__ctsvc_server_sim_get_return_data()) {
+               ret = ctsvc_server_socket_return(__ctsvc_server_sim_get_return_data(), ret, 0, NULL);
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_server_socket_return() Failed(%d)", ret);
+               __ctsvc_server_sim_set_return_data(NULL);
+       }
+       return;
+}
+
+int ctsvc_server_sim_import_contact(void* data, int sim_slot_no)
+{
+       CTS_FN_CALL;
+       int ret;
+       ctsvc_sim_info_s *info;
+
+       info = __ctsvc_server_sim_get_handle_by_sim_slot_no(sim_slot_no);
+       RETVM_IF(NULL == info, CONTACTS_ERROR_SYSTEM, "sim init is not completed");
+       RETVM_IF(false == info->initialized, CONTACTS_ERROR_SYSTEM, "sim init is not completed");
+       RETVM_IF(NULL != __ctsvc_server_sim_get_return_data(), CONTACTS_ERROR_INTERNAL,
+                       "Server is already processing with sim");
+
+       __ctsvc_server_sim_set_return_data(data);
+
+       if (info->file_record[TAPI_PB_3G_NAME].used_count == 0) {
+               ret = ctsvc_server_socket_return(__ctsvc_server_sim_get_return_data(), CONTACTS_ERROR_NO_DATA, 0, NULL);
+               WARN_IF(CONTACTS_ERROR_SYSTEM != ret, "helper_socket_return() Failed(%d)", ret);
+               __ctsvc_server_sim_set_return_data(NULL);
+               return ret;
+       }
+
+       ret = tel_read_sim_pb_record(__ctsvc_server_sim_get_tapi_handle(info), info->sim_type, 1,
+                       __ctsvc_server_sim_import_contact_cb, NULL);
+       if (ret != TAPI_API_SUCCESS) {
+               CTS_ERR("tel_read_sim_pb_record = %d",ret);
+               __ctsvc_server_sim_set_return_data(NULL);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_server_socket_get_sim_init_status(void* data, int sim_slot_no)
+{
+       CTS_FN_CALL;
+       ctsvc_sim_info_s *info;
+
+       info = __ctsvc_server_sim_get_handle_by_sim_slot_no(sim_slot_no);
+       RETVM_IF(NULL == info, CONTACTS_ERROR_SYSTEM, "sim init is not completed");
+       return ctsvc_server_socket_return_sim_int(data, (int)(info->initialized));
+}
+
+static void __ctsvc_server_sim_sdn_read_cb(TapiHandle *handle, int result, void *data, void *user_data)
+{
+       CTS_FN_CALL;
+       int ret=0;
+       TelSimPbAccessResult_t sec_rt = result;
+       TelSimPbRecord_t *sim_info = data;
+       ctsvc_sim_info_s *info = (ctsvc_sim_info_s*)user_data;
+
+       RETM_IF(sim_info == NULL,  "sim_info is NULL");
+
+       if (TAPI_SIM_PB_SUCCESS != sec_rt) {
+               if (TAPI_SIM_PB_SDN == sim_info->phonebook_type &&
+                               TAPI_SIM_PB_INVALID_INDEX == sec_rt) {
+                       CTS_DBG("Index = %d", sim_info->index);
+                       ret = tel_read_sim_pb_record(handle, sim_info->phonebook_type, sim_info->index+1,
+                                       __ctsvc_server_sim_sdn_read_cb, info);
+                       RETM_IF(ret != TAPI_API_SUCCESS,  "tel_read_sim_pb_record() Failed(%d)", ret);
+               }
+               CTS_ERR("SIM phonebook access Failed(%d)", sec_rt);
+               goto ERROR_RETURN;
+       }
+
+       switch (sim_info->phonebook_type) {
+       case TAPI_SIM_PB_SDN:
+               ret = ctsvc_server_insert_sdn_contact((char *)sim_info->name, (char *)sim_info->number, info->sim_slot_no);
+               WARN_IF(ret != CONTACTS_ERROR_NONE, "ctsvc_server_insert_sdn_contact() Failed(%d)", ret);
+               break;
+       case TAPI_SIM_PB_ADN:
+       case TAPI_SIM_PB_3GSIM:
+       case TAPI_SIM_PB_FDN:
+       default:
+               CTS_ERR("Not SDN type(%d)", sim_info->phonebook_type);
+               goto ERROR_RETURN;
+       }
+
+       if (sim_info->next_index && CTSVC_TAPI_SIM_PB_MAX != sim_info->next_index) {
+               CTS_DBG("NextIndex = %d", sim_info->next_index);
+               ret = tel_read_sim_pb_record(handle, sim_info->phonebook_type,sim_info->next_index,
+                               __ctsvc_server_sim_sdn_read_cb, info);
+               if (TAPI_API_SUCCESS != ret) {
+                       CTS_ERR("tel_read_sim_pb_record() Failed(%d)", ret);
+                       goto ERROR_RETURN;
+               }
+       }
+       else {
+               ctsvc_server_trim_memory();
+       }
+       return;
+
+ERROR_RETURN:
+       ctsvc_server_trim_memory();
+
+       return;
+}
+
+static void __ctsvc_server_sim_sdn_meta_info_cb(TapiHandle *handle, int result, void *data, void *user_data)
+{
+       CTS_FN_CALL;
+       int ret = 0;
+       TelSimPbAccessResult_t sec_rt = result;
+       TelSimPbEntryInfo_t *pe = data;
+       ctsvc_sim_info_s *info = (ctsvc_sim_info_s*)user_data;
+
+       RETM_IF(TAPI_SIM_PB_SUCCESS != sec_rt, "TelSimPbAccessResult_t fail(%d)",sec_rt);
+       RETM_IF(pe == NULL, "pe is NULL result =%d",sec_rt);
+
+       if (pe->PbUsedCount > 0) {
+               ret = tel_read_sim_pb_record(info->handle, TAPI_SIM_PB_SDN, 1, __ctsvc_server_sim_sdn_read_cb, info);
+               if (TAPI_API_SUCCESS != ret) {
+                       CTS_ERR("tel_read_sim_pb_record() Failed(%d)", ret);
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+               CTS_ERR("pe->PbUsedCount : 0 no sdn!!!!", ret);
+
+ERROR_RETURN:
+       ctsvc_server_trim_memory();
+       return;
+}
+
+static int __ctsvc_server_sim_sdn_read(ctsvc_sim_info_s* info)
+{
+       CTS_FN_CALL;
+       int ret;
+       int card_changed = 0;
+       TelSimCardStatus_t sim_status;
+
+       RETVM_IF(NULL != __ctsvc_server_sim_get_return_data(), CONTACTS_ERROR_INTERNAL,
+                       "Server is already processing with sim");
+
+       ret = tel_get_sim_init_info(info->handle, &sim_status, &card_changed);
+       if(TAPI_API_SUCCESS != ret) {
+               CTS_ERR("tel_get_sim_init_info() Failed(%d)", ret);
+               CTS_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) {
+               ret = ctsvc_server_delete_sdn_contact(info->sim_slot_no);
+               if(CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_server_delete_sdn_contact() Failed(%d)", ret);
+                       goto ERROR_RETURN;
+               }
+       }
+       else if (TAPI_SIM_STATUS_SIM_INIT_COMPLETED == sim_status) {
+               ret = ctsvc_server_delete_sdn_contact(info->sim_slot_no);
+               if(CONTACTS_ERROR_NONE != ret) {
+                       CTS_ERR("ctsvc_server_delete_sdn_contact() Failed(%d)", ret);
+                       goto ERROR_RETURN;
+               }
+
+               ret = tel_get_sim_pb_meta_info(info->handle, TAPI_SIM_PB_SDN, __ctsvc_server_sim_sdn_meta_info_cb, info);
+               if (TAPI_API_SUCCESS != ret) {
+                       CTS_ERR("tel_get_sim_pb_meta_info() Failed(%d)", ret);
+                       goto ERROR_RETURN;
+               }
+       }
+       else
+               CTS_ERR("sim_status Failed(%d)", sim_status);
+
+       return CONTACTS_ERROR_NONE;
+
+ERROR_RETURN:
+       ctsvc_server_trim_memory();
+       return ret;
+}
+
+static void __ctsvc_server_sim_get_meta_info_cb(TapiHandle *handle, int result, void *data, void *user_data)
+{
+       CTS_FN_CALL;
+       int ret=0;
+       int i=0;
+       int type = TAPI_PB_3G_NAME;
+       TelSimPbAccessResult_t access_rt = result;
+       ctsvc_sim_info_s *info = (ctsvc_sim_info_s*)user_data;
+
+       CTS_DBG("sim slot id :%d, sim_type = %d", info->sim_slot_no, info->sim_type);
+       if (TAPI_SIM_PB_3GSIM == info->sim_type) {
+               TelSimPbCapabilityInfo_t *capa = data;
+               RETM_IF(capa == NULL, "capa is NULL result =%d",access_rt);
+
+               for (i=0; i < capa->FileTypeCount; i++) {
+                       type = capa->FileTypeInfo[i].field_type;
+
+                       info->file_record[type].support = true;
+                       info->file_record[type].index_max = capa->FileTypeInfo[i].index_max;
+                       info->file_record[type].text_max = capa->FileTypeInfo[i].text_max;
+                       info->file_record[type].used_count = capa->FileTypeInfo[i].used_count;
+
+                       INFO(" field_type[%d] : index_max(%d), text_max(%d), used_count(%d)", type,
+                                       info->file_record[type].index_max,
+                                       info->file_record[type].text_max,
+                                       info->file_record[type].used_count);
+               }
+       }
+       else if (TAPI_SIM_PB_ADN == info->sim_type) {
+               TelSimPbEntryInfo_t *pe = data;
+               RETM_IF(pe == NULL, "pe is NULL result =%d",access_rt);
+
+               info->file_record[CTSVC_2GSIM_NAME].support = true;
+               info->file_record[CTSVC_2GSIM_NAME].index_max = pe->PbIndexMax;
+               info->file_record[CTSVC_2GSIM_NAME].text_max = pe->PbTextLenMax;
+               info->file_record[CTSVC_2GSIM_NAME].used_count = pe->PbUsedCount;
+               CTS_DBG(" CTSVC_2GSIM_NAME : index_max(%d), text_max(%d), used_count(%d)",
+                               pe->PbIndexMax,pe->PbTextLenMax,pe->PbUsedCount);
+
+               info->file_record[CTSVC_2GSIM_NUMBER].support = true;
+               info->file_record[CTSVC_2GSIM_NUMBER].index_max = pe->PbIndexMax;
+               info->file_record[CTSVC_2GSIM_NUMBER].text_max = pe->PbNumLenMax;
+               info->file_record[CTSVC_2GSIM_NUMBER].used_count = pe->PbUsedCount;
+               CTS_DBG(" CTSVC_2GSIM_NUMBER : index_max(%d), text_max(%d), used_count(%d)",
+                               pe->PbIndexMax,pe->PbNumLenMax,pe->PbUsedCount);
+
+               INFO(" field_type[%d] : index_max(%d), text_max(%d), used_count(%d)", CTSVC_2GSIM_NAME,
+                               info->file_record[CTSVC_2GSIM_NAME].index_max,
+                               info->file_record[CTSVC_2GSIM_NAME].text_max,
+                               info->file_record[CTSVC_2GSIM_NAME].used_count);
+       }
+       else {
+               CTS_ERR("sim_type [%d]error ", info->sim_type);
+               return;
+       }
+
+       if (!info->initialized) {
+               info->initialized = true;
+               ret = __ctsvc_server_sim_sdn_read(info);
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "__ctsvc_server_sim_sdn_read() Failed(%d)", ret);
+       }
+
+       return;
+}
+
+static void __ctsvc_server_sim_get_iccid_cb(TapiHandle *handle, int result, void *data,void *user_data)
+{
+       TelSimAccessResult_t access_rt = result;
+       TelSimIccIdInfo_t *iccid = data;
+       ctsvc_sim_info_s *info = user_data;
+       int ret;
+       int id;
+
+       RETM_IF(access_rt != TAPI_SIM_ACCESS_SUCCESS, "tel_get_sim_iccid fail(%d)", access_rt);
+
+       CTS_DBG("%d, %s", iccid->icc_length, iccid->icc_num);
+
+       info->sim_unique_id = strdup(iccid->icc_num);
+
+       ret = ctsvc_server_get_sim_id(info->sim_unique_id, &id);
+       if (CONTACTS_ERROR_NONE == ret)
+               info->sim_info_id = id;
+}
+
+static int __ctsvc_server_sim_init_meta_info(ctsvc_sim_info_s *info)
+{
+       int ret = TAPI_API_SUCCESS;
+       int err = CONTACTS_ERROR_NONE;
+
+       if (info->sim_type == TAPI_SIM_PB_UNKNOWNN){
+               err = __ctsvc_server_sim_init_info(info);
+               WARN_IF(CONTACTS_ERROR_NONE != err, "__ctsvc_server_sim_init_info() Failed(%d)", err);
+       }
+
+       if (info->sim_type == TAPI_SIM_PB_3GSIM)
+               ret = tel_get_sim_pb_usim_meta_info(info->handle, __ctsvc_server_sim_get_meta_info_cb, info);
+       else if (info->sim_type == TAPI_SIM_PB_ADN)
+               ret = tel_get_sim_pb_meta_info(info->handle, info->sim_type, __ctsvc_server_sim_get_meta_info_cb, info);
+       else{
+               CTS_ERR("info->sim_type is invalid(%d) stop sim init !!!", info->sim_type);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       RETVM_IF(ret != TAPI_API_SUCCESS, CONTACTS_ERROR_SYSTEM,
+                               "tel_get_sim_(usim)_meta_info(type:%d) fail (%d)", info->sim_type, ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static int __ctsvc_server_sim_init_info(ctsvc_sim_info_s *info)
+{
+       CTS_FN_CALL;
+       int ret;
+       TelSimCardType_t cardtype = TAPI_SIM_PB_UNKNOWNN;
+
+       // get sim_type
+       ret = tel_get_sim_type(info->handle, &cardtype);
+       RETVM_IF(ret != TAPI_API_SUCCESS, CONTACTS_ERROR_SYSTEM, "tel_get_sim_type failed(%d)slot no(%d)", ret, info->sim_slot_no);
+       if (cardtype == TAPI_SIM_CARD_TYPE_USIM)
+               info->sim_type = TAPI_SIM_PB_3GSIM;
+       else if (cardtype == TAPI_SIM_CARD_TYPE_GSM)
+               info->sim_type = TAPI_SIM_PB_ADN;
+       else{
+               CTS_ERR("cardtype(%d)is invalid!!!", cardtype);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       // set iccid : unique info of SIM
+       ret = tel_get_sim_iccid (info->handle, __ctsvc_server_sim_get_iccid_cb, info);
+       RETVM_IF(ret != TAPI_API_SUCCESS, CONTACTS_ERROR_SYSTEM, "tel_get_sim_iccid failed(%d)", ret);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static void __ctsvc_server_sim_data_remove(ctsvc_sim_info_s *info)
+{
+       GSList *cursor;
+       sim_contact_s *record = NULL;
+
+       for (cursor=info->import_contacts;cursor;cursor=cursor->next) {
+               record = cursor->data;
+               info->import_contacts = g_slist_remove(info->import_contacts, record);
+               ctsvc_server_sim_record_destroy(record);
+       }
+       g_slist_free(info->import_contacts);
+       info->import_contacts = NULL;
+}
+
+static void __ctsvc_server_sim_noti_pb_status(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
+{
+       CTS_FN_CALL;
+       int ret = 0;
+       ctsvc_sim_info_s *info = (ctsvc_sim_info_s*)user_data;
+       TelSimPbStatus_t *pb_status = (TelSimPbStatus_t *)data;
+       RETM_IF(pb_status == NULL, "pb_status is null");
+       INFO("received pb status noti : b_3g[%d], b_adn[%d], b_fdn[%d]", pb_status->pb_list.b_3g, pb_status->pb_list.b_adn, pb_status->pb_list.b_fdn);
+
+       if (pb_status->pb_list.b_3g == 1 || pb_status->pb_list.b_adn == 1) {
+               if (info->initialized)
+                       return;
+               ret = __ctsvc_server_sim_init_meta_info(info);
+               WARN_IF(CONTACTS_ERROR_NONE != ret, "__ctsvc_server_sim_init_meta_info() Failed(%d)", ret);
+       }
+       // FDN on : can not import sim contacts
+       else if (pb_status->pb_list.b_fdn ==1 && pb_status->pb_list.b_adn == 0 && info->sim_type == TAPI_SIM_PB_ADN) {
+               CTS_INFO("This is sim card is 2G and FDN on status. sim phonebook will be block");
+               info->initialized = false;
+               __ctsvc_server_sim_data_remove(info);
+       }
+       else {
+               CTS_ERR("This noti did not control !!!");
+       }
+}
+
+static void __ctsvc_server_sim_noti_sim_refreshed(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
+{
+       CTS_FN_CALL;
+       ctsvc_sim_info_s *info = (ctsvc_sim_info_s*)user_data;
+
+       INFO("Recieved SIM Refresh event");
+       info->initialized = false;
+       __ctsvc_server_sim_data_remove(info);
+}
+
+static int __ctsvc_server_sim_info_init()
+{
+       int ret;
+       int sim_stat = -1;
+       TelSimPbList_t pb_list = {0,};
+       char **cp_name = NULL;
+       int i;
+       unsigned int cp_index = 0;
+
+       g_type_init();
+       cp_name = tel_get_cp_name_list();
+       RETVM_IF(cp_name == NULL, CONTACTS_ERROR_SYSTEM, "tel_get_cp_name_list fail (cp_name is NULL)");
+
+       ret = ctsvc_server_delete_sdn_contact(-1);
+       WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_server_delete_sdn_contact() Failed(%d)", ret);
+
+       while(cp_name[cp_index]){
+               cp_index++;
+       }
+
+       cp_index = 0;
+       while(cp_name[cp_index]) {
+               TapiHandle *handle;
+               ctsvc_sim_info_s *info = calloc(1, sizeof(ctsvc_sim_info_s));
+               if (NULL == info) {
+                       CTS_ERR("calloc() return NULL");
+                       break;
+               }
+               info->cp_name = strdup(cp_name[cp_index]);
+               INFO("SIM cp_name[%d] : %s", cp_index, info->cp_name);
+               info->sim_slot_no = cp_index;
+               info->sim_info_id = -1;
+               info->sim_type = TAPI_SIM_PB_UNKNOWNN;
+               info->initialized = false;
+               info->import_contacts = NULL;
+               info->sim_unique_id = NULL;
+
+               // initialize file_record meta info
+               for (i = 0 ;i <TAPI_PB_MAX_FILE_CNT; i++) {
+                       info->file_record[i].support = false;
+                       info->file_record[i].index_max = 0;
+                       info->file_record[i].text_max = 0;
+                       info->file_record[i].used_count = 0;
+               }
+
+               handle = __ctsvc_server_sim_get_tapi_handle(info);
+               if (handle) {
+                       ret = __ctsvc_server_sim_init_info(info);
+                       WARN_IF(CONTACTS_ERROR_NONE != ret, "__ctsvc_server_sim_init_info() Failed(%d)", ret);
+                       ret = tel_get_sim_pb_init_info(handle, &sim_stat, &pb_list);
+                       if (TAPI_API_SUCCESS == ret && (pb_list.b_3g == 1 || pb_list.b_adn == 1)) {
+                               ret = __ctsvc_server_sim_init_meta_info(info);
+                               WARN_IF(CONTACTS_ERROR_NONE != ret, "__ctsvc_server_sim_init_meta_info() Failed(%d)", ret);
+                       }
+
+                       ret = tel_register_noti_event(handle, TAPI_NOTI_PB_STATUS, __ctsvc_server_sim_noti_pb_status, info);
+                       WARN_IF( TAPI_API_SUCCESS != ret, "tel_register_noti_event() Failed(%d)", ret);
+
+                       ret = tel_register_noti_event(handle, TAPI_NOTI_SIM_REFRESHED, __ctsvc_server_sim_noti_sim_refreshed, info);
+                       WARN_IF( TAPI_API_SUCCESS != ret, "tel_register_noti_event() Failed(%d)", ret);
+               }
+               else {
+                       CTS_ERR("tel_init fail");
+               }
+
+               __ctsvc_sim_info = g_slist_append(__ctsvc_sim_info, (void*)info);
+               cp_index++;
+       }
+
+       g_strfreev(cp_name);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static void __ctsvc_server_sim_ready_cb(keynode_t *key, void *data)
+{
+       int status = 0;
+       vconf_get_int(VCONFKEY_TELEPHONY_SIM_STATUS, &status);
+
+       if (VCONFKEY_TELEPHONY_SIM_STATUS_INIT_COMPLETED != status) {
+               CTS_ERR("sim is not ready (%d)", status);
+               return;
+       }
+       INFO("sim is Ready");
+       __ctsvc_sim_cb = false;
+       vconf_ignore_key_changed(VCONFKEY_TELEPHONY_SIM_STATUS, __ctsvc_server_sim_ready_cb);
+
+       __ctsvc_server_sim_info_init();
+}
+
+static void __ctsvc_server_telephony_ready_cb(keynode_t *key, void *data)
+{
+       int bReady = 0;
+       // TODO: it should be changed API
+       vconf_get_bool(VCONFKEY_TELEPHONY_TAPI_STATE, &bReady);
+
+       if (!bReady) {
+               CTS_ERR("telephony is not ready ");
+               return;
+       }
+       INFO("telephony is Ready");
+
+       vconf_ignore_key_changed(VCONFKEY_TELEPHONY_TAPI_STATE, __ctsvc_server_telephony_ready_cb);
+       __ctsvc_tapi_cb = false;
+
+       int status = 0;
+       vconf_get_int(VCONFKEY_TELEPHONY_SIM_STATUS, &status);
+       if (VCONFKEY_TELEPHONY_SIM_STATUS_INIT_COMPLETED != status) {
+               CTS_ERR("sim is not ready (%d)", status);
+               vconf_notify_key_changed(VCONFKEY_TELEPHONY_SIM_STATUS, __ctsvc_server_sim_ready_cb, NULL);
+               __ctsvc_sim_cb = true;
+               return;
+       }
+
+       __ctsvc_server_sim_info_init();
+}
+
+
+int ctsvc_server_sim_init()
+{
+       int bReady = 0;
+       // TODO: it should be changed API
+       vconf_get_bool(VCONFKEY_TELEPHONY_TAPI_STATE, &bReady);
+
+       if (!bReady) {
+               CTS_ERR("telephony is not ready ");
+               vconf_notify_key_changed(VCONFKEY_TELEPHONY_TAPI_STATE, __ctsvc_server_telephony_ready_cb, NULL);
+               __ctsvc_tapi_cb = true;
+               return CONTACTS_ERROR_NONE;
+       }
+
+       int status = 0;
+       vconf_get_int(VCONFKEY_TELEPHONY_SIM_STATUS, &status);
+       if (VCONFKEY_TELEPHONY_SIM_STATUS_INIT_COMPLETED != status) {
+               CTS_ERR("sim is not ready (%d)", status);
+               vconf_notify_key_changed(VCONFKEY_TELEPHONY_SIM_STATUS, __ctsvc_server_sim_ready_cb, NULL);
+               __ctsvc_sim_cb = true;
+               return CONTACTS_ERROR_NONE;
+       }
+
+       return __ctsvc_server_sim_info_init();
+}
+
+int ctsvc_server_sim_final(void)
+{
+       CTS_FN_CALL;
+       GSList *info_cursor = NULL;
+       sim_contact_s *record = NULL;
+       int ret = 0;
+
+       if (__ctsvc_tapi_cb)
+               vconf_ignore_key_changed(VCONFKEY_TELEPHONY_TAPI_STATE, __ctsvc_server_telephony_ready_cb);
+       if (__ctsvc_sim_cb)
+               vconf_ignore_key_changed(VCONFKEY_TELEPHONY_SIM_STATUS, __ctsvc_server_sim_ready_cb);
+
+       for (info_cursor=__ctsvc_sim_info;info_cursor;info_cursor=info_cursor->next) {
+               ctsvc_sim_info_s *info = info_cursor->data;
+               GSList *cursor;
+               free(info->cp_name);
+               free(info->sim_unique_id);
+
+               if (info->handle) {
+                       ret = tel_deinit(info->handle);
+                       WARN_IF(TAPI_API_SUCCESS != ret, "tel_deinit() Failed(%d)", ret);
+               }
+
+               for (cursor=info->import_contacts;cursor;cursor=cursor->next) {
+                       record = cursor->data;
+                       info->import_contacts = g_slist_remove(info->import_contacts, record);
+                       ctsvc_server_sim_record_destroy(record);
+               }
+               g_slist_free(info->import_contacts);
+
+               free(info);
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/server/ctsvc_server_sim.h b/server/ctsvc_server_sim.h
new file mode 100755 (executable)
index 0000000..30a36d0
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_SERVER_SIM_H__
+#define __CTSVC_SERVER_SIM_H__
+
+#include <tapi_type.h>
+
+typedef struct {
+       int sim_index;
+       int contact_id;
+       int addressbook_id;
+       char *name;
+       char *number;
+       char *anr1;
+       char *anr2;
+       char *anr3;
+       char *email1;
+       char *email2;
+       char *email3;
+       char *email4;
+       char *nickname;
+}sim_contact_s;
+
+
+int ctsvc_server_sim_init(void);
+int ctsvc_server_sim_final(void);
+
+int ctsvc_server_sim_import_contact(void* data, int sim_slot_no);
+int ctsvc_server_sim_get_info_id_by_sim_slot_no(int sim_slot_no);
+int ctsvc_server_sim_get_sim_slot_no_by_info_id(int sim_info_id);
+int ctsvc_server_socket_get_sim_init_status(void* data, int sim_slot_no);
+
+#endif // __CTSVC_SERVER_SIM_H__
+
diff --git a/server/ctsvc_server_socket.c b/server/ctsvc_server_socket.c
new file mode 100644 (file)
index 0000000..57fc694
--- /dev/null
@@ -0,0 +1,350 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <unistd.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <security-server.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+#include "ctsvc_struct.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_socket.h"
+#include "ctsvc_server_socket.h"
+#ifdef ENABLE_SIM_FEATURE
+#include "ctsvc_server_sim.h"
+#include "ctsvc_server_utils.h"
+#endif
+
+static int sockfd = -1;
+
+static inline int __ctsvc_server_socket_safe_write(int fd, char *buf, int buf_size)
+{
+       int ret, writed = 0;
+       while (buf_size) {
+               ret = write(fd, buf+writed, buf_size);
+               if (-1 == ret) {
+                       if (EINTR == errno)
+                               continue;
+                       else
+                               return ret;
+               }
+               writed += ret;
+               buf_size -= ret;
+       }
+       return writed;
+}
+
+
+static inline int __ctsvc_server_socket_safe_read(int fd, char *buf, int buf_size)
+{
+       int ret, read_size = 0;
+       while (buf_size) {
+               ret = read(fd, buf+read_size, buf_size);
+               if (-1 == ret) {
+                       if (EINTR == errno)
+                               continue;
+                       else
+                               return ret;
+               }
+               read_size += ret;
+               buf_size -= ret;
+       }
+       return read_size;
+}
+
+int ctsvc_server_socket_return(GIOChannel *src, int value, int attach_num, int *attach_size)
+{
+       CTS_FN_CALL;
+       int ret;
+       ctsvc_socket_msg_s msg = {0};
+
+       //      RETVM_IF(CONTACTS_ERROR_SYSTEM == value, value, "Socket has problems");
+       RETVM_IF(CTSVC_SOCKET_MSG_REQUEST_MAX_ATTACH < attach_num, CONTACTS_ERROR_INTERNAL,
+                       "Invalid msg(attach_num = %d)", attach_num);
+
+       msg.type = CTSVC_SOCKET_MSG_TYPE_REQUEST_RETURN_VALUE;
+       msg.val = value;
+       msg.attach_num = attach_num;
+
+       memcpy(msg.attach_sizes, attach_size, attach_num * sizeof(int));
+
+       CTS_DBG("fd = %d, MSG_TYPE=%d, MSG_VAL=%d, MSG_ATTACH_NUM=%d,"
+                       "MSG_ATTACH1=%d, MSG_ATTACH2=%d, MSG_ATTACH3=%d, MSG_ATTACH4=%d",
+                       g_io_channel_unix_get_fd(src), msg.type, msg.val, msg.attach_num,
+                       msg.attach_sizes[0], msg.attach_sizes[1], msg.attach_sizes[2],
+                       msg.attach_sizes[3]);
+
+       ret = __ctsvc_server_socket_safe_write(g_io_channel_unix_get_fd(src), (char *)&msg, sizeof(msg));
+       RETVM_IF(-1 == ret, CONTACTS_ERROR_SYSTEM,
+                       "__ctsvc_server_socket_safe_write() Failed(errno = %d)", errno);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+#ifdef ENABLE_SIM_FEATURE
+static void __ctsvc_server_socket_import_sim(GIOChannel *src, int size)
+{
+       CTS_FN_CALL;
+       int ret;
+       gsize len = 0;
+       GError *gerr = NULL;
+       char receiver[CTS_SQL_MAX_LEN] = {0};
+
+       if (size > 0) {
+               g_io_channel_read_chars(src, receiver, size, &len, &gerr);
+               if (gerr) {
+                       CTS_ERR("g_io_channel_read_chars() Failed(%s)", gerr->message);
+                       g_error_free(gerr);
+                       return;
+               }
+               CTS_DBG("Receiver = %s(%d), read_size = %d", receiver, len, size);
+       }
+
+       if (len) {
+               receiver[len] = '\0';
+               CTS_DBG("sim_id %d", atoi(receiver));
+               ret = ctsvc_server_sim_import_contact(src, atoi(receiver));
+       }
+       else {
+               ret = ctsvc_server_sim_import_contact(src, 0);
+       }
+
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_server_sim_import_contact() Failed(%d)", ret);
+               ctsvc_server_socket_return(src, ret, 0, NULL);
+       }
+}
+
+static void __ctsvc_server_socket_get_sim_init_status(GIOChannel *src, int size)
+{
+       CTS_FN_CALL;
+
+       int ret;
+       gsize len = 0;
+       GError *gerr = NULL;
+       char receiver[CTS_SQL_MAX_LEN] = {0};
+
+       if (size > 0) {
+               g_io_channel_read_chars(src, receiver, size, &len, &gerr);
+               if (gerr) {
+                       CTS_ERR("g_io_channel_read_chars() Failed(%s)", gerr->message);
+                       g_error_free(gerr);
+                       return;
+               }
+               CTS_DBG("Receiver = %s(%d), read_size = %d", receiver, len, size);
+       }
+
+       if (len) {
+               receiver[len] = '\0';
+               CTS_DBG("sim_id : %d", atoi(receiver));
+               ret = ctsvc_server_socket_get_sim_init_status(src, atoi(receiver));
+       }
+       else {
+               ret = ctsvc_server_socket_get_sim_init_status(src, 0);
+       }
+
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_server_socket_get_sim_init_status() Failed(%d)", ret);
+               ctsvc_server_socket_return(src, ret, 0, NULL);
+       }
+}
+
+int ctsvc_server_socket_return_sim_int(GIOChannel *src, int value)
+{
+       CTS_FN_CALL;
+       int ret;
+       int str_len;
+       char count_str[CTS_SQL_MAX_LEN] = {0};
+
+       str_len = snprintf(count_str, sizeof(count_str), "%d", value);
+       ret = ctsvc_server_socket_return(src, CONTACTS_ERROR_NONE, 1, &str_len);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_server_socket_return() Failed(%d)", ret);
+       CTS_DBG("count_str : %s", count_str);
+       ret = __ctsvc_server_socket_safe_write(g_io_channel_unix_get_fd(src), count_str, str_len);
+       RETVM_IF(-1 == ret, CONTACTS_ERROR_SYSTEM, "__ctsvc_server_socket_safe_write() Failed(errno = %d)", errno);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+static void __ctsvc_server_socket_read_flush(GIOChannel *src, int size)
+{
+       gsize len;
+       GError *gerr = NULL;
+       char receiver[CTS_SQL_MAX_LEN] = {0};
+
+       if (size <= 0)
+               return;
+
+       g_io_channel_read_chars(src, receiver, size, &len, &gerr);
+       if (gerr) {
+               CTS_ERR("g_io_channel_read_chars() Failed(%s)", gerr->message);
+               g_error_free(gerr);
+       }
+}
+#endif // ENABLIE_SIM_FEATURE
+
+static gboolean __ctsvc_server_socket_request_handler(GIOChannel *src, GIOCondition condition,
+               gpointer data)
+{
+       int ret;
+       int fd;
+#ifdef ENABLE_SIM_FEATURE
+       bool have_read_permission = false;
+       bool have_write_permission = false;
+       bool have_telephony_feature = false;
+#endif // ENABLE_SIM_FEATURE
+
+       ctsvc_socket_msg_s msg = {0};
+       CTS_FN_CALL;
+
+       if (G_IO_HUP & condition) {
+               close(g_io_channel_unix_get_fd(src));
+               return FALSE;
+       }
+
+       fd = g_io_channel_unix_get_fd(src);
+       ret = __ctsvc_server_socket_safe_read(fd, (char *)&msg, sizeof(msg));
+       RETVM_IF(-1 == ret, TRUE, "__ctsvc_server_socket_safe_read() Failed(errno = %d)", errno);
+
+       CTS_DBG("attach number = %d", msg.attach_num);
+
+
+
+#ifdef ENABLE_SIM_FEATURE
+       have_telephony_feature = ctsvc_server_have_telephony_feature();
+       if (!have_telephony_feature) {
+               CTS_ERR("Telephony feature disabled");
+               __ctsvc_server_socket_read_flush(src, msg.attach_sizes[0]);     // sim_id
+               ctsvc_server_socket_return(src, CONTACTS_ERROR_NOT_SUPPORTED, 0, NULL);
+               return TRUE;
+       }
+
+       if (SECURITY_SERVER_API_SUCCESS == (ret = security_server_check_privilege_by_sockfd(fd, "contacts-service::svc", "r")))
+               have_read_permission = true;
+       else
+               INFO("fd(%d) : does not have contact read permission (%d)", fd, ret);
+
+       if (SECURITY_SERVER_API_SUCCESS == (ret = security_server_check_privilege_by_sockfd(fd, "contacts-service::svc", "w")))
+               have_write_permission = true;
+       else
+               INFO("fd(%d) : does not have contact write permission (%d)", fd, ret);
+#endif // ENABLE_SIM_FEATURE
+
+       switch (msg.type) {
+#ifdef ENABLE_SIM_FEATURE
+       case CTSVC_SOCKET_MSG_TYPE_REQUEST_IMPORT_SIM:
+               if (!have_write_permission) {
+                       CTS_ERR("write permission denied");
+                       __ctsvc_server_socket_read_flush(src, msg.attach_sizes[0]);             // sim_id
+                       ctsvc_server_socket_return(src, CONTACTS_ERROR_PERMISSION_DENIED, 0, NULL);
+                       return TRUE;
+               }
+               __ctsvc_server_socket_import_sim(src, msg.attach_sizes[0]);
+               break;
+       case CTSVC_SOCKET_MSG_TYPE_REQUEST_SIM_INIT_COMPLETE:
+               if (!have_read_permission) {
+                       CTS_ERR("read permission denied");
+                       __ctsvc_server_socket_read_flush(src, msg.attach_sizes[0]);             // sim_id
+                       ctsvc_server_socket_return(src, CONTACTS_ERROR_PERMISSION_DENIED, 0, NULL);
+                       return TRUE;
+               }
+               __ctsvc_server_socket_get_sim_init_status(src, msg.attach_sizes[0]);
+               break;
+#endif // ENABLE_SIM_FEATURE
+       default:
+               CTS_ERR("Unknown request type(%d)", msg.type);
+               break;
+       }
+       return TRUE;
+}
+
+static gboolean __ctsvc_server_socket_handler(GIOChannel *src,
+               GIOCondition condition, gpointer data)
+{
+       CTS_FN_CALL;
+
+       GIOChannel *channel;
+       int client_sockfd, sockfd = (int)data;
+       struct sockaddr_un clientaddr;
+       socklen_t client_len = sizeof(clientaddr);
+
+       client_sockfd = accept(sockfd, (struct sockaddr *)&clientaddr, &client_len);
+       RETVM_IF(-1 == client_sockfd, TRUE, "accept() Failed(errno = %d)", errno);
+
+       channel = g_io_channel_unix_new(client_sockfd);
+       g_io_add_watch(channel, G_IO_IN|G_IO_HUP, __ctsvc_server_socket_request_handler, NULL);
+       g_io_channel_unref(channel);
+
+       return TRUE;
+}
+
+int ctsvc_server_socket_init(void)
+{
+       CTS_FN_CALL;
+
+       int ret;
+       struct sockaddr_un addr;
+       GIOChannel *gio;
+
+       unlink(CTSVC_SOCKET_PATH);
+
+       bzero(&addr, sizeof(addr));
+       addr.sun_family = AF_UNIX;
+       snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", CTSVC_SOCKET_PATH);
+
+       sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
+       RETVM_IF(-1 == sockfd, CONTACTS_ERROR_SYSTEM, "socket() Failed(errno = %d)", errno);
+
+       ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
+       RETVM_IF(-1 == ret, CONTACTS_ERROR_SYSTEM, "bind() Failed(errno = %d)", errno);
+
+       ret = chown(CTSVC_SOCKET_PATH, getuid(), CTS_SECURITY_FILE_GROUP);
+       if (0 != ret)
+               CTS_ERR("chown(%s) Failed(%d)", CTSVC_SOCKET_PATH, ret);
+
+       ret = chmod(CTSVC_SOCKET_PATH, CTS_SECURITY_DEFAULT_PERMISSION);
+       if (0 != ret)
+               CTS_ERR("chmod(%s) Failed(%d)", CTSVC_SOCKET_PATH, ret);
+
+       ret = listen(sockfd, 30);
+       if (-1 == ret) {
+               close(sockfd);
+               CTS_ERR("listen() Failed(errno = %d)", errno);
+               return CONTACTS_ERROR_SYSTEM;
+       }
+
+       gio = g_io_channel_unix_new(sockfd);
+       g_io_add_watch(gio, G_IO_IN, __ctsvc_server_socket_handler, (gpointer)sockfd);
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_server_socket_deinit(void)
+{
+       if (sockfd != -1)
+               close(sockfd);
+       return CONTACTS_ERROR_NONE;
+}
diff --git a/server/ctsvc_server_socket.h b/server/ctsvc_server_socket.h
new file mode 100644 (file)
index 0000000..e623679
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_SERVER_SOCKET_H__
+#define __CTSVC_SERVER_SOCKET_H__
+
+#include <glib.h>
+
+int ctsvc_server_socket_init(void);
+int ctsvc_server_socket_deinit(void);
+int ctsvc_server_socket_return(GIOChannel *src, int value, int attach_num, int *attach_size);
+int ctsvc_server_socket_return_sim_int(GIOChannel *src, int value);
+
+#endif // __CTSVC_SERVER_SOCKET_H__
diff --git a/server/ctsvc_server_sqlite.c b/server/ctsvc_server_sqlite.c
new file mode 100755 (executable)
index 0000000..6009f48
--- /dev/null
@@ -0,0 +1,738 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <unistd.h>
+#include <string.h>
+#include <db-util.h>
+#include <fcntl.h>
+
+#include "ctsvc_internal.h"
+#include "contacts.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_notify.h"
+#include "ctsvc_setting.h"
+#include "ctsvc_normalize.h"
+#include "ctsvc_localize.h"
+#include "ctsvc_localize_utils.h"
+#include "ctsvc_localize_ch.h"
+#include "ctsvc_server_utils.h"
+#include "ctsvc_number_utils.h"
+#include "ctsvc_server_change_subject.h"
+
+#include "ctsvc_notification.h"
+#include "ctsvc_db_query.h"
+#include "ctsvc_db_plugin_image_helper.h"
+#include "ctsvc_db_plugin_company_helper.h"
+#include "ctsvc_db_plugin_group_helper.h"
+#include "ctsvc_db_plugin_contact_helper.h"
+
+#include "ctsvc_person.h"
+
+#ifdef ENABLE_LOG_FEATURE
+#include "ctsvc_phonelog.h"
+#endif // ENABLE_LOG_FEATURE
+
+static sqlite3 *server_db;
+
+int ctsvc_server_db_open(sqlite3 **db)
+{
+       CTS_FN_CALL;
+       int ret;
+
+       if (!server_db) {
+               ret = db_util_open(CTSVC_DB_PATH, &server_db, 0);
+               RETVM_IF(ret != SQLITE_OK, CONTACTS_ERROR_DB,
+                               "db_util_open() Failed(%d)", ret);
+
+               ret = sqlite3_create_function(server_db, "_DATA_DELETE_", 2, SQLITE_UTF8, NULL,
+                                       ctsvc_db_data_delete_callback, NULL, NULL);
+               RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB,
+                                               "sqlite3_create_function() Failed(%d)", ret);
+               ret = sqlite3_create_function(server_db, "_DATA_IMAGE_DELETE_", 1, SQLITE_UTF8, NULL,
+                                       ctsvc_db_image_delete_callback, NULL, NULL);
+               RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB,
+                                               "sqlite3_create_function() Failed(%d)", ret);
+               ret = sqlite3_create_function(server_db, "_DATA_COMPANY_DELETE_", 1, SQLITE_UTF8, NULL,
+                                       ctsvc_db_company_delete_callback, NULL, NULL);
+               RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB,
+                                               "sqlite3_create_function() Failed(%d)", ret);
+#ifdef ENABLE_LOG_FEATURE
+               ret = sqlite3_create_function(server_db, "_PHONE_LOG_DELETE_", 1, SQLITE_UTF8, NULL,
+                                       ctsvc_db_phone_log_delete_callback, NULL, NULL);
+               RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB,
+                                               "sqlite3_create_function() Failed(%d)", ret);
+#endif // ENABLE_LOG_FEATURE
+               ret = sqlite3_create_function(server_db, "_PERSON_DELETE_", 1, SQLITE_UTF8, NULL,
+                                       ctsvc_db_person_delete_callback, NULL, NULL);
+               RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB,
+                                               "sqlite3_create_function() Failed(%d)", ret);
+               ret = sqlite3_create_function(server_db, "_GROUP_DELETE_", 1, SQLITE_UTF8, NULL,
+                                       ctsvc_db_group_delete_callback, NULL, NULL);
+               RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB,
+                                               "sqlite3_create_function() Failed(%d)", ret);
+               ret = sqlite3_create_function(server_db, "_NUMBER_COMPARE_", 4, SQLITE_UTF8, NULL,
+                                       ctsvc_db_phone_number_equal_callback, NULL, NULL);
+               RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB,
+                                               "sqlite3_create_function() Failed(%d)", ret);
+       }
+       if (db)
+               *db = server_db;
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_server_db_close(void)
+{
+       if (server_db) {
+               db_util_close(server_db);
+               server_db = NULL;
+       }
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_server_begin_trans(void)
+{
+       int ret = -1;
+
+       ret = sqlite3_exec(server_db, "BEGIN IMMEDIATE TRANSACTION",
+                       NULL, NULL, NULL);
+
+       while (SQLITE_BUSY == ret) {
+               sleep(1);
+               ret = sqlite3_exec(server_db, "BEGIN IMMEDIATE TRANSACTION",
+                               NULL, NULL, NULL);
+       }
+
+       if (SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_exec() Failed(%d)", ret);
+               return CONTACTS_ERROR_DB;
+       }
+       return CONTACTS_ERROR_NONE;
+}
+
+#define CTS_COMMIT_TRY_MAX 5
+int ctsvc_server_end_trans(bool success)
+{
+       int ret = -1, i=0;
+       char *errmsg = NULL;
+
+       if (success) {
+               do {
+                       ret = sqlite3_exec(server_db, "COMMIT TRANSACTION",
+                                       NULL, NULL, &errmsg);
+                       if (SQLITE_OK != ret) {
+                               CTS_ERR("sqlite3_exec(COMMIT) Failed(%d, %s)", ret, errmsg);
+                               sqlite3_free(errmsg);
+                               i++;
+                               sleep(1);
+                       }
+                       else {
+                               INFO("commit end");
+                               return CONTACTS_ERROR_NONE;
+                       }
+               } while ((SQLITE_BUSY == ret || SQLITE_LOCKED == ret) && i < CTS_COMMIT_TRY_MAX);
+
+               CTS_ERR("Commit error : %d", ret);
+       }
+
+       i = 0;
+       do {
+               ret = sqlite3_exec(server_db, "ROLLBACK TRANSACTION",
+                               NULL, NULL, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("sqlite3_exec(ROLLBACK) Failed(%d, %s)", ret, errmsg);
+                       sqlite3_free(errmsg);
+                       i++;
+                       sleep(1);
+               }
+       } while ((SQLITE_BUSY == ret || SQLITE_LOCKED == ret) && i < CTS_COMMIT_TRY_MAX);
+
+       if (SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_exec(ROLLBACK) Failed(%d) : DB lock", ret);
+               return CONTACTS_ERROR_DB;
+       }
+       else {
+               INFO("rollback end");
+               return CONTACTS_ERROR_NONE;
+       }
+}
+
+int ctsvc_server_update_sort(int prev_sort_primary, int prev_sort_secondary, int new_sort_primary, int new_sort_secondary)
+{
+       CTS_FN_CALL;
+       int ret;
+       sqlite3* db = NULL;
+       char *errmsg = NULL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       ret = ctsvc_server_db_open(&db);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_server_db_open() Failed(%d)", ret);
+
+       ret = ctsvc_server_begin_trans();
+       RETVM_IF(ret, ret, "ctsvc_server_begin_trans() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query), "UPDATE %s SET display_name_language=%d WHERE display_name_language =%d",
+                       CTS_TABLE_CONTACTS, prev_sort_primary, CTSVC_SORT_PRIMARY);
+       ret = sqlite3_exec(db, query, NULL, NULL, &errmsg);
+       if (SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_exec(%s) Failed(%d, %s)", query, ret, errmsg);
+               sqlite3_free(errmsg);
+               ctsvc_server_end_trans(false);
+               ctsvc_server_db_close();
+               return CONTACTS_ERROR_DB;
+       }
+
+       snprintf(query, sizeof(query), "UPDATE %s SET display_name_language=%d WHERE display_name_language = %d",
+                       CTS_TABLE_CONTACTS, prev_sort_secondary, CTSVC_SORT_SECONDARY);
+       ret = sqlite3_exec(db, query, NULL, NULL, &errmsg);
+       if (SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_exec(%s) Failed(%d, %s)", query, ret, errmsg);
+               sqlite3_free(errmsg);
+               ctsvc_server_end_trans(false);
+               ctsvc_server_db_close();
+               return CONTACTS_ERROR_DB;
+       }
+
+       snprintf(query, sizeof(query), "UPDATE %s SET display_name_language=%d WHERE display_name_language=%d",
+                               CTS_TABLE_CONTACTS, CTSVC_SORT_PRIMARY, new_sort_primary);
+       ret = sqlite3_exec(db, query, NULL, NULL, &errmsg);
+       if (SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_exec(%s) Failed(%d, %s)", query, ret, errmsg);
+               sqlite3_free(errmsg);
+               ctsvc_server_end_trans(false);
+               ctsvc_server_db_close();
+               return CONTACTS_ERROR_DB;
+       }
+
+       snprintf(query, sizeof(query), "UPDATE %s SET display_name_language=%d WHERE display_name_language =%d",
+                       CTS_TABLE_CONTACTS, CTSVC_SORT_SECONDARY, new_sort_secondary);
+       ret = sqlite3_exec(db, query, NULL, NULL, &errmsg);
+       if (SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_exec(%s) Failed(%d, %s)", query, ret, errmsg);
+               sqlite3_free(errmsg);
+               ctsvc_server_end_trans(false);
+               ctsvc_server_db_close();
+               return CONTACTS_ERROR_DB;
+       }
+
+       snprintf(query, sizeof(query), "UPDATE %s SET reverse_display_name_language=%d WHERE reverse_display_name_language = %d",
+                               CTS_TABLE_CONTACTS, prev_sort_primary, CTSVC_SORT_PRIMARY);
+       ret = sqlite3_exec(db, query, NULL, NULL, &errmsg);
+       if (SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_exec(%s) Failed(%d, %s)", query, ret, errmsg);
+               sqlite3_free(errmsg);
+               ctsvc_server_end_trans(false);
+               ctsvc_server_db_close();
+               return CONTACTS_ERROR_DB;
+       }
+
+       snprintf(query, sizeof(query), "UPDATE %s SET reverse_display_name_language=%d WHERE reverse_display_name_language = %d",
+                       CTS_TABLE_CONTACTS, prev_sort_secondary, CTSVC_SORT_SECONDARY);
+       ret = sqlite3_exec(db, query, NULL, NULL, &errmsg);
+       if (SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_exec(%s) Failed(%d, %s)", query, ret, errmsg);
+               sqlite3_free(errmsg);
+               ctsvc_server_end_trans(false);
+               ctsvc_server_db_close();
+               return CONTACTS_ERROR_DB;
+       }
+
+       snprintf(query, sizeof(query), "UPDATE %s SET reverse_display_name_language=%d WHERE reverse_display_name_language = %d",
+                               CTS_TABLE_CONTACTS, CTSVC_SORT_PRIMARY, new_sort_primary);
+       ret = sqlite3_exec(db, query, NULL, NULL, &errmsg);
+       if (SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_exec(%s) Failed(%d, %s)", query, ret, errmsg);
+               sqlite3_free(errmsg);
+               ctsvc_server_end_trans(false);
+               ctsvc_server_db_close();
+               return CONTACTS_ERROR_DB;
+       }
+
+       snprintf(query, sizeof(query), "UPDATE %s SET reverse_display_name_language=%d WHERE reverse_display_name_language = %d",
+                       CTS_TABLE_CONTACTS, CTSVC_SORT_SECONDARY, new_sort_secondary);
+       ret = sqlite3_exec(db, query, NULL, NULL, &errmsg);
+       if (SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_exec(%s) Failed(%d, %s)", query, ret, errmsg);
+               sqlite3_free(errmsg);
+               ctsvc_server_end_trans(false);
+               ctsvc_server_db_close();
+               return CONTACTS_ERROR_DB;
+       }
+
+       ret = ctsvc_server_set_default_sort(new_sort_primary);
+       if (CONTACTS_ERROR_NONE != ret) {
+               ctsvc_server_end_trans(false);
+               ctsvc_server_db_close();
+               return ret;
+       }
+       ret = ctsvc_server_end_trans(true);
+
+       // person noti
+#if 0
+       if (CONTACTS_ERROR_NONE == ret) {
+               int fd = open(CTSVC_NOTI_PERSON_CHANGED, O_TRUNC | O_RDWR);
+               if (0 <= fd)
+                       close(fd);
+       }
+#endif
+       ctsvc_server_db_close();
+
+       return ret;
+}
+
+int ctsvc_server_insert_sdn_contact(const char *name, const char *number,
+               int sim_slot_no)
+{
+       int ret;
+       sqlite3* db = NULL;
+       sqlite3_stmt* stmt = NULL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       ret = ctsvc_server_db_open(&db);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_server_db_open() Failed(%d)", ret);
+
+       snprintf(query, sizeof(query), "INSERT INTO %s(name, number, sim_slot_no) VALUES(?, ?, ?)",
+                       CTS_TABLE_SDN);
+
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if(SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_prepare_v2(%s) Failed(%s)", query, sqlite3_errmsg(db));
+               ctsvc_server_db_close();
+               return CONTACTS_ERROR_DB;
+       }
+
+       sqlite3_bind_text(stmt, 1, name, strlen(name), SQLITE_STATIC);
+       sqlite3_bind_text(stmt, 2, number, strlen(number), SQLITE_STATIC);
+       sqlite3_bind_int(stmt, 3, sim_slot_no);
+
+       ret = sqlite3_step(stmt);
+       if (SQLITE_DONE != ret) {
+               CTS_ERR("sqlite3_step() Failed(%d)", ret);
+               sqlite3_finalize(stmt);
+               ctsvc_server_db_close();
+               return CONTACTS_ERROR_DB;
+       }
+       sqlite3_finalize(stmt);
+       ctsvc_server_db_close();
+
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_server_delete_sdn_contact(int sim_slot_no)
+{
+       int ret;
+       sqlite3* db = NULL;
+       sqlite3_stmt* stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       ret = ctsvc_server_db_open(&db);
+       RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "helper_db_open() Failed(%d)", ret);
+
+       if (sim_slot_no < 0)
+               snprintf(query, sizeof(query), "DELETE FROM %s", CTS_TABLE_SDN);
+       else
+               snprintf(query, sizeof(query), "DELETE FROM %s WHERE sim_slot_no = %d", CTS_TABLE_SDN, sim_slot_no);
+
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if(SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_prepare_v2(%s) Failed(%s)", query, sqlite3_errmsg(db));
+               ctsvc_server_db_close();
+               return CONTACTS_ERROR_DB;
+       }
+       ret = sqlite3_step(stmt);
+       if (SQLITE_DONE != ret) {
+               CTS_ERR("sqlite3_step() Failed(%d)", ret);
+               sqlite3_finalize(stmt);
+               ctsvc_server_db_close();
+               return CONTACTS_ERROR_DB;
+       }
+       sqlite3_finalize(stmt);
+
+       ctsvc_server_db_close();
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_server_update_collation()
+{
+       int ret = 0;
+       sqlite3* db = NULL;
+       cts_stmt stmt = NULL;
+       cts_stmt update_stmt = NULL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       ctsvc_db_set_status(CONTACTS_DB_STATUS_CHANGING_COLLATION);
+
+       ret = ctsvc_server_db_open(&db);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_server_db_open() Failed(%d)", ret);
+               ctsvc_db_set_status(CONTACTS_DB_STATUS_NORMAL);
+               return ret;
+       }
+
+       ret = ctsvc_server_begin_trans();
+       if(CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_server_begin_trans() Failed(%d)", ret);
+               ctsvc_server_db_close();
+               ctsvc_db_set_status(CONTACTS_DB_STATUS_NORMAL);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id, sort_name, reverse_sort_name "
+                               "FROM "CTS_TABLE_CONTACTS" WHERE deleted = 0");
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if(SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_prepare_v2(%s) Failed(%s)", query, sqlite3_errmsg(db));
+               ctsvc_server_end_trans(false);
+               ctsvc_server_db_close();
+               ctsvc_db_set_status(CONTACTS_DB_STATUS_NORMAL);
+               return CONTACTS_ERROR_DB;
+       }
+
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_CONTACTS" SET sortkey=?, reverse_sortkey=? "
+                               "WHERE contact_id = ?");
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &update_stmt, NULL);
+       if(SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_prepare_v2(%s) Failed(%s)", query, sqlite3_errmsg(db));
+               sqlite3_finalize(stmt);
+               ctsvc_server_end_trans(false);
+               ctsvc_server_db_close();
+               ctsvc_db_set_status(CONTACTS_DB_STATUS_NORMAL);
+               return CONTACTS_ERROR_DB;
+       }
+
+       while (SQLITE_ROW == (ret = sqlite3_step(stmt))) {
+               int contact_id = sqlite3_column_int(stmt, 0);
+               char *sort_name = (char*)sqlite3_column_text(stmt, 1);
+               char *reverse_sort_name = (char*)sqlite3_column_text(stmt, 2);
+               char *sortkey = NULL;
+               char *reverse_sortkey = NULL;
+
+               if (sort_name) {
+                       ret = ctsvc_collation_str(sort_name, &sortkey);
+                       if (CONTACTS_ERROR_NONE == ret && sortkey)
+                               sqlite3_bind_text(update_stmt, 1, sortkey, strlen(sortkey), SQLITE_STATIC);
+               }
+
+               if (reverse_sort_name) {
+                       ret = ctsvc_collation_str(reverse_sort_name, &reverse_sortkey);
+                       if (CONTACTS_ERROR_NONE == ret && reverse_sortkey)
+                               sqlite3_bind_text(update_stmt, 2, reverse_sortkey, strlen(reverse_sortkey), SQLITE_STATIC);
+               }
+
+               sqlite3_bind_int(update_stmt, 3, contact_id);
+
+               ret = sqlite3_step(update_stmt);
+
+               free(sortkey);
+               free(reverse_sortkey);
+
+               if (SQLITE_DONE != ret) {
+                       CTS_ERR("sqlite3_step(%s) Failed(%d, %s)", query, ret, sqlite3_errmsg(db));
+                       sqlite3_finalize(stmt);
+                       sqlite3_finalize(update_stmt);
+                       ctsvc_server_end_trans(false);
+                       ctsvc_server_db_close();
+                       ctsvc_db_set_status(CONTACTS_DB_STATUS_NORMAL);
+                       return CONTACTS_ERROR_DB;
+               }
+
+               sqlite3_reset(update_stmt);
+
+       }
+
+       if (SQLITE_ROW != ret && SQLITE_DONE != ret) {
+               CTS_ERR("sqlite3_step() Failed(%d)", ret);
+               sqlite3_finalize(update_stmt);
+               sqlite3_finalize(stmt);
+               ctsvc_server_end_trans(false);
+               ctsvc_server_db_close();
+               ctsvc_db_set_status(CONTACTS_DB_STATUS_NORMAL);
+               return CONTACTS_ERROR_DB;
+       }
+
+       sqlite3_finalize(update_stmt);
+       sqlite3_finalize(stmt);
+
+       ret = ctsvc_server_end_trans(true);
+       if (CONTACTS_ERROR_NONE == ret) {
+               int fd;
+               fd = open(CTSVC_NOTI_CONTACT_CHANGED, O_TRUNC | O_RDWR);
+               if (0 <= fd)
+                       close(fd);
+               fd = open(CTSVC_NOTI_PERSON_CHANGED, O_TRUNC | O_RDWR);
+               if (0 <= fd)
+                       close(fd);
+       }
+       ctsvc_server_db_close();
+
+       ctsvc_db_set_status(CONTACTS_DB_STATUS_NORMAL);
+
+       return ret;
+}
+
+int ctsvc_server_get_sim_id(const char *unique_id, int *sim_id)
+{
+       int ret;
+       int id;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       *sim_id = 0;
+       RETVM_IF(unique_id == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "unique_id is NULL");
+
+       snprintf(query, sizeof(query),
+                               "SELECT sim_id FROM "CTS_TABLE_SIM_INFO" "
+                                                               "WHERE unique_id = '%s'", unique_id);
+       ret = ctsvc_query_get_first_int_result(query, &id);
+       if (CONTACTS_ERROR_NONE != ret && CONTACTS_ERROR_NO_DATA != ret) {
+               CTS_ERR("ctsvc_query_get_first_int_result() Failed(%d)", ret);
+               return ret;
+       }
+
+       if (CONTACTS_ERROR_NO_DATA == ret) {
+               snprintf(query, sizeof(query),
+                       "INSERT INTO "CTS_TABLE_SIM_INFO" (unique_id) VALUES('%s')", unique_id);
+               ret = ctsvc_query_exec(query);
+               if (ret != CONTACTS_ERROR_NONE) {
+                       CTS_ERR("ctsvc_query_exec Fail(%d)", ret);
+                       return ret;
+               }
+               id = ctsvc_db_get_last_insert_id();
+       }
+       CTS_DBG("id :%d, unique_id :%s", id, unique_id);
+       *sim_id = id;
+
+       return CONTACTS_ERROR_NONE;
+
+}
+
+static int __ctsvc_server_db_get_contact_data(sqlite3* db, int id, ctsvc_contact_s *contact)
+{
+       int ret;
+       int datatype;
+       cts_stmt stmt = NULL;
+       char query[CTS_SQL_MAX_LEN] = {0};
+
+       snprintf(query, sizeof(query),
+                               "SELECT datatype, id, data.contact_id, is_default, data1, data2, "
+                                       "data3, data4, data5, data6, data7, data8, data9, data10, data11, data12 "
+                                       "FROM "CTS_TABLE_DATA", "CTSVC_DB_VIEW_CONTACT" "
+                                       "ON "CTS_TABLE_DATA".contact_id = "CTSVC_DB_VIEW_CONTACT".contact_id "
+                                       "WHERE data.contact_id = %d  AND is_my_profile = 0 "
+                                       "ORDER BY is_default DESC", id);
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       RETVM_IF(SQLITE_OK != ret, ret, "DB error : sqlite3_prepare_v2() Failed(%d)", ret);
+
+       ret = sqlite3_step(stmt);
+       if (SQLITE_ROW != ret) {
+               CTS_ERR("sqlite3_step() Failed(%d)", ret);
+               sqlite3_finalize(stmt);
+               return ret;
+       }
+
+       do {
+               datatype = ctsvc_stmt_get_int(stmt, 0);
+               switch (datatype) {
+               case CTSVC_DATA_NAME:
+                       ctsvc_get_data_info_name(stmt, (contacts_list_h)contact->name);
+                       break;
+               case CTSVC_DATA_NICKNAME:
+                       ctsvc_get_data_info_nickname(stmt, (contacts_list_h)contact->nicknames);
+                       break;
+               case CTSVC_DATA_NUMBER:
+                       ctsvc_get_data_info_number(stmt, (contacts_list_h)contact->numbers);
+                       break;
+               case CTSVC_DATA_EMAIL:
+                       ctsvc_get_data_info_email(stmt, (contacts_list_h)contact->emails);
+                       break;
+               case CTSVC_DATA_COMPANY:
+                       ctsvc_get_data_info_company(stmt, (contacts_list_h)contact->company);
+                       break;
+               default:
+                       break;
+               }
+       }while(SQLITE_ROW == sqlite3_step(stmt));
+
+       sqlite3_finalize(stmt);
+
+       return SQLITE_DONE;
+}
+
+int ctsvc_server_update_sort_name()
+{
+       int ret = 0;
+       sqlite3* db = NULL;
+       cts_stmt stmt = NULL;
+       cts_stmt update_stmt = NULL;
+       cts_stmt search_name_stmt = NULL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       INFO("Start to update sort_name");
+
+       ctsvc_db_set_status(CONTACTS_DB_STATUS_CHANGING_COLLATION);
+
+       ret = ctsvc_server_db_open(&db);
+       if (CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_server_db_open() Failed(%d)", ret);
+               ctsvc_db_set_status(CONTACTS_DB_STATUS_NORMAL);
+               return ret;
+       }
+
+       ret = ctsvc_server_begin_trans();
+       if(CONTACTS_ERROR_NONE != ret) {
+               CTS_ERR("ctsvc_server_begin_trans() Failed(%d)", ret);
+               ctsvc_server_db_close();
+               ctsvc_db_set_status(CONTACTS_DB_STATUS_NORMAL);
+               return ret;
+       }
+
+       snprintf(query, sizeof(query),
+                       "SELECT contact_id "
+                               "FROM "CTS_TABLE_CONTACTS" WHERE deleted = 0");
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if(SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_prepare_v2(%s) Failed(%s)", query, sqlite3_errmsg(db));
+               ctsvc_server_end_trans(false);
+               ctsvc_server_db_close();
+               ctsvc_db_set_status(CONTACTS_DB_STATUS_NORMAL);
+               return CONTACTS_ERROR_DB;
+       }
+
+       // Update sort_name, sortkey, display_name_language of contact table
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_CONTACTS" "
+                               "SET sort_name = ?, reverse_sort_name = ?, sortkey = ?, reverse_sortkey = ?, "
+                                       " display_name_language = ?,  reverse_display_name_language = ?, "
+                                       " display_name_source = ? "
+                               "WHERE contact_id = ?");
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &update_stmt, NULL);
+       if(SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_propare_v2(%s) Failed(%s)", query, sqlite3_errmsg(db));
+               ret = CONTACTS_ERROR_DB;
+               goto DATA_FREE;
+       }
+
+       // Update name of search_index table
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET name=? WHERE contact_id = ?",
+                       CTS_TABLE_SEARCH_INDEX);
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &search_name_stmt, NULL);
+       if(SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_propare_v2(%s) Failed(%s)", query, sqlite3_errmsg(db));
+               ret = CONTACTS_ERROR_DB;
+               goto DATA_FREE;
+       }
+
+       while (SQLITE_ROW == (ret = sqlite3_step(stmt))) {
+               int contact_id = sqlite3_column_int(stmt, 0);
+               char *search_name = NULL;
+
+               // get_contact_info
+               ctsvc_contact_s *contact = NULL;
+               contacts_record_create(_contacts_contact._uri, (contacts_record_h*)&contact);
+               ret = __ctsvc_server_db_get_contact_data(db, contact_id, contact);
+               if (SQLITE_DONE != ret) {
+                       CTS_ERR("sqlite3_step(%s) Failed(%d, %s)", query, ret, sqlite3_errmsg(db));
+                       contacts_record_destroy((contacts_record_h)contact, true);
+                       ret = CONTACTS_ERROR_DB;
+                       goto DATA_FREE;
+               }
+
+               // update sort_name, sortkey, display_name_language(sort group)
+               ctsvc_contact_make_display_name(contact);
+               if (contact->sort_name)
+                       sqlite3_bind_text(update_stmt, 1, contact->sort_name, strlen(contact->sort_name), SQLITE_STATIC);
+               if (contact->reverse_sort_name)
+                       sqlite3_bind_text(update_stmt, 2, contact->reverse_sort_name, strlen(contact->reverse_sort_name), SQLITE_STATIC);
+               if (contact->sortkey)
+                       sqlite3_bind_text(update_stmt, 3, contact->sortkey, strlen(contact->sortkey), SQLITE_STATIC);
+               if (contact->reverse_sortkey)
+                       sqlite3_bind_text(update_stmt, 4, contact->reverse_sortkey, strlen(contact->reverse_sortkey), SQLITE_STATIC);
+               sqlite3_bind_int(update_stmt, 5, contact->display_name_language);
+               sqlite3_bind_int(update_stmt, 6, contact->reverse_display_name_language);
+               sqlite3_bind_int(update_stmt, 7, contact->display_source_type);
+               sqlite3_bind_int(update_stmt, 8, contact_id);
+
+               ret = sqlite3_step(update_stmt);
+               if (SQLITE_DONE != ret) {
+                       CTS_ERR("sqlite3_step(%s) Failed(%d, %s)", query, ret, sqlite3_errmsg(db));
+                       contacts_record_destroy((contacts_record_h)contact, true);
+                       ret = CONTACTS_ERROR_DB;
+                       goto DATA_FREE;
+               }
+               sqlite3_reset(update_stmt);
+
+               // update name valud of search_index table
+               ctsvc_contact_make_search_name(contact, &search_name);
+               if (search_name) {
+                       sqlite3_bind_text(search_name_stmt, 1, search_name, strlen(search_name), SQLITE_STATIC);
+                       sqlite3_bind_int(search_name_stmt, 2, contact_id);
+                       ret = sqlite3_step(search_name_stmt);
+                       free(search_name);
+                       if (SQLITE_DONE != ret) {
+                               CTS_ERR("sqlite3_step(%s) Failed(%d, %s)", query, ret, sqlite3_errmsg(db));
+                               contacts_record_destroy((contacts_record_h)contact, true);
+                               ret = CONTACTS_ERROR_DB;
+                               goto DATA_FREE;
+                       }
+                       sqlite3_reset(search_name_stmt);
+               }
+
+               contacts_record_destroy((contacts_record_h)contact, true);
+       }
+
+       if (SQLITE_ROW != ret && SQLITE_DONE != ret) {
+               CTS_ERR("sqlite3_step() Failed(%d)", ret);
+               ret = CONTACTS_ERROR_DB;
+               goto DATA_FREE;
+       }
+
+DATA_FREE:
+       if (stmt)
+               sqlite3_finalize(stmt);
+       if (update_stmt)
+               sqlite3_finalize(update_stmt);
+       if (search_name_stmt)
+               sqlite3_finalize(search_name_stmt);
+
+       // send notification
+       if (CONTACTS_ERROR_DB != ret) {
+               ret = ctsvc_server_end_trans(true);
+               if (CONTACTS_ERROR_NONE == ret) {
+                       int fd;
+                       fd = open(CTSVC_NOTI_CONTACT_CHANGED, O_TRUNC | O_RDWR);
+                       if (0 <= fd)
+                               close(fd);
+                       fd = open(CTSVC_NOTI_PERSON_CHANGED, O_TRUNC | O_RDWR);
+                       if (0 <= fd)
+                               close(fd);
+               }
+       }
+       else
+               ctsvc_server_end_trans(false);
+
+       ctsvc_server_db_close();
+       ctsvc_db_set_status(CONTACTS_DB_STATUS_NORMAL);
+
+       INFO("End to update sort_name");
+
+       return ret;
+}
+
similarity index 52%
rename from helper/sqlite.h
rename to server/ctsvc_server_sqlite.h
index a2b5368..35b79ab 100755 (executable)
@@ -1,10 +1,8 @@
 /*
- * Contacts Service Helper
+ * 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
  * limitations under the License.
  *
  */
-#ifndef __CTS_HELPER_SQLITE_H__
-#define __CTS_HELPER_SQLITE_H__
+#ifndef __CTSVC_SERVER_SQLITE_H__
+#define __CTSVC_SERVER_SQLITE_H__
 
 #include <sqlite3.h>
 
-int helper_db_open(sqlite3 **db);
-int helper_db_close(void);
-int helper_update_default_language(int system_lang, int default_lang);
-int helper_insert_SDN_contact(const char *name, const char *number);
-int helper_delete_SDN_contact(void);
-int helper_update_collation();
+int ctsvc_server_db_open(sqlite3 **db);
+int ctsvc_server_db_close(void);
+int ctsvc_server_update_sort(int prev_sort_primary, int prev_sort_secondary, int new_sort_primary, int new_sort_secondary);
+int ctsvc_server_insert_sdn_contact(const char *name, const char *number, int sim_slot_no);
+int ctsvc_server_delete_sdn_contact(int sim_slot_no);
+int ctsvc_server_update_collation();
+int ctsvc_server_update_sort_name();
+
+int ctsvc_server_get_sim_id(const char *unique_id, int *sim_id);
 
-#endif // __CTS_HELPER_SQLITE_H__
+#endif // __CTSVC_SERVER_SQLITE_H__
 
 
diff --git a/server/ctsvc_server_update.c b/server/ctsvc_server_update.c
new file mode 100755 (executable)
index 0000000..20e7e74
--- /dev/null
@@ -0,0 +1,422 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <sqlite3.h>
+#include <db-util.h>
+
+#include "contacts.h"
+
+#include "ctsvc_internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_setting.h"
+#include "ctsvc_number_utils.h"
+#include "ctsvc_localize_utils.h"
+#include "ctsvc_server_update.h"
+
+// It should be updated whenever DB schema including VIEW query is changed
+// You have to update user version schema.sql
+//                     PRAGMA user_version = 100;
+#define CTSVC_SCHEMA_VERSION           101
+
+#ifdef ENABLE_LOG_FEATURE
+static int __ctsvc_server_find_person_id_of_phonelog(sqlite3 *__db, char *normal_num,
+               char *minmatch, int person_id, int *find_number_type)
+{
+       int ret;
+       int find_person_id = -1;
+       char query[CTS_SQL_MAX_LEN] = {0};
+       cts_stmt stmt = NULL;
+       int id;
+       int number_type = -1;
+       GSList *bind_text = NULL;
+       GSList *cursor = NULL;
+       int i = 0;
+
+       *find_number_type = -1;
+
+       ret = snprintf(query, sizeof(query),
+                       "SELECT person_id, data1 FROM "CTS_TABLE_CONTACTS", "CTS_TABLE_DATA" "
+                       "ON "CTS_TABLE_CONTACTS".contact_id = "CTS_TABLE_DATA".contact_id "
+                       "AND datatype = %d AND is_my_profile = 0 AND deleted = 0 "
+                       "WHERE data4 = ? AND _NUMBER_COMPARE_(data5, ?, NULL, NULL)",
+                       CTSVC_DATA_NUMBER);
+
+       bind_text = g_slist_append(bind_text, strdup(minmatch));
+       bind_text = g_slist_append(bind_text, strdup(normal_num));
+
+       ret = sqlite3_prepare_v2(__db, query, sizeof(query), &stmt, NULL);
+       if (stmt == NULL) {
+               CTS_ERR("sqlite3_prepare_v2 fail(%d)", ret);
+               if (bind_text) {
+                       for (cursor=bind_text;cursor;cursor=cursor->next,i++)
+                               free(cursor->data);
+                       g_slist_free(bind_text);
+               }
+               return CONTACTS_ERROR_DB;
+       }
+
+       if (bind_text) {
+               for (cursor=bind_text,i=1;cursor;cursor=cursor->next,i++) {
+                       const char *text = cursor->data;
+                       if (text && *text)
+                               sqlite3_bind_text(stmt, i, text, strlen(text), SQLITE_STATIC);
+               }
+       }
+
+       while ((ret = sqlite3_step(stmt))) {
+               id = sqlite3_column_int(stmt, 0);
+               number_type = sqlite3_column_int(stmt, 1);
+               if (find_person_id <= 0 && id > 0) {
+                       find_person_id = id;            // find first match person_id
+                       *find_number_type = number_type;
+                       if (person_id <= 0)
+                               break;
+               }
+
+               if (id == person_id) {
+                       find_person_id = person_id;
+                       *find_number_type = number_type;
+                       break;
+               }
+       }
+       sqlite3_finalize(stmt);
+
+       if (bind_text) {
+               for (cursor=bind_text;cursor;cursor=cursor->next,i++)
+                       free(cursor->data);
+               g_slist_free(bind_text);
+       }
+
+       return find_person_id;
+}
+#endif // ENABLE_LOG_FEATURE
+
+static void __ctsvc_server_number_info_update(sqlite3 *__db)
+{
+       int ret;
+       cts_stmt stmt = NULL;
+       cts_stmt update_stmt = NULL;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+#ifdef ENABLE_LOG_FEATURE
+       // update number of phonelog table
+       ret = snprintf(query, sizeof(query),
+                       "SELECT id, number, person_id FROM "CTS_TABLE_PHONELOGS " "
+                       "WHERE log_type < %d", CONTACTS_PLOG_TYPE_EMAIL_RECEIVED);
+       ret = sqlite3_prepare_v2(__db, query, strlen(query), &stmt, NULL);
+       if(SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_prepare_v2() Failed(%s)", sqlite3_errmsg(__db));
+               return;
+       }
+
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_PHONELOGS" SET normal_num=?, clean_num=?, "
+                       "minmatch=?, person_id=?, number_type=? WHERE id = ?");
+       ret = sqlite3_prepare_v2(__db, query, strlen(query), &update_stmt, NULL);
+       if(SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_prepare_v2() Failed(%s)", sqlite3_errmsg(__db));
+               sqlite3_finalize(stmt);
+               return;
+       }
+
+       while(SQLITE_ROW == (ret = sqlite3_step(stmt))) {
+               int phonelog_id = sqlite3_column_int(stmt, 0);
+               char *number = (char*)sqlite3_column_text(stmt, 1);
+               int person_id = sqlite3_column_int(stmt, 2);
+               char clean_num[SAFE_STRLEN(number)+1];
+               int find_person_id = -1;
+               int number_type = -1;
+
+               ret = ctsvc_clean_number(number, clean_num, sizeof(clean_num), true);
+               if (0 < ret) {
+                       char normal_num[sizeof(clean_num) + 20];
+                       sqlite3_bind_text(update_stmt, 2, clean_num, strlen(clean_num), SQLITE_STATIC);
+                       ret = ctsvc_normalize_number(clean_num, normal_num, sizeof(normal_num), true);
+                       char minmatch[sizeof(normal_num) +1];
+                       if (0 < ret) {
+                               sqlite3_bind_text(update_stmt, 1, normal_num, strlen(normal_num), SQLITE_STATIC);
+                               ret = ctsvc_get_minmatch_number(normal_num, minmatch, sizeof(minmatch), ctsvc_get_phonenumber_min_match_digit());
+                               if (CONTACTS_ERROR_NONE == ret) {
+                                       sqlite3_bind_text(stmt, 3, minmatch, strlen(minmatch), SQLITE_STATIC);
+                                       find_person_id  = __ctsvc_server_find_person_id_of_phonelog(__db, normal_num, minmatch, person_id, &number_type);
+                               }
+
+                               if (find_person_id > 0)
+                                       sqlite3_bind_int(update_stmt, 4, find_person_id);
+                               if (number_type >= 0)
+                                       sqlite3_bind_int(update_stmt, 5, number_type);
+                       }
+                       sqlite3_bind_int(update_stmt, 6, phonelog_id);
+
+                       ret = sqlite3_step(update_stmt);
+                       if (SQLITE_DONE != ret) {
+                               CTS_ERR("sqlite3_step() Failed(%d, %s)", ret, sqlite3_errmsg(__db));
+                               break;
+                       }
+                       sqlite3_reset(update_stmt);
+               }
+       }
+       sqlite3_finalize(stmt);
+       sqlite3_finalize(update_stmt);
+#endif // ENABLE_LOG_FEATURE
+
+       // update number of data table
+       snprintf(query, sizeof(query),
+                       "SELECT id, data3 FROM "CTS_TABLE_DATA" "
+                       "WHERE datatype = %d", CTSVC_DATA_NUMBER);
+       ret = sqlite3_prepare_v2(__db, query, strlen(query), &stmt, NULL);
+       if(SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_prepare_v2() Failed(%s)", sqlite3_errmsg(__db));
+               return;
+       }
+
+       snprintf(query, sizeof(query),
+                       "UPDATE "CTS_TABLE_DATA" SET data4=?, data5=?, data6=?  WHERE id = ?");
+       ret = sqlite3_prepare_v2(__db, query, strlen(query), &update_stmt, NULL);
+       if(SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_prepare_v2() Failed(%s)", sqlite3_errmsg(__db));
+               sqlite3_finalize(stmt);
+               return;
+       }
+
+       while(SQLITE_ROW == (ret = sqlite3_step(stmt))) {
+               int id = sqlite3_column_int(stmt, 0);
+               char *number = (char*)sqlite3_column_text(stmt, 1);
+               char clean_num[SAFE_STRLEN(number)+1];
+
+               ret = ctsvc_clean_number(number, clean_num, sizeof(clean_num), true);
+               if (0 < ret) {
+                       char normal_num[sizeof(clean_num)+20];
+                       sqlite3_bind_text(update_stmt, 3, clean_num, strlen(clean_num), SQLITE_STATIC);
+                       ret = ctsvc_normalize_number(clean_num, normal_num, sizeof(normal_num), true);
+                       char minmatch[sizeof(normal_num)+1];
+                       if (0 < ret) {
+                               sqlite3_bind_text(update_stmt, 2, normal_num, strlen(normal_num), SQLITE_STATIC);
+                               ret = ctsvc_get_minmatch_number(normal_num, minmatch, sizeof(minmatch), ctsvc_get_phonenumber_min_match_digit());
+                               if (CONTACTS_ERROR_NONE == ret)
+                                       ctsvc_stmt_bind_text(stmt, 1, minmatch);
+                       }
+                       sqlite3_bind_int(update_stmt, 4, id);
+                       ret = sqlite3_step(update_stmt);
+                       if (SQLITE_DONE != ret) {
+                               CTS_ERR("sqlite3_step() Failed(%d, %s)", ret, sqlite3_errmsg(__db));
+                               break;
+                       }
+                       sqlite3_reset(update_stmt);
+               }
+       }
+       sqlite3_finalize(stmt);
+       sqlite3_finalize(update_stmt);
+
+       return;
+}
+
+static int __ctsvc_server_get_db_version(sqlite3 *db, int *version)
+{
+       int ret;
+       char query[CTS_SQL_MIN_LEN] = {0};
+       cts_stmt stmt = NULL;
+
+       *version = 0;
+
+       snprintf(query, sizeof(query), "PRAGMA user_version;");
+       ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL);
+       if(SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_prepare_v2() Failed(%s)", sqlite3_errmsg(db));
+               return CONTACTS_ERROR_DB;
+       }
+       ret = sqlite3_step(stmt);
+       if (SQLITE_ROW != ret) {
+               CTS_ERR("sqlite3_step() Failed(%s)", sqlite3_errmsg(db));
+               sqlite3_finalize(stmt);
+               return CONTACTS_ERROR_DB;
+       }
+       *version = sqlite3_column_int(stmt, 0);
+       sqlite3_finalize(stmt);
+       return CONTACTS_ERROR_NONE;
+}
+
+int ctsvc_server_db_update(void)
+{
+       int ret;
+       int old_version = 0;
+       char *errmsg = NULL;
+       sqlite3 *__db;
+       char query[CTS_SQL_MIN_LEN] = {0};
+
+       ret = db_util_open(CTSVC_DB_PATH, &__db, 0);
+       RETVM_IF(ret != SQLITE_OK, CONTACTS_ERROR_DB,
+                       "db_util_open() Failed(%d)", ret);
+
+       // check DB schema version
+       __ctsvc_server_get_db_version(__db, &old_version);
+
+       // Tizen 2.3a Releae 0.9.114.7 ('14/5)  -----------------------------------
+       if (old_version <= 100) {
+               ret = sqlite3_exec(__db, "CREATE INDEX name_lookup_idx1 ON name_lookup(contact_id);", NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("drop view view_person_contact_group Failed(%d) : %s", ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               ret = sqlite3_exec(__db, "CREATE INDEX phone_lookup_idx1 ON phone_lookup(contact_id);", NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("drop view view_person_contact_group Failed(%d) : %s", ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               // add view_activity_photos
+               ret = sqlite3_exec(__db, "DROP VIEW view_phonelog_number", NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("drop view view_person_contact_group Failed(%d) : %s", ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               // add view_person_contact_group_assigned
+               // add view_person_contact_group_not_assigned
+               // change DB VIEW view_person_contact_group for performance
+               ret = sqlite3_exec(__db, "DROP VIEW "CTSVC_DB_VIEW_PERSON_GROUP, NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("drop view view_person_contact_group Failed(%d) : %s", ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               // change DB VIEW view_contact_group for performance
+               ret = sqlite3_exec(__db, "DROP VIEW "CTSVC_DB_VIEW_CONTACT_GROUP, NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("drop view view_contact_group Failed : %s", errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               // for number compare
+               ret = sqlite3_exec(__db, "DROP VIEW "CTSVC_DB_VIEW_NUMBER, NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("drop view %s Failed(%d) : %s", CTSVC_DB_VIEW_NUMBER, ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               ret = sqlite3_exec(__db, "DROP VIEW "CTSVC_DB_VIEW_SPEEDIDAL, NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("drop view %s Failed(%d) : %s", CTSVC_DB_VIEW_SPEEDIDAL, ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               ret = sqlite3_exec(__db, "DROP VIEW "CTSVC_DB_VIEW_PERSON_NUMBER, NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("drop view %s Failed(%d) : %s", CTSVC_DB_VIEW_PERSON_NUMBER, ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               ret = sqlite3_exec(__db, "DROP VIEW "CTSVC_DB_VIEW_CONTACT_NUMBER, NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("drop view %s Failed(%d) : %s", CTSVC_DB_VIEW_CONTACT_NUMBER, ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               ret = sqlite3_exec(__db, "DROP VIEW "CTSVC_DB_VIEW_PERSON_PHONELOG, NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("drop view %s Failed(%d) : %s", CTSVC_DB_VIEW_PERSON_PHONELOG, ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               ret = sqlite3_exec(__db, "ALTER TABLE "CTS_TABLE_PHONELOGS" ADD COLUMN clean_num TEXT", NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("add phonelogs.clean_num Failed(%d) : %s", ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               ret = sqlite3_exec(__db, "ALTER TABLE "CTS_TABLE_PHONELOGS" ADD COLUMN sim_id TEXT", NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("add phonelogs.sim_id Failed(%d) : %s", ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               ret = sqlite3_exec(__db, "ALTER TABLE "CTS_TABLE_PHONELOGS" ADD COLUMN number_type TEXT", NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("add phonelogs.number_type Failed(%d) : %s", ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               // update phonelog, data number value
+               __ctsvc_server_number_info_update(__db);
+
+               ret = sqlite3_exec(__db, "ALTER TABLE "CTS_TABLE_SDN" ADD COLUMN sim_slot_no TEXT", NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("add sdn.sim_id Failed(%d) : %s", ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               ret = sqlite3_exec(__db, "ALTER TABLE "CTS_TABLE_ADDRESSBOOKS" ADD COLUMN smack_label TEXT", NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("add sdn.sim_id Failed(%d) : %s", ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+               ret = sqlite3_exec(__db, "UPDATE "CTS_TABLE_ADDRESSBOOKS" SET='org.tizen.contact' WHERE addressbook_id = 0", NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("add sdn.sim_id Failed(%d) : %s", ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               snprintf(query, sizeof(query),
+                               "CREATE TABLE IF NOT EXISTS "CTS_TABLE_SIM_INFO" ("
+                               "sim_id                 INTEGER PRIMARY KEY AUTOINCREMENT,"
+                               "unique_id              TEXT NOT NULL, "
+                               "UNIQUE(unique_id))");
+               ret = sqlite3_exec(__db, query, NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("create sim_info table(%d)", ret);
+                       sqlite3_free(errmsg);
+               }
+
+               ret = sqlite3_exec(__db, "DROP trigger trg_contacts_update", NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("drop trigger trg_contacts_update Failed(%d) : %s", ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+               ret = sqlite3_exec(__db,
+                               "CREATE TRIGGER trg_contacts_update AFTER UPDATE ON contacts "
+                               "WHEN new.deleted = 1 "
+                               " BEGIN "
+                               "       SELECT _DATA_DELETE_(data.id, data.datatype) FROM data WHERE contact_id = old.contact_id AND is_my_profile = 0;"
+                               "       DELETE FROM group_relations WHERE old.addressbook_id != -1 AND contact_id = old.contact_id; "
+                               "       DELETE FROM persons WHERE person_id = old.person_id AND link_count = 1; "
+                               "       UPDATE persons SET dirty=1 WHERE person_id = old.person_id AND link_count > 1; "
+                               "       DELETE FROM speeddials WHERE number_id IN (SELECT id FROM data WHERE data.contact_id = old.contact_id AND datatype = 8); "
+                               " END;",
+                               NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       CTS_ERR("create trigger trg_contacts_update Failed(%d) : %s", ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               old_version = 101;
+       }
+
+       snprintf(query, sizeof(query),
+                       "PRAGMA user_version = %d", CTSVC_SCHEMA_VERSION);
+       ret = sqlite3_exec(__db, query, NULL, 0, &errmsg);
+       if(SQLITE_OK != ret) {
+               CTS_ERR("sqlite3_exec() Failed(%s)", errmsg);
+               sqlite3_free(errmsg);
+       }
+
+       db_util_close(__db);
+       return CONTACTS_ERROR_NONE;
+}
+
diff --git a/server/ctsvc_server_update.h b/server/ctsvc_server_update.h
new file mode 100755 (executable)
index 0000000..b349916
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_SERVER_UDATE_H__
+#define __CTSVC_SERVER_UDATE_H__
+
+int ctsvc_server_db_update(void);
+
+#endif // __CTSVC_SERVER_UDATE_H__
+
diff --git a/server/ctsvc_server_utils.c b/server/ctsvc_server_utils.c
new file mode 100755 (executable)
index 0000000..fa2673b
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 <malloc.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+#include <ITapiPhonebook.h>
+#include <TapiUtility.h>
+#include <system_info.h>
+
+#include "contacts.h"
+
+#include "ctsvc_internal.h"
+#include "ctsvc_setting.h"
+#include "ctsvc_server_utils.h"
+#ifdef ENABLE_SIM_FEATURE
+#include "ctsvc_server_sim.h"
+#endif // ENABLE_SIM_FEATURE
+#include "ctsvc_server_sqlite.h"
+#include "ctsvc_localize.h"
+#include "ctsvc_normalize.h"
+
+#define CTSVC_FEATURE_TELEPHONY "http://tizen.org/feature/network.telephony"
+
+static int system_language = -1;
+static bool _have_telephony_feature = false;
+
+int ctsvc_server_load_feature_list(void)
+{
+       system_info_get_platform_bool(CTSVC_FEATURE_TELEPHONY, &_have_telephony_feature);
+       return CONTACTS_ERROR_NONE;
+}
+
+bool ctsvc_server_have_telephony_feature(void)
+{
+       return _have_telephony_feature;
+}
+
+inline int ctsvc_server_set_default_sort(int sort)
+{
+       int ret = vconf_set_int(ctsvc_get_default_sort_vconfkey(), sort);
+       RETVM_IF(ret<0, CONTACTS_ERROR_SYSTEM, "vconf_set_int() Failed(%d)", ret);
+       ctsvc_set_sort_memory(sort);
+       return CONTACTS_ERROR_NONE;
+}
+
+static void __ctsvc_server_change_language_cb(keynode_t *key, void *data)
+{
+       int ret = -1;
+       int new_primary_sort, new_secondary_sort;
+       int old_primary_sort, old_secondary_sort;
+       char *new_langset = NULL;
+       char *langset = NULL;
+
+       new_langset = vconf_keynode_get_str(key);
+       RETM_IF(NULL == new_langset, "vconf_keynode_get_str() return NULL");
+       langset = ctsvc_get_langset();
+       INFO("%s --> %s", langset, new_langset);
+       if (strcmp(langset, new_langset) != 0) {
+               bool sort_name_update = false;
+               old_primary_sort = ctsvc_get_primary_sort();
+               if (old_primary_sort < 0) {
+                       RETM_IF(ret<0, "ctsvc_get_primary_sort() Fail(%d)", ret);
+               }
+               old_secondary_sort = ctsvc_get_secondary_sort();
+               if (old_secondary_sort < 0) {
+                       RETM_IF(ret<0, "ctsvc_get_secondary_sort() Fail(%d)", ret);
+               }
+
+               if (strncmp(langset, "zh", strlen("zh")) == 0 ||
+                       strncmp(langset, "ko", strlen("ko")) == 0 ||
+                       strncmp(langset, "ja", strlen("ja")) == 0 ||
+                       strncmp(new_langset, "zh", strlen("zh")) == 0 ||
+                       strncmp(new_langset, "ko", strlen("ko")) == 0 ||
+                       strncmp(new_langset, "ja", strlen("ja")) == 0) {
+                       sort_name_update = true;
+               }
+               ctsvc_set_langset(strdup(new_langset));
+               langset = new_langset;
+
+               system_language = ctsvc_get_language_type(langset);
+               new_primary_sort = ctsvc_get_sort_type_from_language(system_language);
+               if (new_primary_sort == CTSVC_SORT_OTHERS)
+                       new_primary_sort = CTSVC_SORT_WESTERN;
+
+               new_secondary_sort = CTSVC_SORT_WESTERN;
+
+               if (sort_name_update) {
+                  ctsvc_server_set_default_sort(new_primary_sort);
+                       ctsvc_server_update_sort_name();
+               }
+               else {
+                       if (new_primary_sort != old_primary_sort)
+                               ret = ctsvc_server_update_sort(old_primary_sort, old_secondary_sort, new_primary_sort, new_secondary_sort);
+
+                       ctsvc_server_update_collation();
+               }
+       }
+}
+
+void ctsvc_server_final_configuration(void)
+{
+       int ret = -1;
+
+       ret = vconf_ignore_key_changed(VCONFKEY_LANGSET, __ctsvc_server_change_language_cb);
+       RETM_IF(ret<0,"vconf_ignore_key_changed(%s) Failed(%d)", VCONFKEY_LANGSET, ret);
+
+#ifdef ENABLE_SIM_FEATURE
+       ctsvc_server_sim_final();
+#endif // ENABLE_SIM_FEATURE
+}
+
+int ctsvc_server_init_configuration(void)
+{
+       int ret;
+       char *langset = NULL;
+       int sort_type;
+
+       langset = vconf_get_str(VCONFKEY_LANGSET);
+       WARN_IF(NULL == langset, "language setting is return NULL");
+       ctsvc_set_langset(langset);
+       system_language = ctsvc_get_language_type(langset);
+
+       ret = vconf_get_int(ctsvc_get_default_sort_vconfkey(), &sort_type);
+       if (ret < 0 || sort_type == CTSVC_SORT_OTHERS) {
+               CTS_ERR("vconf_get_int(%s) Failed(%d)", ctsvc_get_default_sort_vconfkey() ,ret);
+               sort_type = ctsvc_get_sort_type_from_language(system_language);
+               if (sort_type == CTSVC_SORT_OTHERS)
+                       sort_type = CTSVC_SORT_WESTERN;
+       }
+       ctsvc_server_set_default_sort(sort_type);
+
+       ret = vconf_notify_key_changed(VCONFKEY_LANGSET,
+                       __ctsvc_server_change_language_cb, NULL);
+       RETVM_IF(ret<0, CONTACTS_ERROR_SYSTEM, "vconf_notify_key_changed(%s) Failed(%d)",
+                       VCONFKEY_LANGSET, ret);
+
+#ifdef ENABLE_SIM_FEATURE
+       ret = ctsvc_server_sim_init();
+       RETVM_IF(ret !=CONTACTS_ERROR_NONE, ret, "ctsvc_server_sim_init Failed(%d)", ret);
+#endif // ENABLE_SIM_FEATURE
+
+       return CONTACTS_ERROR_NONE;
+}
+
+void ctsvc_server_trim_memory(void)
+{
+       malloc_trim(0);
+       sqlite3_release_memory(-1);
+}
diff --git a/server/ctsvc_server_utils.h b/server/ctsvc_server_utils.h
new file mode 100755 (executable)
index 0000000..77881e0
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Contacts Service
+ *
+ * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * 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 __CTSVC_SERVER_UTILS_H__
+#define __CTSVC_SERVER_UTILS_H__
+
+int ctsvc_server_load_feature_list(void);
+bool ctsvc_server_have_telephony_feature(void);
+
+int ctsvc_server_init_configuration(void);
+void ctsvc_server_final_configuration(void);
+
+int ctsvc_server_set_default_sort(int lang);
+
+void ctsvc_server_trim_memory(void);
+
+#endif // __CTSVC_SERVER_UTILS_H__
+
diff --git a/src/cts-addressbook.c b/src/cts-addressbook.c
deleted file mode 100755 (executable)
index 4769094..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * 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-sqlite.h"
-#include "cts-utils.h"
-#include "cts-person.h"
-#include "cts-addressbook.h"
-
-static inline int cts_reset_internal_addressbook(void)
-{
-       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), "DELETE FROM %s WHERE addrbook_id = %d",
-                       CTS_TABLE_CONTACTS, CTS_ADDRESSBOOK_INTERNAL);
-
-       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 addrbook_id = %d",
-                       CTS_TABLE_GROUPS, CTS_ADDRESSBOOK_INTERNAL);
-
-       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();
-       cts_set_group_noti();
-       ret = contacts_svc_end_trans(true);
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-API int contacts_svc_insert_addressbook(CTSvalue *addressbook)
-{
-       int ret, index;
-       cts_stmt stmt = NULL;
-       cts_addrbook *record = (cts_addrbook *)addressbook;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       retv_if(NULL == addressbook, CTS_ERR_ARG_NULL);
-       retv_if(NULL == record->name, CTS_ERR_ARG_INVALID);
-       retvm_if(CTS_VALUE_ADDRESSBOOK != record->v_type, CTS_ERR_ARG_INVALID,
-                       "addressbook is invalid type(%d)", record->v_type);
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       snprintf(query, sizeof(query),
-                       "INSERT INTO %s(addrbook_name, acc_id, acc_type, mode) "
-                       "VALUES(?, %d, %d, %d)",
-                       CTS_TABLE_ADDRESSBOOKS, record->acc_id, record->acc_type, record->mode);
-
-       stmt = cts_query_prepare(query);
-       if (NULL == stmt) {
-               ERR("cts_query_prepare() Failed");
-               contacts_svc_end_trans(false);
-               return CTS_ERR_DB_FAILED;
-       }
-
-       cts_stmt_bind_text(stmt, 1, record->name);
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_SUCCESS != ret) {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-       index = cts_db_get_last_insert_id();
-       cts_stmt_finalize(stmt);
-
-       cts_set_addrbook_noti();
-       ret = contacts_svc_end_trans(true);
-       retvm_if(ret < CTS_SUCCESS, ret, "contacts_svc_end_trans() Failed(%d)", ret);
-
-       return index;
-}
-
-API int contacts_svc_delete_addressbook(int addressbook_id)
-{
-       CTS_FN_CALL;
-       int ret;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       if (CTS_ADDRESSBOOK_INTERNAL == addressbook_id)
-               return cts_reset_internal_addressbook();
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       snprintf(query, sizeof(query), "DELETE FROM %s WHERE addrbook_id = %d",
-                       CTS_TABLE_ADDRESSBOOKS, addressbook_id);
-
-       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_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) {
-               cts_set_contact_noti();
-               cts_set_group_noti();
-               cts_set_addrbook_noti();
-               ret = contacts_svc_end_trans(true);
-       }
-       else {
-               contacts_svc_end_trans(false);
-               ret = CTS_ERR_NO_DATA;
-       }
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-API int contacts_svc_update_addressbook(CTSvalue *addressbook)
-{
-       int ret;
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MIN_LEN] = {0};
-       cts_addrbook *record = (cts_addrbook *)addressbook;
-
-       retv_if(NULL == addressbook, CTS_ERR_ARG_NULL);
-       retv_if(NULL == record->name, CTS_ERR_ARG_INVALID);
-       retvm_if(CTS_VALUE_ADDRESSBOOK != record->v_type, CTS_ERR_ARG_INVALID,
-                       "addressbook is invalid type(%d)", record->v_type);
-
-       snprintf(query, sizeof(query),
-                       "UPDATE %s SET addrbook_name=?, acc_id=%d, acc_type=%d, mode=%d "
-                       "WHERE addrbook_id=%d", CTS_TABLE_ADDRESSBOOKS,
-                       record->acc_id, record->acc_type, record->mode, record->id);
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       stmt = cts_query_prepare(query);
-       if (NULL == stmt) {
-               ERR("cts_query_prepare() Failed");
-               contacts_svc_end_trans(false);
-               return CTS_ERR_DB_FAILED;
-       }
-
-       cts_stmt_bind_text(stmt, 1, record->name);
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_SUCCESS != ret) {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-       cts_stmt_finalize(stmt);
-
-       cts_set_addrbook_noti();
-
-       ret = contacts_svc_end_trans(true);
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-API int contacts_svc_get_addressbook(int addressbook_id, CTSvalue **ret_value)
-{
-       int ret;
-       cts_addrbook *ab;
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       retv_if(NULL == ret_value, CTS_ERR_ARG_NULL);
-
-       snprintf(query, sizeof(query),
-                       "SELECT addrbook_id, addrbook_name, acc_id, acc_type, mode "
-                       "FROM %s WHERE addrbook_id = %d", CTS_TABLE_ADDRESSBOOKS, addressbook_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;
-       }
-
-       ab = (cts_addrbook *)contacts_svc_value_new(CTS_VALUE_ADDRESSBOOK);
-       if (ab) {
-               ab->embedded = true;
-               cts_stmt_get_addressbook(stmt, ab);
-       }
-
-       cts_stmt_finalize(stmt);
-
-       *ret_value = (CTSvalue *)ab;
-
-       return CTS_SUCCESS;
-}
diff --git a/src/cts-addressbook.h b/src/cts-addressbook.h
deleted file mode 100755 (executable)
index 244433e..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * 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_ADDRESSBOOK_H__
-#define __CTS_ADDRESSBOOK_H__
-
-/**
- * system addressbook id
- */
-
-enum ADDRESSBOOK{
-       CTS_ADDRESSBOOK_INTERNAL,
-       CTS_ADDRESSBOOK_START,
-};
-
-#ifndef __CONTACTS_SVC_H__
-
-
-//<!--
-/**
- * @defgroup   CONTACTS_SVC_ADDRESSBOOK Addressbook Modification
- * @ingroup    CONTACTS_SVC
- * @addtogroup CONTACTS_SVC_ADDRESSBOOK
- * @{
- *
- * This interface provides methods to insert/update/delete the addressbook.
- * Addressbook supports groups and contacts. Several addressbooks can be included in the same account_id.
- *
- * If the ID of an addressbook is 'zero', it means it is the internal addressbook of a phone.
- * It needs additional management because it is not included in database(physical storage).
- *
- * - getting all addressbook (0 is logical value for internal addressbook)
- * @code
- void addrbook_list(void)
- {
-        int ret, count;
-        CTSiter *iter;
-
-        count = contacts_svc_count_with_int(CTS_GET_COUNT_CONTACTS_IN_ADDRESSBOOK, 0);
-        printf("Phone(%d)", count);
-
-        ret = contacts_svc_get_list(CTS_LIST_ALL_ADDRESSBOOK, &iter);
-        if (CTS_SUCCESS != ret) {
-                printf("contacts_svc_get_list() Failed(%d)\n", ret);
-                return;
-        }
-
-        while (CTS_SUCCESS == contacts_svc_iter_next(iter)) {
-                int id;
-                const char *name;
-                CTSvalue *info;
-
-                info = contacts_svc_iter_get_info(iter);
-                id = contacts_svc_value_get_int(info, CTS_LIST_ADDRESSBOOK_ID_INT);
-                name = contacts_svc_value_get_str(info, CTS_LIST_ADDRESSBOOK_NAME_STR);
-                count = contacts_svc_count_with_int(CTS_GET_COUNT_CONTACTS_IN_ADDRESSBOOK, id);
-
-                printf("%s(%d)", name, count);
-        }
-        contacts_svc_iter_remove(iter);
- }
- * @endcode
- *
- */
-
-/**
- * addressbook permission
- */
-enum ADDRESSBOOKPERMISSION {
-       CTS_ADDRESSBOOK_MODE_NONE, /**< .*/
-       CTS_ADDRESSBOOK_MODE_READONLY, /**< .*/
-};
-
-/**
- * This function inserts a addressbook information into database.
- * The implementation assigns an index number of the addressbook automatically.
- * \n The returned index is unique and non-reusable.
- *
- * @param[in] addressbook A addressbook information of #CTSvalue created by contacts_svc_value_new(CTS_VALUE_ADDRESSBOOK).
- * @return the index of contact on success, Negative value(#cts_error) on error
- * @par example
- * @code
- int insert_addrbook(void)
- {
-    int ret;
-    CTSvalue *ab;
-    ab = contacts_svc_value_new(CTS_VALUE_ADDRESSBOOK);
-
-    contacts_svc_value_set_int(ab, CTS_ADDRESSBOOK_VAL_ACC_ID_INT, 1);
-    contacts_svc_value_set_int(ab, CTS_ADDRESSBOOK_VAL_ACC_TYPE_INT, CTS_ADDRESSBOOK_TYPE_GOOGLE);
-    contacts_svc_value_set_int(ab, CTS_ADDRESSBOOK_VAL_MODE_INT, CTS_ADDRESSBOOK_MODE_NONE);
-    contacts_svc_value_set_str(ab, CTS_ADDRESSBOOK_VAL_NAME_STR, "test1");
-
-    ret = contacts_svc_insert_addressbook(ab);
-    if(ret < CTS_SUCCESS)
-       printf("contacts_svc_insert_addressbook() Failed\n");
-
-    contacts_svc_value_free(ab);
-    return ret;
- }
- * @endcode
- */
-int contacts_svc_insert_addressbook(CTSvalue *addressbook);
-
-/**
- * This function deletes the addressbook information related to addressbook_id.
- * Also, the related contacts and groups are deleted.
- * @param[in] addressbook_id index of addressbook
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_delete_addressbook(int addressbook_id);
-
-/**
- * This function updates a addressbook information into database.
- *
- * @param[in] addressbook A addressbook information of #CTSvalue created by contacts_svc_get_addressbook().
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @par example
- * @code
- void update_addrbook(void)
- {
-    int ret;
-    CTSvalue *ab = NULL;
-    ret = contacts_svc_get_addressbook(2, &ab);
-    if(CTS_SUCCESS != ret) {
-       printf("contacts_svc_get_addressbook() Failed\n");
-       return;
-    }
-
-    contacts_svc_value_set_str(ab, CTS_ADDRESSBOOK_VAL_NAME_STR,"Fixed-addressbook");
-
-    ret = contacts_svc_update_addressbook(ab);
-    if(ret < CTS_SUCCESS)
-       printf("contacts_svc_update_addressbook() Failed\n");
-
-    contacts_svc_value_free(ab);
- }
- * @endcode
- */
-int contacts_svc_update_addressbook(CTSvalue *addressbook);
-
-/**
- * This function gets a addressbook record which has the index from the database.
- * Obtained addressbook record should be free using by contacts_svc_value_free().
- * @param[in] addressbook_id The index of addressbook to get
- * @param[out] ret_value Points of the addressbook record which is returned
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @par example
- * @code
- void get_addrbook(int addressbook_id)
- {
-    int ret;
-    const char *name;
-    CTSvalue *ab = NULL;
-
-    ret = contacts_svc_get_addressbook(addressbook_id, &ab);
-    if(CTS_SUCCESS != ret) {
-       printf("contacts_svc_get_addressbook() Failed\n");
-       return;
-    }
-
-    printf("///////////%d//////////////\n",
-          contacts_svc_value_get_int(ab, CTS_ADDRESSBOOK_VAL_ID_INT));
-    printf("The related account ID : %d\n",
-          contacts_svc_value_get_int(ab, CTS_ADDRESSBOOK_VAL_ACC_ID_INT));
-    printf("The related account type : %d\n",
-          contacts_svc_value_get_int(ab, CTS_ADDRESSBOOK_VAL_ACC_TYPE_INT));
-    printf("permission : %d\n",
-          contacts_svc_value_get_int(ab, CTS_ADDRESSBOOK_VAL_MODE_INT));
-
-    name = contacts_svc_value_get_str(ab, CTS_ADDRESSBOOK_VAL_NAME_STR);
-    if(name)
-       printf("Name : %s\n", name);
-    printf("//////////////////////////\n");
-
-   contacts_svc_value_free(ab);
- }
- * @endcode
- */
-int contacts_svc_get_addressbook(int addressbook_id, CTSvalue **ret_value);
-
-/**
- * @}
- */
-//-->
-#endif //__CONTACTS_SVC_H__
-#endif //__CTS_ADDRESSBOOK_H__
diff --git a/src/cts-contact-read.c b/src/cts-contact-read.c
deleted file mode 100755 (executable)
index ec4fc94..0000000
+++ /dev/null
@@ -1,1020 +0,0 @@
-/*
- * 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-write.c b/src/cts-contact-write.c
deleted file mode 100755 (executable)
index 590dd11..0000000
+++ /dev/null
@@ -1,2446 +0,0 @@
-/*
- * 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-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;
-
-static inline int cts_insert_contact_data_number(cts_stmt stmt,
-               GSList* number_list)
-{
-       CTS_FN_CALL;
-
-       int ret, cnt, default_num=0, mobile_num=0;
-       GSList *number_repeat = number_list;
-       cts_number *number_data;
-
-       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
-       retv_if(NULL == number_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               if (NULL != (number_data = (cts_number *)number_repeat->data)
-                               && !number_data->deleted && number_data->number)
-               {
-                       const char *normal_num;
-                       char clean_num[CTS_NUMBER_MAX_LEN];
-
-                       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 (0 < ret) {
-                               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();
-
-                       if (number_data->is_default)
-                               default_num = number_data->id;
-                       else if (!default_num && CTS_NUM_TYPE_CELL & number_data->type && !mobile_num)
-                               mobile_num = number_data->id;
-                       cts_stmt_reset(stmt);
-               }
-               number_repeat = g_slist_next(number_repeat);
-       }while(number_repeat);
-
-       if (default_num)
-               return default_num;
-       else
-               return mobile_num;
-}
-
-static inline int cts_insert_contact_data_email(cts_stmt stmt,
-               GSList* email_list)
-{
-       CTS_FN_CALL;
-
-       int ret, cnt, default_email=0;
-       GSList *email_repeat = email_list;
-       cts_email *email_data;
-
-       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
-       retv_if(NULL == email_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               if (NULL != (email_data = (cts_email *)email_repeat->data)
-                               && !email_data->deleted && email_data->email_addr)
-               {
-                       cnt = 1;
-                       cts_stmt_bind_int(stmt, cnt++, CTS_DATA_EMAIL);
-                       cts_stmt_bind_int(stmt, cnt++, email_data->type);
-                       cts_stmt_bind_text(stmt, cnt++, email_data->email_addr);
-
-                       ret = cts_stmt_step(stmt);
-                       retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-                       email_data->id = cts_db_get_last_insert_id();
-
-                       if (email_data->is_default)
-                               default_email = email_data->id;
-                       cts_stmt_reset(stmt);
-               }
-               email_repeat = g_slist_next(email_repeat);
-       }while(email_repeat);
-
-       return default_email;
-}
-
-static inline int cts_insert_contact_grouprel(int acc_id, int index,
-               GSList* group_list)
-{
-       CTS_FN_CALL;
-
-       GSList *group_repeat = group_list;
-       cts_group *group_data;
-       int rel_changed = 0;
-
-       retv_if(NULL == group_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               group_data = group_repeat->data;
-               group_repeat = group_repeat->next;
-
-               if (NULL == group_data || group_data->deleted)
-                       continue;
-
-               if (group_data->vcard_group) {
-                       int found_id;
-                       found_id = contacts_svc_find_group(acc_id, group_data->vcard_group);
-                       if (0 < found_id)
-                               group_data->id = found_id;
-                       else if (found_id == CTS_ERR_DB_RECORD_NOT_FOUND) {
-                               CTSvalue *group;
-                               group = contacts_svc_value_new(CTS_VALUE_GROUP);
-
-                               contacts_svc_value_set_str(group, CTS_GROUP_VAL_NAME_STR, group_data->vcard_group);
-                               found_id = contacts_svc_insert_group(acc_id, group);
-                               if (found_id < CTS_SUCCESS)
-                                       ERR("contacts_svc_insert_group() Failed\n");
-                               else
-                                       group_data->id = found_id;
-
-                               contacts_svc_value_free(group);
-                       }
-               }
-               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);
-
-       if (rel_changed)
-               return rel_changed;
-       else
-               return CTS_SUCCESS;
-}
-
-static inline int cts_insert_contact_data_event(cts_stmt stmt,
-               GSList* event_list)
-{
-       CTS_FN_CALL;
-
-       GSList *event_repeat = event_list;
-       cts_event *event_data;
-
-       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
-       retv_if(NULL == event_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               if (NULL != (event_data = (cts_event *)event_repeat->data)
-                               && !event_data->deleted && event_data->date)
-               {
-                       cts_stmt_bind_int(stmt, 1, CTS_DATA_EVENT);
-                       cts_stmt_bind_event(stmt, 2, event_data);
-
-                       int ret = cts_stmt_step(stmt);
-                       retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-                       cts_stmt_reset(stmt);
-               }
-               event_repeat = g_slist_next(event_repeat);
-       }while(event_repeat);
-
-       return CTS_SUCCESS;
-}
-
-
-static inline int cts_insert_contact_data_messenger(cts_stmt stmt,
-               GSList* messenger_list)
-{
-       CTS_FN_CALL;
-
-       GSList *messenger_repeat = messenger_list;
-       cts_messenger *messenger_data;
-
-       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
-       retv_if(NULL == messenger_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               if (NULL != (messenger_data = (cts_messenger *)messenger_repeat->data)
-                               && !messenger_data->deleted && messenger_data->im_id)
-               {
-                       cts_stmt_bind_int(stmt, 1, CTS_DATA_MESSENGER);
-                       cts_stmt_bind_messenger(stmt, 2, messenger_data);
-
-                       int ret = cts_stmt_step(stmt);
-                       retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-                       cts_stmt_reset(stmt);
-               }
-               messenger_repeat = g_slist_next(messenger_repeat);
-       }while(messenger_repeat);
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_insert_contact_data_postal(cts_stmt stmt,
-               GSList* postal_list)
-{
-       CTS_FN_CALL;
-
-       GSList *postal_repeat = postal_list;
-       cts_postal *postal_data;
-
-       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
-       retv_if(NULL == postal_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               if (NULL != (postal_data = (cts_postal *)postal_repeat->data)
-                               && !postal_data->deleted
-                               && (postal_data->country || postal_data->pobox
-                                       || postal_data->postalcode || postal_data->region
-                                       || postal_data->locality || postal_data->street || postal_data->extended))
-               {
-                       cts_stmt_bind_int(stmt, 1, CTS_DATA_POSTAL);
-                       cts_stmt_bind_postal(stmt, 2, postal_data);
-
-                       int ret = cts_stmt_step(stmt);
-                       retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-                       cts_stmt_reset(stmt);
-               }
-               postal_repeat = g_slist_next(postal_repeat);
-       }while(postal_repeat);
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_insert_contact_data_web(cts_stmt stmt,
-               GSList* web_list)
-{
-       CTS_FN_CALL;
-
-       GSList *web_repeat = web_list;
-       cts_web *web_data;
-
-       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
-       retv_if(NULL == web_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               if (NULL != (web_data = (cts_web *)web_repeat->data)
-                               && !web_data->deleted && web_data->url)
-               {
-                       cts_stmt_bind_int(stmt, 1, CTS_DATA_WEB);
-                       cts_stmt_bind_web(stmt, 2, web_data);
-
-                       int ret = cts_stmt_step(stmt);
-                       retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-                       cts_stmt_reset(stmt);
-               }
-               web_repeat = g_slist_next(web_repeat);
-       }while(web_repeat);
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_insert_contact_data_nick(cts_stmt stmt,
-               GSList* nick_list)
-{
-       CTS_FN_CALL;
-       GSList *nick_repeat = nick_list;
-       cts_nickname *nick_data;
-
-       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
-       retv_if(NULL == nick_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               if (NULL != (nick_data = (cts_nickname *)nick_repeat->data)
-                               && !nick_data->deleted && nick_data->nick)
-               {
-                       cts_stmt_bind_int(stmt, 1, CTS_DATA_NICKNAME);
-                       cts_stmt_bind_text(stmt, 3, nick_data->nick);
-
-                       int ret = cts_stmt_step(stmt);
-                       retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-                       cts_stmt_reset(stmt);
-               }
-               nick_repeat = g_slist_next(nick_repeat);
-       }while(nick_repeat);
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_insert_contact_data_extend(cts_stmt stmt,
-               GSList* extend_list)
-{
-       CTS_FN_CALL;
-
-       GSList *extend_repeat = extend_list;
-       cts_extend *extend_data;
-
-       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
-       retv_if(NULL == extend_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               if (NULL != (extend_data = (cts_extend *)extend_repeat->data)
-                               && !extend_data->deleted)
-               {
-                       cts_stmt_bind_int(stmt, 1, extend_data->type);
-                       cts_stmt_bind_extend(stmt, 2, extend_data);
-
-                       int ret = cts_stmt_step(stmt);
-                       retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-                       cts_stmt_reset(stmt);
-               }
-               extend_repeat = g_slist_next(extend_repeat);
-       }while(extend_repeat);
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_make_name_lookup(int op_code, cts_name *name,
-               char *name_lookup, int name_lookup_size)
-{
-       if (name->display) {
-               snprintf(name_lookup, name_lookup_size, "%s", name->display);
-               return CTS_SUCCESS;
-       }
-
-       if (CTS_ORDER_NAME_FIRSTLAST == op_code)
-               snprintf(name_lookup, name_lookup_size, "%s %c%s",
-                               SAFE_STR(name->first), 0x1, SAFE_STR(name->last));
-       else
-               snprintf(name_lookup, name_lookup_size, "%s,%c %c%s",
-                               SAFE_STR(name->last), 0x1, 0x1, SAFE_STR(name->first));
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_insert_contact_data_name(cts_stmt stmt,
-               cts_name *name)
-{
-       int ret;
-       int cnt = 2;
-       cts_name normalize_name={0};
-       char *tmp_display, *tmp_first, *tmp_last;
-       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
-
-       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;
-       tmp_last = name->last;
-
-       if (name->display) {
-               ret = cts_normalize_name(name, normal_name, true);
-               retvm_if(ret < CTS_SUCCESS, ret, "cts_normalize_name() Failed(%d)", ret);
-               if (normal_name[CTS_NN_FIRST][0])
-                       normalize_name.display = normal_name[CTS_NN_FIRST];
-               else
-                       name->display = NULL;
-       }
-
-       if (NULL == name->display) {
-               ret = cts_normalize_name(name, normal_name, false);
-               retvm_if(ret < CTS_SUCCESS, ret, "cts_normalize_name() Failed(%d)", ret);
-
-               switch (ret)
-               {
-               case CTS_LANG_KOREAN:
-                       snprintf(display, sizeof(display), "%s%s",
-                                       SAFE_STR(name->last), SAFE_STR(name->first));
-
-                       strncat(normal_name[CTS_NN_LAST], normal_name[CTS_NN_FIRST],
-                                       sizeof(normal_name[CTS_NN_LAST]));
-
-                       name->display = display;
-                       normalize_name.display = normal_name[CTS_NN_LAST];
-                       break;
-               case CTS_LANG_ENGLISH:
-               default:
-                       if (normal_name[CTS_NN_FIRST][0])
-                               normalize_name.first = normal_name[CTS_NN_FIRST];
-                       else
-                               name->first = NULL;
-
-                       if (normal_name[CTS_NN_LAST][0])
-                               normalize_name.last = normal_name[CTS_NN_LAST];
-                       else
-                               name->last = NULL;
-
-                       break;
-               }
-       }
-
-       if (cts_get_default_language() == ret)
-               cts_stmt_bind_int(stmt, cnt, CTS_LANG_DEFAULT);
-       else
-               cts_stmt_bind_int(stmt, cnt, ret);
-       cnt = cts_stmt_bind_name(stmt, cnt, name);
-
-       name->display = tmp_display;
-       name->first = tmp_first;
-       name->last = tmp_last;
-
-       ret = cts_make_name_lookup(CTS_ORDER_NAME_FIRSTLAST, &normalize_name,
-                       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));
-       retvm_if(CTS_SUCCESS != ret, ret, "cts_make_name_lookup() Failed(%d)", ret);
-
-       CTS_DBG("lookup=%s(%d), reverse_lookup=%s(%d)",
-                       lookup, strlen(lookup), reverse_lookup, strlen(reverse_lookup));
-
-       cts_stmt_bind_text(stmt, cnt++, lookup);
-       cts_stmt_bind_text(stmt, cnt++, reverse_lookup);
-       cts_stmt_bind_text(stmt, cnt++, normal_name[CTS_NN_SORTKEY]);
-
-       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)
-{
-       int ret;
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       snprintf(query, sizeof(query), "INSERT INTO %s(contact_id, is_restricted, datatype, "
-                       "data1, data2, data3, data4, data5, data6, data7, data8, data9, data10) "
-                       "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 (contact->name && (field & CTS_DATA_FIELD_NAME)) {
-               ret = cts_insert_contact_data_name(stmt, contact->name);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_insert_contact_data_name() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-       }
-
-       //Insert the company
-       if (contact->company && (field & CTS_DATA_FIELD_COMPANY))
-       {
-               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;
-               }
-       }
-
-       //Insert the events
-       if (contact->events && (field & CTS_DATA_FIELD_EVENT))
-       {
-               ret = cts_insert_contact_data_event(stmt, contact->events);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_insert_contact_data_event() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-       }
-
-       //Insert the messengers
-       if (contact->messengers && (field & CTS_DATA_FIELD_MESSENGER))
-       {
-               ret = cts_insert_contact_data_messenger(stmt, contact->messengers);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_insert_contact_data_messenger() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-       }
-
-       //Insert the postals
-       if (contact->postal_addrs && (field & CTS_DATA_FIELD_POSTAL))
-       {
-               ret = cts_insert_contact_data_postal(stmt, contact->postal_addrs);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_insert_contact_data_postal() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-       }
-
-       //Insert the Web addrs
-       if (contact->web_addrs && (field & CTS_DATA_FIELD_WEB))
-       {
-               ret = cts_insert_contact_data_web(stmt, contact->web_addrs);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_insert_contact_data_web() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-       }
-
-       //Insert the Nick names
-       if (contact->nicknames && (field & CTS_DATA_FIELD_NICKNAME))
-       {
-               ret = cts_insert_contact_data_nick(stmt, contact->nicknames);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_insert_contact_data_nick() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-       }
-
-       //Insert the numbers
-       if (contact->numbers && (field & CTS_DATA_FIELD_NUMBER))
-       {
-               ret = cts_insert_contact_data_number(stmt, contact->numbers);
-               if (ret < CTS_SUCCESS) {
-                       ERR("cts_insert_contact_data_number() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-               contact->default_num = ret;
-       }
-
-       //Insert the emails
-       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);
-                       return ret;
-               }
-               contact->default_email = ret;
-       }
-
-
-       //Insert the extended values
-       if (contact->extended_values && (field & CTS_DATA_FIELD_EXTEND_ALL))
-       {
-               ret = cts_insert_contact_data_extend(stmt, contact->extended_values);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_insert_contact_data_extend() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-       }
-
-       cts_stmt_finalize(stmt);
-
-       return CTS_SUCCESS;
-}
-
-static int cts_set_first_id_for_default(contact_t *contact)
-{
-       GSList *cur;
-
-       if (!contact->default_num)
-       {
-               for (cur = contact->numbers;cur;cur = cur->next) {
-                       if(cur->data) {
-                               cts_number *num = cur->data;
-                               if(!num->deleted && num->id) {
-                                       contact->default_num = num->id;
-                                       break;
-                               }
-                       }
-               }
-       }
-
-       if (!contact->default_email)
-       {
-               for (cur = contact->emails;cur;cur = cur->next) {
-                       if(cur->data) {
-                               cts_email *email = cur->data;
-                               if(!email->deleted && email->id) {
-                                       contact->default_email = email->id;
-                                       break;
-                               }
-                       }
-               }
-       }
-
-       return CTS_SUCCESS;
-}
-
-static inline char* cts_contact_get_valid_first_number_or_email(GSList *numbers, GSList *emails)
-{
-       GSList *cur;
-
-       for (cur=numbers;cur;cur=cur->next) {
-               cts_number *num = cur->data;
-               if (num && !num->deleted && num->number) {
-                       return num->number;
-               }
-       }
-
-       for (cur=emails;cur;cur=cur->next) {
-               cts_email *email = cur->data;
-               if (email && !email->deleted && email->email_addr) {
-                       return email->email_addr;
-               }
-       }
-       return NULL;
-}
-
-static inline void cts_insert_contact_handle_no_name(contact_t *contact)
-{
-       if (NULL == contact->name) {
-               contact->name = calloc(1, sizeof(cts_name));
-               contact->name->embedded = true;
-       }
-
-       if (contact->name->display || contact->name->first || contact->name->last)
-               return;
-
-       if (contact->company && contact->company->name)
-               contact->name->display = strdup(contact->company->name);
-       else {
-               char *temp;
-
-               temp = cts_contact_get_valid_first_number_or_email(contact->numbers, contact->emails);
-               contact->name->display = SAFE_STRDUP(temp);
-       }
-       return;
-}
-
-static inline int cts_safe_strcmp(char *s1, char *s2)
-{
-       if (NULL == s1 || NULL == s2)
-               return !(s1 == s2);
-       else
-               return strcmp(s1, s2);
-}
-
-
-static inline void cts_contact_remove_dup_data_number(GSList *numbers)
-{
-       GSList *cur1, *cur2;
-
-       cts_number *num1, *num2;
-       for (cur1=numbers;cur1;cur1=cur1->next) {
-               num1 = cur1->data;
-               if (NULL == num1 || num1->deleted)
-                       continue;
-               for (cur2=numbers;cur2;cur2=cur2->next) {
-                       num2 = cur2->data;
-                       if(NULL == num2 || num1 == num2)
-                               continue;
-                       if (!num2->deleted && num1->type == num2->type &&
-                                       !cts_safe_strcmp(num1->number, num2->number)) {
-                               num1->is_default |= num2->is_default;
-                               num1->is_favorite |= num2->is_favorite;
-                               num2->deleted = true;
-                       }
-               }
-       }
-}
-
-
-static inline void cts_contact_remove_dup_data_email(GSList *emails)
-{
-       GSList *cur1, *cur2;
-       cts_email *email1, *email2;
-
-       for (cur1=emails;cur1;cur1=cur1->next) {
-               email1 = cur1->data;
-               if (NULL == email1 || email1->deleted)
-                       continue;
-               for (cur2=emails;cur2;cur2=cur2->next) {
-                       email2 = cur2->data;
-                       if(NULL == email2 || email1 == email2)
-                               continue;
-                       if (!email2->deleted && email1->type == email2->type &&
-                                       !cts_safe_strcmp(email1->email_addr, email2->email_addr)) {
-                               email1->is_default |= email2->is_default;
-                               email2->deleted = true;
-                       }
-               }
-       }
-}
-
-static inline void cts_contact_remove_dup_data_event(GSList *events)
-{
-       GSList *cur1, *cur2;
-       cts_event *event1, *event2;
-
-       for (cur1=events;cur1;cur1=cur1->next) {
-               event1 = cur1->data;
-               if (NULL == event1 || event1->deleted)
-                       continue;
-               for (cur2=events;cur2;cur2=cur2->next) {
-                       event2 = cur2->data;
-                       if(NULL == event2 || event1 == event2)
-                               continue;
-                       if (!event2->deleted && event1->type == event2->type &&
-                                       event1->date == event2->date) {
-                               event2->deleted = true;
-                       }
-               }
-       }
-}
-
-
-static inline void cts_contact_remove_dup_data_IM(GSList *IMs)
-{
-       GSList *cur1, *cur2;
-       cts_messenger *im1, *im2;
-
-       for (cur1=IMs;cur1;cur1=cur1->next) {
-               im1 = cur1->data;
-               if (NULL == im1 || im1->deleted)
-                       continue;
-               for (cur2=IMs;cur2;cur2=cur2->next) {
-                       im2 = cur2->data;
-                       if(NULL == im2 || im1 == im2)
-                               continue;
-                       if (!im2->deleted && im1->type == im2->type &&
-                                       !cts_safe_strcmp(im1->im_id, im2->im_id) &&
-                                       !cts_safe_strcmp(im1->svc_name, im2->svc_name)) {
-                               im2->deleted = true;
-                       }
-               }
-       }
-}
-
-
-static inline void cts_contact_remove_dup_data_web(GSList *webs)
-{
-       GSList *cur1, *cur2;
-       cts_web *web1, *web2;
-
-       for (cur1=webs;cur1;cur1=cur1->next) {
-               web1 = cur1->data;
-               if (NULL == web1 || web1->deleted)
-                       continue;
-               for (cur2=webs;cur2;cur2=cur2->next) {
-                       web2 = cur2->data;
-                       if(NULL == web2 || web1 == web2)
-                               continue;
-                       if (!web2->deleted && web1->type == web2->type &&
-                                       !cts_safe_strcmp(web1->url, web2->url)) {
-                               web2->deleted = true;
-                       }
-               }
-       }
-}
-
-
-static inline void cts_contact_remove_dup_data_nick(GSList *nicks)
-{
-       GSList *cur1, *cur2;
-       cts_nickname *nick1, *nick2;
-
-       for (cur1=nicks;cur1;cur1=cur1->next) {
-               nick1 = cur1->data;
-               if (NULL == nick1 || nick1->deleted)
-                       continue;
-               for (cur2=nicks;cur2;cur2=cur2->next) {
-                       nick2 = cur2->data;
-                       if(NULL == nick2 || nick1 == nick2)
-                               continue;
-                       if (!nick2->deleted && !cts_safe_strcmp(nick1->nick, nick2->nick)) {
-                               nick2->deleted = true;
-                       }
-               }
-       }
-}
-
-
-static inline void cts_contact_remove_dup_data_postal(GSList *postals)
-{
-       GSList *cur1, *cur2;
-       cts_postal *addr1, *addr2;
-
-       for (cur1=postals;cur1;cur1=cur1->next) {
-               addr1 = cur1->data;
-               if (NULL == addr1 || addr1->deleted)
-                       continue;
-               for (cur2=postals;cur2;cur2=cur2->next) {
-                       addr2 = cur2->data;
-                       if(NULL == addr2 || addr1 == addr2)
-                               continue;
-                       if (!addr2->deleted && addr1->type == addr2->type &&
-                                       !cts_safe_strcmp(addr1->pobox, addr2->pobox) &&
-                                       !cts_safe_strcmp(addr1->postalcode, addr2->postalcode) &&
-                                       !cts_safe_strcmp(addr1->region, addr2->region) &&
-                                       !cts_safe_strcmp(addr1->locality, addr2->locality) &&
-                                       !cts_safe_strcmp(addr1->street, addr2->street) &&
-                                       !cts_safe_strcmp(addr1->extended, addr2->extended) &&
-                                       !cts_safe_strcmp(addr1->country, addr2->country)) {
-                               addr2->deleted = true;
-                       }
-               }
-       }
-}
-
-static inline int cts_insert_contact(int addressbook_id, contact_t *contact)
-{
-       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);
-
-       //Insert Data
-       ret = cts_insert_contact_data(CTS_DATA_FIELD_ALL, contact);
-       retvm_if(CTS_SUCCESS != ret, ret, "cts_insert_contact_data() Failed(%d)", ret);
-
-       //Insert group Info
-       if (contact->grouprelations)
-       {
-               rel_changed = cts_insert_contact_grouprel(addressbook_id, contact->base->id,
-                               contact->grouprelations);
-               retvm_if(rel_changed < CTS_SUCCESS, rel_changed, "cts_insert_contact_grouprel() Failed(%d)", rel_changed);
-       }
-
-       // default setting
-       if (!contact->default_num || !contact->default_email)
-               ret = cts_set_first_id_for_default(contact);
-       retvm_if(CTS_SUCCESS != ret, ret, "cts_set_first_id_for_default() Failed(%d)", ret);
-
-       //insert contact table
-       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, 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, %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");
-
-       if (contact->base->uid)
-               cts_stmt_bind_text(stmt, 1, contact->base->uid);
-       if (contact->base->ringtone_path)
-               cts_stmt_bind_text(stmt, 2, contact->base->ringtone_path);
-       if (contact->base->note)
-               cts_stmt_bind_text(stmt, 3, contact->base->note);
-
-       normal_img[0] = '\0';
-       if (contact->base->img_path) {
-               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_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_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_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);
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_SUCCESS != ret) {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               return ret;
-       }
-       cts_stmt_finalize(stmt);
-
-       if (rel_changed)
-               return rel_changed;
-       else
-               return CTS_SUCCESS;
-}
-
-
-API int contacts_svc_insert_contact(int addressbook_id, CTSstruct* contact)
-{
-       int ret;
-       contact_t *record = (contact_t *)contact;;
-
-       CTS_FN_CALL;
-
-       retv_if(NULL == contact, CTS_ERR_ARG_NULL);
-       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);
-
-       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);
-
-       ret = cts_db_get_next_id(CTS_TABLE_CONTACTS);
-       if (ret < CTS_SUCCESS)
-       {
-               ERR("cts_db_get_next_id() Failed(%d)", ret);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-
-       CTS_DBG("index = %d.", ret);
-
-       if (!record->base) {
-               record->base = (cts_ct_base*)contacts_svc_value_new(CTS_VALUE_CONTACT_BASE_INFO);
-
-               if (NULL == record->base)
-               {
-                       ERR("contacts_svc_value_new() Failed");
-                       contacts_svc_end_trans(false);
-                       return CTS_ERR_OUT_OF_MEMORY;
-               }
-       }
-
-       record->base->id = ret;
-       record->base->addrbook_id = addressbook_id;
-       ret = cts_insert_contact(addressbook_id, record);
-       if (ret < CTS_SUCCESS)
-       {
-               ERR("cts_insert_contact() Failed(%d)", ret);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-
-       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);
-
-       CTS_END_TIME_CHECK();
-       return record->base->id;
-}
-
-API int contacts_svc_delete_contact(int index)
-{
-       CTS_FN_CALL;
-       int ret, addrbook_id;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       CTS_START_TIME_CHECK;
-
-       snprintf(query, sizeof(query),
-                       "SELECT addrbook_id FROM %s WHERE contact_id = %d",
-                       CTS_TABLE_CONTACTS, index);
-       addrbook_id = cts_query_get_first_int_result(query);
-       retvm_if(addrbook_id < CTS_SUCCESS, addrbook_id,
-                       "The index(%d) is Invalid(%d)", index, addrbook_id);
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       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_contact_delete_image_file(NORMAL) Failed(%d)", ret);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-       ret = cts_contact_delete_image_file(CTS_IMG_FULL, index);
-       warn_if(CTS_SUCCESS != ret && CTS_ERR_DB_RECORD_NOT_FOUND != 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);
-       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), "INSERT INTO %s VALUES(%d, %d, %d)",
-                       CTS_TABLE_DELETEDS, index, addrbook_id, 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;
-       }
-
-       cts_set_contact_noti();
-
-       ret = contacts_svc_end_trans(true);
-       CTS_END_TIME_CHECK();
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-static inline int cts_delete_record_by_id(const char *table, int id)
-{
-       int ret;
-       char query[CTS_SQL_MIN_LEN] = {0};
-
-       retv_if(NULL == table, CTS_ERR_ARG_NULL);
-
-       snprintf(query, sizeof(query), "DELETE FROM %s WHERE id=%d", table, id);
-
-       ret = cts_query_exec(query);
-       retvm_if(ret, ret, "cts_query_exec() Failed(%d)", ret);
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_update_contact_data_number(
-               cts_stmt stmt, int contact_id, GSList* number_list)
-{
-       CTS_FN_CALL;
-
-       int ret, default_num=0, mobile_num=0;
-       GSList *added_numbers=NULL, *number_repeat = number_list;
-       cts_number *number_data;
-
-       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
-       retv_if(NULL == number_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               if (NULL != (number_data = (cts_number *)number_repeat->data))
-               {
-                       if (!number_data->id){
-                               if (!number_data->deleted)
-                                       added_numbers = g_slist_append(added_numbers, number_data);
-                               number_repeat = g_slist_next(number_repeat);
-                               continue;
-                       }
-                       if (number_data->deleted || NULL == number_data->number) {
-                               ret = cts_delete_record_by_id(CTS_TABLE_DATA, number_data->id);
-                               retvm_if(ret, ret, "cts_delete_record_by_id() Failed(%d)", ret);
-                       }
-                       else
-                       {
-                               int cnt = 1;
-                               const char *normal_num;
-                               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 (0 < ret) {
-                                       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);
-                               retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-
-                               if (number_data->is_default)
-                                       default_num = number_data->id;
-                               else if (!default_num && CTS_NUM_TYPE_CELL & number_data->type && !mobile_num)
-                                       mobile_num = number_data->id;
-                               cts_stmt_reset(stmt);
-                       }
-               }
-               number_repeat = g_slist_next(number_repeat);
-       }while(number_repeat);
-
-       if (added_numbers) {
-               contact_t temp;
-               cts_ct_base base;
-               temp.base = &base;
-               temp.base->id = contact_id;
-               temp.numbers = added_numbers;
-
-               ret = cts_insert_contact_data(CTS_DATA_FIELD_NUMBER, &temp);
-               if (temp.default_num) {
-                       number_repeat = added_numbers;
-                       while (number_repeat) {
-                               if (NULL != (number_data = (cts_number *)number_repeat->data)) {
-                                       if (number_data->is_default) {
-                                               default_num = temp.default_num;
-                                               break;
-                                       }
-                               }
-                               number_repeat = number_repeat->next;
-                       }
-                       if(!default_num)
-                               mobile_num = temp.default_num;
-               }
-               g_slist_free(added_numbers);
-               retvm_if(CTS_SUCCESS != ret, ret, "cts_insert_contact_data() Failed(%d)", ret);
-       }
-
-       if (default_num)
-               return default_num;
-       else
-               return mobile_num;
-}
-
-static inline int cts_update_contact_data_email(
-               cts_stmt stmt, int contact_id, GSList* email_list)
-{
-       CTS_FN_CALL;
-
-       int ret, default_email=0;
-       GSList *added_emails=NULL, *email_repeat = email_list;
-       cts_email *email_data;
-
-       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
-       retv_if(NULL == email_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               if (NULL != (email_data = (cts_email *)email_repeat->data))
-               {
-                       if (!email_data->id){
-                               if (!email_data->deleted)
-                                       added_emails = g_slist_append(added_emails, email_data);
-                               email_repeat = g_slist_next(email_repeat);
-                               continue;
-                       }
-                       if (email_data->deleted || NULL == email_data->email_addr) {
-                               ret = cts_delete_record_by_id(CTS_TABLE_DATA, email_data->id);
-                               retvm_if(ret, ret, "cts_delete_record_by_id() Failed(%d)", ret);
-                       }
-                       else
-                       {
-                               int cnt = 1;
-
-                               cts_stmt_bind_int(stmt, cnt++, email_data->type);
-                               cts_stmt_bind_text(stmt, cnt++, email_data->email_addr);
-                               cts_stmt_bind_int(stmt, CTS_UPDATE_ID_LOC, email_data->id);
-
-                               ret = cts_stmt_step(stmt);
-                               retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-
-                               if (email_data->is_default)
-                                       default_email = email_data->id;
-                               cts_stmt_reset(stmt);
-                       }
-               }
-               email_repeat = g_slist_next(email_repeat);
-       }while(email_repeat);
-
-       if (added_emails) {
-               contact_t temp;
-               cts_ct_base base;
-               temp.base = &base;
-               temp.base->id = contact_id;
-               temp.emails = added_emails;
-
-               ret = cts_insert_contact_data(CTS_DATA_FIELD_EMAIL, &temp);
-               if (temp.default_email) {
-                       email_repeat = added_emails;
-                       while (email_repeat) {
-                               if (NULL != (email_data = (cts_email *)email_repeat->data)) {
-                                       if (email_data->is_default) {
-                                               default_email = temp.default_email;
-                                               break;
-                                       }
-                               }
-                               email_repeat = email_repeat->next;
-                       }
-               }
-               g_slist_free(added_emails);
-               retvm_if(CTS_SUCCESS != ret, ret, "cts_insert_contact_data() Failed(%d)", ret);
-       }
-
-       return default_email;
-}
-
-static inline int cts_update_contact_grouprel(cts_ct_base *base_info,
-               GSList* group_list)
-{
-       CTS_FN_CALL;
-
-       int ret;
-       GSList *group_repeat = group_list;
-       cts_group *group_data;
-       int rel_changed = 0;
-
-       retv_if(NULL == group_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               group_data = group_repeat->data;
-               group_repeat = group_repeat->next;
-
-               if (NULL == group_data)
-                       continue;
-
-               if (group_data->deleted) {
-                       ret = cts_group_unset_relation(group_data->id, base_info->id);
-                       retvm_if(ret, ret, "cts_group_unset_relation() Failed(%d)", ret);
-               }
-               else {
-                       if (group_data->vcard_group) {
-                               int found_id;
-                               found_id = contacts_svc_find_group(base_info->addrbook_id, group_data->vcard_group);
-                               if (0 < found_id)
-                                       group_data->id = found_id;
-                               else if (found_id == CTS_ERR_DB_RECORD_NOT_FOUND) {
-                                       CTSvalue *group;
-                                       group = contacts_svc_value_new(CTS_VALUE_GROUP);
-
-                                       contacts_svc_value_set_str(group, CTS_GROUP_VAL_NAME_STR, group_data->vcard_group);
-                                       found_id = contacts_svc_insert_group(base_info->addrbook_id, group);
-                                       if (found_id < CTS_SUCCESS)
-                                               ERR("contacts_svc_insert_group() Failed\n");
-                                       else
-                                               group_data->id = found_id;
-
-                                       contacts_svc_value_free(group);
-                               }
-                       }
-                       if (group_data->id) {
-                               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);
-
-       if (rel_changed)
-               return rel_changed;
-       else
-               return CTS_SUCCESS;
-}
-
-static inline int cts_update_contact_data_event(
-               cts_stmt stmt, int contact_id, GSList* event_list)
-{
-       CTS_FN_CALL;
-
-       int ret;
-       GSList *added_event=NULL, *event_repeat = event_list;
-       cts_event *event_data;
-
-       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
-       retv_if(NULL == event_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               if (NULL != (event_data = (cts_event *)event_repeat->data))
-               {
-                       if (!event_data->id){
-                               if (!event_data->deleted)
-                                       added_event = g_slist_append(added_event, event_data);
-                               event_repeat = g_slist_next(event_repeat);
-                               continue;
-                       }
-                       if (event_data->deleted) {
-                               ret = cts_delete_record_by_id(CTS_TABLE_DATA, event_data->id);
-                               retvm_if(ret, ret, "cts_delete_record_by_id() Failed(%d)", ret);
-                       }
-                       else
-                       {
-                               cts_stmt_bind_event(stmt, 1, event_data);
-                               cts_stmt_bind_int(stmt, CTS_UPDATE_ID_LOC, event_data->id);
-
-                               ret = cts_stmt_step(stmt);
-                               retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-                               cts_stmt_reset(stmt);
-                       }
-               }
-               event_repeat = g_slist_next(event_repeat);
-       }while(event_repeat);
-
-       if (added_event) {
-               contact_t temp;
-               cts_ct_base base;
-               temp.base = &base;
-               temp.base->id = contact_id;
-               temp.events = added_event;
-
-               ret = cts_insert_contact_data(CTS_DATA_FIELD_EVENT, &temp);
-               g_slist_free(added_event);
-               retvm_if(CTS_SUCCESS != ret, ret,
-                               "cts_insert_contact_data() Failed(%d)", ret);
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_update_contact_data_messenger(
-               cts_stmt stmt, int contact_id, GSList* messenger_list)
-{
-       CTS_FN_CALL;
-
-       int ret;
-       GSList *added_messenger=NULL, *messenger_repeat = messenger_list;
-       cts_messenger *messenger_data;
-
-       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
-       retv_if(NULL == messenger_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               if (NULL != (messenger_data = (cts_messenger *)messenger_repeat->data))
-               {
-                       if (!messenger_data->id){
-                               if (!messenger_data->deleted)
-                                       added_messenger = g_slist_append(added_messenger, messenger_data);
-                               messenger_repeat = g_slist_next(messenger_repeat);
-                               continue;
-                       }
-                       if (messenger_data->deleted || NULL == messenger_data->im_id)
-                       {
-                               ret = cts_delete_record_by_id(CTS_TABLE_DATA, messenger_data->id);
-                               retvm_if(ret, ret, "cts_delete_record_by_id() Failed(%d)", ret);
-                       }
-                       else
-                       {
-                               cts_stmt_bind_messenger(stmt, 1, messenger_data);
-                               cts_stmt_bind_int(stmt, CTS_UPDATE_ID_LOC, messenger_data->id);
-
-                               ret = cts_stmt_step(stmt);
-                               retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-                               cts_stmt_reset(stmt);
-                       }
-               }
-               messenger_repeat = g_slist_next(messenger_repeat);
-       }while(messenger_repeat);
-
-       if (added_messenger) {
-               contact_t temp;
-               cts_ct_base base;
-               temp.base = &base;
-               temp.base->id = contact_id;
-               temp.messengers = added_messenger;
-
-               ret = cts_insert_contact_data(CTS_DATA_FIELD_MESSENGER, &temp);
-               g_slist_free(added_messenger);
-               retvm_if(CTS_SUCCESS != ret, ret,
-                               "cts_insert_contact_data() Failed(%d)", ret);
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_update_contact_data_postal(
-               cts_stmt stmt, int contact_id, GSList* postal_list)
-{
-       CTS_FN_CALL;
-
-       int ret;
-       GSList *added_postal=NULL, *postal_repeat = postal_list;
-       cts_postal *postal_data;
-
-       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
-       retv_if(NULL == postal_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               if (NULL != (postal_data = (cts_postal *)postal_repeat->data))
-               {
-                       if (!postal_data->id){
-                               if (!postal_data->deleted)
-                                       added_postal = g_slist_append(added_postal, postal_data);
-                               postal_repeat = g_slist_next(postal_repeat);
-                               continue;
-                       }
-                       if (postal_data->deleted || !(postal_data->country || postal_data->pobox
-                                               || postal_data->postalcode || postal_data->region
-                                               || postal_data->locality || postal_data->street || postal_data->extended))
-                       {
-                               ret = cts_delete_record_by_id(CTS_TABLE_DATA, postal_data->id);
-                               retvm_if(ret, ret, "cts_delete_record_by_id() Failed(%d)", ret);
-                       }
-                       else
-                       {
-                               cts_stmt_bind_postal(stmt, 1, postal_data);
-                               cts_stmt_bind_int(stmt, CTS_UPDATE_ID_LOC, postal_data->id);
-
-                               ret = cts_stmt_step(stmt);
-                               retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-                               cts_stmt_reset(stmt);
-                       }
-               }
-               postal_repeat = g_slist_next(postal_repeat);
-       }while(postal_repeat);
-
-       if (added_postal) {
-               contact_t temp;
-               cts_ct_base base;
-               temp.base = &base;
-               temp.base->id = contact_id;
-               temp.postal_addrs = added_postal;
-
-               ret = cts_insert_contact_data(CTS_DATA_FIELD_POSTAL, &temp);
-               g_slist_free(added_postal);
-               retvm_if(CTS_SUCCESS != ret, ret,
-                               "cts_insert_contact_data() Failed(%d)", ret);
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_update_contact_data_web(
-               cts_stmt stmt, int contact_id, GSList* web_list)
-{
-       CTS_FN_CALL;
-
-       int ret;
-       GSList *added_web=NULL, *web_repeat = web_list;
-       cts_web *web_data;
-
-       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
-       retv_if(NULL == web_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               if (NULL != (web_data = (cts_web *)web_repeat->data))
-               {
-                       if (!web_data->id){
-                               if (!web_data->deleted)
-                                       added_web = g_slist_append(added_web, web_data);
-                               web_repeat = g_slist_next(web_repeat);
-                               continue;
-                       }
-                       if (web_data->deleted || NULL == web_data->url)
-                       {
-                               ret = cts_delete_record_by_id(CTS_TABLE_DATA, web_data->id);
-                               retvm_if(ret, ret, "cts_delete_record_by_id() Failed(%d)", ret);
-                       }
-                       else
-                       {
-                               cts_stmt_bind_web(stmt, 1, web_data);
-                               cts_stmt_bind_int(stmt, CTS_UPDATE_ID_LOC, web_data->id);
-
-                               ret = cts_stmt_step(stmt);
-                               retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-                               cts_stmt_reset(stmt);
-                       }
-               }
-               web_repeat = g_slist_next(web_repeat);
-       }while(web_repeat);
-
-       if (added_web) {
-               contact_t temp;
-               cts_ct_base base;
-               temp.base = &base;
-               temp.base->id = contact_id;
-               temp.web_addrs = added_web;
-
-               ret = cts_insert_contact_data(CTS_DATA_FIELD_WEB, &temp);
-               g_slist_free(added_web);
-               retvm_if(CTS_SUCCESS != ret, ret,
-                               "cts_insert_contact_data() Failed(%d)", ret);
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_update_contact_data_nick(
-               cts_stmt stmt, int contact_id, GSList* nick_list)
-{
-       CTS_FN_CALL;
-
-       int ret;
-       GSList *added_nick=NULL, *nick_repeat = nick_list;
-       cts_nickname *nick_data;
-
-       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
-       retv_if(NULL == nick_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               if (NULL != (nick_data = (cts_nickname *)nick_repeat->data))
-               {
-                       if (!nick_data->id){
-                               if (!nick_data->deleted)
-                                       added_nick = g_slist_append(added_nick, nick_data);
-                               nick_repeat = g_slist_next(nick_repeat);
-                               continue;
-                       }
-                       if (nick_data->deleted || NULL == nick_data->nick)
-                       {
-                               ret = cts_delete_record_by_id(CTS_TABLE_DATA, nick_data->id);
-                               retvm_if(ret, ret, "cts_delete_record_by_id() Failed(%d)", ret);
-                       }
-                       else
-                       {
-                               cts_stmt_bind_text(stmt, 2, nick_data->nick);
-                               cts_stmt_bind_int(stmt, CTS_UPDATE_ID_LOC, nick_data->id);
-
-                               ret = cts_stmt_step(stmt);
-                               retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-                               cts_stmt_reset(stmt);
-                       }
-               }
-               nick_repeat = g_slist_next(nick_repeat);
-       }while(nick_repeat);
-
-       if (added_nick) {
-               contact_t temp;
-               cts_ct_base base;
-               temp.base = &base;
-               temp.base->id = contact_id;
-               temp.nicknames = added_nick;
-
-               ret = cts_insert_contact_data(CTS_DATA_FIELD_NICKNAME, &temp);
-               g_slist_free(added_nick);
-               retvm_if(CTS_SUCCESS != ret, ret,
-                               "cts_insert_contact_data() Failed(%d)", ret);
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_update_contact_data_extend(
-               cts_stmt stmt, int contact_id, GSList* extend_list)
-{
-       CTS_FN_CALL;
-
-       int ret;
-       GSList *added_extend=NULL, *extend_repeat = extend_list;
-       cts_extend *extend_data;
-
-       retv_if(NULL == stmt, CTS_ERR_ARG_NULL);
-       retv_if(NULL == extend_list, CTS_ERR_ARG_NULL);
-
-       do
-       {
-               if (NULL != (extend_data = (cts_extend *)extend_repeat->data))
-               {
-                       if (!extend_data->id){
-                               if (!extend_data->deleted)
-                                       added_extend = g_slist_append(added_extend, extend_data);
-                               extend_repeat = g_slist_next(extend_repeat);
-                               continue;
-                       }
-                       if (extend_data->deleted)
-                       {
-                               ret = cts_delete_record_by_id(CTS_TABLE_DATA, extend_data->id);
-                               retvm_if(ret, ret, "cts_delete_record_by_id() Failed(%d)", ret);
-                       }
-                       else
-                       {
-                               cts_stmt_bind_extend(stmt, 1, extend_data);
-                               cts_stmt_bind_int(stmt, CTS_UPDATE_ID_LOC, extend_data->id);
-
-                               ret = cts_stmt_step(stmt);
-                               retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-                               cts_stmt_reset(stmt);
-                       }
-               }
-               extend_repeat = g_slist_next(extend_repeat);
-       }while(extend_repeat);
-
-       if (added_extend) {
-               contact_t temp;
-               cts_ct_base base;
-               temp.base = &base;
-               temp.base->id = contact_id;
-               temp.extended_values = added_extend;
-
-               ret = cts_insert_contact_data(CTS_DATA_FIELD_EXTEND_ALL, &temp);
-               g_slist_free(added_extend);
-               retvm_if(CTS_SUCCESS != ret, ret,
-                               "cts_insert_contact_data() Failed(%d)", ret);
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_update_contact_data_name(cts_stmt stmt,
-               cts_name *name)
-{
-       int ret, cnt=1;
-       cts_name normalize_name={0};
-       char *tmp_display, *tmp_first, *tmp_last;
-       char display[CTS_SQL_MAX_LEN]={0};
-       char lookup[CTS_SQL_MAX_LEN]={0};
-       char reverse_lookup[CTS_SQL_MAX_LEN]={0};
-
-       retvm_if(!name->id, CTS_ERR_ARG_INVALID, "name of contact has no ID.");
-       cts_stmt_bind_int(stmt, CTS_UPDATE_ID_LOC, name->id);
-
-       //Update name search info
-       char normal_name[CTS_NN_MAX][CTS_SQL_MAX_LEN]={{0},{0},{0}};
-
-       tmp_display = name->display;
-       tmp_first = name->first;
-       tmp_last = name->last;
-
-       if (name->display) {
-               ret = cts_normalize_name(name, normal_name, true);
-               retvm_if(ret < CTS_SUCCESS, ret, "cts_normalize_name() Failed(%d)", ret);
-               if (normal_name[CTS_NN_FIRST][0])
-                       normalize_name.display = normal_name[CTS_NN_FIRST];
-               else
-                       name->display = NULL;
-       }
-
-       if (NULL == name->display) {
-               ret = cts_normalize_name(name, normal_name, false);
-               retvm_if(ret < CTS_SUCCESS, ret, "cts_normalize_name() Failed(%d)", ret);
-
-               switch (ret)
-               {
-               case CTS_LANG_KOREAN:
-                       snprintf(display, sizeof(display), "%s%s",
-                                       SAFE_STR(name->last), SAFE_STR(name->first));
-
-                       strncat(normal_name[CTS_NN_LAST], normal_name[CTS_NN_FIRST],
-                                       sizeof(normal_name[CTS_NN_LAST]));
-
-                       name->display = display;
-                       normalize_name.display = normal_name[CTS_NN_LAST];
-                       break;
-               case CTS_LANG_ENGLISH:
-               default:
-                       if (normal_name[CTS_NN_FIRST][0])
-                               normalize_name.first = normal_name[CTS_NN_FIRST];
-                       else
-                               name->first = NULL;
-
-                       if (normal_name[CTS_NN_LAST][0])
-                               normalize_name.last = normal_name[CTS_NN_LAST];
-                       else
-                               name->last = NULL;
-
-                       break;
-               }
-       }
-
-       if (cts_get_default_language() == ret)
-               cts_stmt_bind_int(stmt, cnt, CTS_LANG_DEFAULT);
-       else
-               cts_stmt_bind_int(stmt, cnt, ret);
-       cnt = cts_stmt_bind_name(stmt, cnt, name);
-
-       name->display = tmp_display;
-       name->first = tmp_first;
-       name->last = tmp_last;
-
-       ret = cts_make_name_lookup(CTS_ORDER_NAME_FIRSTLAST, &normalize_name,
-                       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));
-       retvm_if(CTS_SUCCESS != ret, ret, "cts_make_name_lookup() Failed(%d)", ret);
-
-       CTS_DBG("lookup=%s(%d), reverse_lookup=%s(%d)",
-                       lookup, strlen(lookup), reverse_lookup, strlen(reverse_lookup));
-
-       cts_stmt_bind_text(stmt, cnt++, lookup);
-       cts_stmt_bind_text(stmt, cnt++, reverse_lookup);
-       cts_stmt_bind_text(stmt, cnt, normal_name[CTS_NN_SORTKEY]);
-
-       ret = cts_stmt_step(stmt);
-       retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_update_contact_data(contact_t *contact)
-{
-       int ret;
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       // Use stmt query for DATA table
-       snprintf(query, sizeof(query), "UPDATE %s SET data1=?, data2=?, data3=?, data4=?,"
-                       "data5=?, data6=?, data7=?, data8=?, data9=?, data10=? WHERE id=?",
-                       CTS_TABLE_DATA);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       //Update the name
-       if (contact->name && contact->name->is_changed)
-       {
-               ret = cts_update_contact_data_name(stmt, contact->name);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_update_contact_data_name() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-               cts_stmt_reset(stmt);
-       }
-
-       //Update the company
-       if (contact->company)
-       {
-               cts_company *com = contact->company;
-               if (!com->id) {
-                       ret = cts_insert_contact_data(CTS_DATA_FIELD_COMPANY, contact);
-                       retvm_if(CTS_SUCCESS != ret, ret,
-                                       "cts_insert_contact_data(CTS_DATA_FIELD_COMPANY) Failed(%d)", ret);
-               }
-               else {
-                       if (com->name || com->department || com->jot_title || com->role || com->assistant_name) {
-                               cts_stmt_bind_company(stmt, 1, com);
-                               cts_stmt_bind_int(stmt, CTS_UPDATE_ID_LOC, com->id);
-
-                               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);
-                       }
-                       else {
-                               ret = cts_delete_record_by_id(CTS_TABLE_DATA, com->id);
-                               retvm_if(ret, ret, "cts_delete_record_by_id() Failed(%d)", ret);
-                       }
-               }
-       }
-
-       //Update the events
-       if (contact->events)
-       {
-               ret = cts_update_contact_data_event(stmt, contact->base->id, contact->events);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_update_contact_data_event() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-       }
-
-       //Update the messengers
-       if (contact->messengers)
-       {
-               ret = cts_update_contact_data_messenger(stmt, contact->base->id,
-                               contact->messengers);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_update_contact_data_messenger() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-       }
-
-       //Update the postals
-       if (contact->postal_addrs)
-       {
-               ret = cts_update_contact_data_postal(stmt, contact->base->id,
-                               contact->postal_addrs);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_update_contact_data_postal() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-       }
-
-       //Update the Web addrs
-       if (contact->web_addrs)
-       {
-               ret = cts_update_contact_data_web(stmt, contact->base->id, contact->web_addrs);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_update_contact_data_web() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-       }
-
-       //Update the Nick Names
-       if (contact->nicknames)
-       {
-               ret = cts_update_contact_data_nick(stmt, contact->base->id, contact->nicknames);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_update_contact_data_nick() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-       }
-
-       //Update the Numbers
-       if (contact->numbers)
-       {
-               ret = cts_update_contact_data_number(stmt, contact->base->id, contact->numbers);
-               if (ret < CTS_SUCCESS) {
-                       ERR("cts_update_contact_data_number() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-               contact->default_num = ret;
-       }
-
-       //Update the Emails
-       if (contact->emails)
-       {
-               ret = cts_update_contact_data_email(stmt, contact->base->id, contact->emails);
-               if (ret < CTS_SUCCESS) {
-                       ERR("cts_update_contact_data_email() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-               contact->default_email = ret;
-       }
-
-       //Update the extended values
-       if (contact->extended_values)
-       {
-               ret = cts_update_contact_data_extend(stmt, contact->base->id,
-                               contact->extended_values);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_update_contact_data_extend() Failed(%d)", ret);
-                       cts_stmt_finalize(stmt);
-                       return ret;
-               }
-       }
-
-       cts_stmt_finalize(stmt);
-
-       return CTS_SUCCESS;
-}
-
-
-static inline void cts_update_contact_handle_no_name(contact_t *contact)
-{
-       if (NULL == contact->name) {
-               contact->name = calloc(1, sizeof(cts_name));
-               contact->name->embedded = true;
-       } else if (contact->name->first || contact->name->last) {
-               return;
-       }
-
-       if (contact->name->display) {
-               free(contact->name->display);
-               contact->name->display = NULL;
-       }
-       contact->name->is_changed = true;
-
-       if (contact->company && contact->company->name) {
-               contact->name->display = strdup(contact->company->name);
-       } else {
-               char *temp;
-
-               temp = cts_contact_get_valid_first_number_or_email(contact->numbers, contact->emails);
-               contact->name->display = SAFE_STRDUP(temp);
-       }
-}
-
-
-static inline int cts_update_contact(contact_t *contact)
-{
-       int i, ret, len;
-       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",
-                       CTS_TABLE_CONTACTS, contact->base->id);
-       ret = cts_query_get_first_int_result(query);
-       retvm_if(1 != ret, CTS_ERR_DB_RECORD_NOT_FOUND,
-                       "The index(%d) is Invalid. %d Record(s) is(are) found", contact->base->id, ret);
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       cts_update_contact_handle_no_name(contact);
-
-       //update data
-       ret = cts_update_contact_data(contact);
-       if (CTS_SUCCESS != ret)
-       {
-               ERR("cts_update_contact_data() Failed(%d)", ret);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-
-       //update group relation Info
-       if (contact->grouprelations)
-       {
-               rel_changed = cts_update_contact_grouprel(contact->base, contact->grouprelations);
-               if (rel_changed < CTS_SUCCESS)
-               {
-                       ERR("cts_update_contact_grouprel() Failed(%d)", rel_changed);
-                       contacts_svc_end_trans(false);
-                       return rel_changed;
-               }
-       }
-
-       // default setting
-       if (!contact->default_num || !contact->default_email) {
-               ret = cts_set_first_id_for_default(contact);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_set_first_id_for_default() Failed(%d)", ret);
-                       contacts_svc_end_trans(false);
-                       return ret;
-               }
-       }
-       len = snprintf(query, sizeof(query),
-                       "UPDATE %s SET changed_ver=%d, changed_time=%d, "
-                       "default_num=%d, default_email=%d",
-                       CTS_TABLE_CONTACTS, cts_get_next_ver(), (int)time(NULL),
-                       contact->default_num, contact->default_email);
-
-       if (contact->base->uid_changed)
-               len += snprintf(query+len, sizeof(query)-len, ", uid=?");
-
-       if (contact->base->ringtone_changed)
-               len += snprintf(query+len, sizeof(query)-len, ", ringtone=?");
-
-       if (contact->base->note_changed)
-               len += snprintf(query+len, sizeof(query)-len, ", note=?");
-
-       if (contact->base->img_changed ||
-                       (NULL == contact->base->img_path && contact->base->vcard_img_path))
-               len += snprintf(query+len, sizeof(query)-len, ", image0=?");
-
-       if (contact->base->full_img_changed)
-               len += snprintf(query+len, sizeof(query)-len, ", image1=?");
-
-       snprintf(query+len, sizeof(query)-len,
-                       " WHERE contact_id=%d", contact->base->id);
-
-       cts_stmt stmt = cts_query_prepare(query);
-       if (NULL == stmt) {
-               ERR("cts_query_prepare() Failed");
-               contacts_svc_end_trans(false);
-               return CTS_ERR_DB_FAILED;
-       }
-
-       i=1;
-       if (contact->base->uid_changed) {
-               if (contact->base->uid)
-                       cts_stmt_bind_text(stmt, i, contact->base->uid);
-               i++;
-       }
-       if (contact->base->ringtone_changed) {
-               if (contact->base->ringtone_path)
-                       cts_stmt_bind_text(stmt, i, contact->base->ringtone_path);
-               i++;
-       }
-       if (contact->base->note_changed) {
-               if (contact->base->note)
-                       cts_stmt_bind_text(stmt, i, contact->base->note);
-               i++;
-       }
-
-       if (contact->base->img_changed ||
-                       (NULL == contact->base->img_path && contact->base->vcard_img_path)) {
-               normal_img[0] = '\0';
-               if (contact->base->img_path) {
-                       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_contact_update_image_file() Failed(%d)", ret);
-                               cts_stmt_finalize(stmt);
-                               contacts_svc_end_trans(false);
-                               return ret;
-                       }
-                       if (*normal_img)
-                               cts_stmt_bind_text(stmt, i, normal_img);
-                       i++;
-               } else {
-                       if (contact->base->vcard_img_path) {
-                               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_contact_delete_image_file(CTS_IMG_NORMAL, contact->base->id);
-                               if (CTS_SUCCESS != ret) {
-                                       ERR("cts_contact_delete_image_file() Failed(%d)", ret);
-                                       cts_stmt_finalize(stmt);
-                                       contacts_svc_end_trans(false);
-                                       return ret;
-                               }
-                       }
-               }
-       }
-
-       if (contact->base->full_img_changed) {
-               full_img[0] = '\0';
-               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++;
-       }
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_SUCCESS != ret)
-       {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-       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)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-API int contacts_svc_update_contact(CTSstruct* contact)
-{
-       int ret;
-       contact_t *record = (contact_t *)contact;
-
-       retv_if(NULL == contact, CTS_ERR_ARG_NULL);
-       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);
-
-       CTS_END_TIME_CHECK();
-       return ret;
-}
-
-static inline int cts_put_base_val(int op_code, int contact_id,
-               cts_ct_base *value)
-{
-       int ret;
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MIN_LEN] = {0};
-
-       retvm_if(CTS_VALUE_CONTACT_BASE_INFO != value->v_type, CTS_ERR_ARG_INVALID,
-                       "value has unknown type");
-       switch (op_code) {
-       case CTS_PUT_VAL_REPLACE_RINGTONE:
-               snprintf(query, sizeof(query),
-                               "UPDATE %s SET changed_ver=%d, changed_time=%d, "
-                               "ringtone=? WHERE contact_id=%d",
-                               CTS_TABLE_CONTACTS, cts_get_next_ver(), (int)time(NULL),
-                               contact_id);
-
-               stmt = cts_query_prepare(query);
-               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-               if (value->ringtone_path)
-                       cts_stmt_bind_text(stmt, 1, value->ringtone_path);
-               break;
-       case CTS_PUT_VAL_REPLACE_NOTE:
-               snprintf(query, sizeof(query),
-                               "UPDATE %s SET changed_ver=%d, changed_time=%d, "
-                               "note=? WHERE contact_id=%d",
-                               CTS_TABLE_CONTACTS, cts_get_next_ver(), (int)time(NULL),
-                               contact_id);
-
-               stmt = cts_query_prepare(query);
-               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-               if (value->note)
-                       cts_stmt_bind_text(stmt, 1, value->note);
-               break;
-       default:
-               ERR("Invalid parameter : The op_code(%d) is not supported", op_code);
-               return CTS_ERR_ARG_INVALID;
-       }
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_SUCCESS != ret)
-       {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               return ret;
-       }
-       cts_stmt_finalize(stmt);
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_put_number_val(int contact_id,
-               cts_number *number)
-{
-       int ret, default_id;
-       cts_stmt stmt = NULL;
-       char clean_num[CTS_NUMBER_MAX_LEN], query[CTS_SQL_MAX_LEN] = {0};
-       const char *normal_num;
-
-       retv_if(NULL == number->number, CTS_ERR_ARG_NULL);
-       retvm_if(CTS_VALUE_NUMBER != number->v_type, CTS_ERR_ARG_INVALID,
-                       "value has unknown type");
-
-       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);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       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) {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               return ret;
-       }
-       cts_stmt_finalize(stmt);
-
-       if (number->is_default) {
-               default_id = cts_db_get_last_insert_id();
-               snprintf(query, sizeof(query),
-                               "UPDATE %s SET changed_ver=%d, changed_time=%d, default_num=%d "
-                               "WHERE contact_id=%d",
-                               CTS_TABLE_CONTACTS, cts_get_next_ver(), (int)time(NULL),
-                               default_id, contact_id);
-       } else {
-               snprintf(query, sizeof(query),
-                               "UPDATE %s SET changed_ver=%d, changed_time=%d WHERE contact_id=%d",
-                               CTS_TABLE_CONTACTS, cts_get_next_ver(), (int)time(NULL),
-                               contact_id);
-       }
-
-       ret = cts_query_exec(query);
-       if (CTS_SUCCESS != ret) {
-               ERR("cts_query_exec() Failed(%d)", ret);
-               return ret;
-       }
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_put_email_val(int contact_id,
-               cts_email *email)
-{
-       int ret, default_id;
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       retv_if(NULL == email->email_addr, CTS_ERR_ARG_NULL);
-       retvm_if(CTS_VALUE_EMAIL != email->v_type, CTS_ERR_ARG_INVALID,
-                       "value has unknown type");
-
-       snprintf(query, sizeof(query),
-                       "INSERT INTO %s(contact_id, datatype, data1, data2) VALUES(%d, %d, %d, ?)",
-                       CTS_TABLE_DATA, contact_id, CTS_DATA_EMAIL, email->type);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       if (email->email_addr)
-               cts_stmt_bind_text(stmt, 1, email->email_addr);
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_SUCCESS != ret)
-       {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               return ret;
-       }
-       cts_stmt_finalize(stmt);
-
-       if (email->is_default) {
-               default_id = cts_db_get_last_insert_id();
-               snprintf(query, sizeof(query),
-                               "UPDATE %s SET changed_ver=%d, changed_time=%d, default_email=%d "
-                               "WHERE contact_id=%d",
-                               CTS_TABLE_CONTACTS, cts_get_next_ver(), (int)time(NULL),
-                               default_id, contact_id);
-       } else {
-               snprintf(query, sizeof(query),
-                               "UPDATE %s SET changed_ver=%d, changed_time=%d WHERE contact_id=%d",
-                               CTS_TABLE_CONTACTS, cts_get_next_ver(), (int)time(NULL),
-                               contact_id);
-       }
-
-       ret = cts_query_exec(query);
-       if (CTS_SUCCESS != ret) {
-               ERR("cts_query_exec() Failed(%d)", ret);
-               return ret;
-       }
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_put_contact_value(cts_put_contact_val_op op_code,
-               int contact_id, CTSvalue* value)
-{
-       CTS_FN_CALL;
-       int ret;
-
-       retv_if(NULL == value, CTS_ERR_ARG_NULL);
-       CTS_START_TIME_CHECK;
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       switch (op_code)
-       {
-       case CTS_PUT_VAL_REPLACE_RINGTONE:
-       case CTS_PUT_VAL_REPLACE_NOTE:
-               ret = cts_put_base_val(op_code, contact_id, (cts_ct_base *)value);
-               if (CTS_SUCCESS != ret)
-               {
-                       ERR("cts_update_contact_val_ringtone() Failed(%d)", ret);
-                       contacts_svc_end_trans(false);
-                       return ret;
-               }
-               break;
-       case CTS_PUT_VAL_ADD_NUMBER:
-               ret = cts_put_number_val(contact_id, (cts_number *)value);
-               if (CTS_SUCCESS != ret)
-               {
-                       ERR("cts_put_number_val() Failed(%d)", ret);
-                       contacts_svc_end_trans(false);
-                       return ret;
-               }
-               break;
-       case CTS_PUT_VAL_ADD_EMAIL:
-               ret = cts_put_email_val(contact_id, (cts_email *)value);
-               if (CTS_SUCCESS != ret)
-               {
-                       ERR("cts_put_email_val() Failed(%d)", ret);
-                       contacts_svc_end_trans(false);
-                       return ret;
-               }
-               break;
-       default:
-               ERR("Invalid parameter : The op_code(%d) is not supported", op_code);
-               contacts_svc_end_trans(false);
-               return CTS_ERR_ARG_INVALID;
-       }
-
-       cts_set_contact_noti();
-
-       ret = contacts_svc_end_trans(true);
-       CTS_END_TIME_CHECK();
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-static inline int cts_insert_myprofile_base(cts_stmt stmt, cts_ct_base *base)
-{
-       int ret;
-
-       retv_if(NULL == base, CTS_ERR_ARG_NULL);
-
-       cts_stmt_bind_int(stmt, 1, 0);
-       if (base->note)
-               cts_stmt_bind_text(stmt, 3, base->note);
-
-       ret = cts_stmt_step(stmt);
-       retvm_if(CTS_SUCCESS != ret, ret, "cts_stmt_step() Failed(%d)", ret);
-
-       cts_stmt_reset(stmt);
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_set_myprofile(contact_t *contact)
-{
-       int ret;
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MAX_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);
-
-       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");
-
-       if (contact->base) {
-               ret = cts_insert_myprofile_base(stmt, contact->base);
-               retvm_if(CTS_SUCCESS != ret, ret, "cts_insert_myprofile_base() Failed(%d)", ret);
-       }
-
-       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);
-       }
-
-       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);
-       }
-
-       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);
-       }
-
-       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);
-       }
-
-       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);
-       }
-
-       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);
-       }
-
-       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);
-       }
-
-       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);
-       }
-
-       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);
-       }
-
-       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);
-       }
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_set_myprofile(CTSstruct *contact)
-{
-       int ret;
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       ret = cts_set_myprofile((contact_t *)contact);
-       if (CTS_SUCCESS != ret) {
-               ERR("cts_set_myprofile() Failed(%d)", ret);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-
-       ret = contacts_svc_end_trans(true);
-       retvm_if(ret < CTS_SUCCESS, ret, "contacts_svc_end_trans() Failed(%d)", ret);
-
-       return CTS_SUCCESS;
-}
diff --git a/src/cts-contact.h b/src/cts-contact.h
deleted file mode 100755 (executable)
index f0dd35b..0000000
+++ /dev/null
@@ -1,421 +0,0 @@
-/*
- * 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_CONTACT_H__
-#define __CTS_CONTACT_H__
-
-enum{
-       CTS_GET_DATA_BY_CONTACT_ID,
-       CTS_GET_DATA_BY_ID
-};
-
-int cts_get_data_info(int op_code, int field, int index, contact_t *contact);
-
-//<!--
-/**
- * @defgroup   CONTACTS_SVC_NAME Contact Naming Rule
- * @ingroup    CONTACTS_SVC
- * @addtogroup CONTACTS_SVC_NAME
- * @{
- * - insert
- * @code
- * if (No Name) {
- *     if (Has "Company Name")
- *             Display Name = "Company Name";
- *     else if (Has "Number")
- *             Display Name = "Number";
- *     else if (Has "E-mail")
- *             Display Name = "E-mail";
- * }
- * @endcode
- *
- * - update
- * @code
- * if (No "First Name" & No "Last Name") {
- *     if (Has "Company Name")
- *             Display Name = "Company Name";
- *     else if (Has "Number")
- *             Display Name = "Number";
- *     else if (Has "E-mail")
- *             Display Name = "E-mail";
- * }
- * @endcode
- * @}
- */
-
-/**
- * @defgroup   CONTACTS_SVC_CONTACT Contact information Modification
- * @ingroup    CONTACTS_SVC
- * @addtogroup CONTACTS_SVC_CONTACT
- * @{
- *
- * This interface provides methods to insert/update/delete the Contact information.
- *
- */
-
-/**
- * This function inserts a contact into database.
- * This api assigns a index of the contact automatically.
- * \n The returned index is unique and non-reusable.
- *
- * @param[in] addressbook_id The index of addressbook. 0 is local(phone internal)
- * @param[in] contact A contact information of CTSstruct() created by contacts_svc_struct_new(CTS_STRUCT_CONTACT).
- * @return the index of contact on success, Negative value(#cts_error) on error
- * @par example
- * @code
- void insert_test(void)
- {
-    CTSstruct *contact;
-    CTSvalue *name, *number1, *number2;
-    GSList *numbers=NULL;
-    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, "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);
-
-    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_BUSINESS|CTS_NUM_TYPE_FAX);
-    }
-    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);
-
-    contacts_svc_insert_contact(0, contact);
-    contacts_svc_struct_free(contact);
- }
- * @endcode
- */
-int contacts_svc_insert_contact(int addressbook_id, CTSstruct* contact);
-
-/**
- * This function deletes a contact in database.
- * 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 contact to delete in database.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @par example
- * @code
- void delete_test(void)
- {
-    //get contact
-    //CTSstruct *contact;
-    //contacts_svc_struct_get_value(contact, CTS_CF_INDEX_INT, &value);
-    //int index = contacts_svc_value_get_int(value, CTS_BASIC_VAL_INT);
-
-    contacts_svc_delete_contact(2);
-
-    //contacts_svc_struct_free(contact);
-
-#if DELETE_CONTACTS
-    // TODO: get each index of contacts
-    int i, index_list[10] ={1,3,4,65,345,54,5,2,9,10};
-    int ret;
-
-    ret = contacts_svc_begin_trans();
-    if(CTS_SUCCESS != ret) return;
-    for(i=0;i<10;i++) {
-       ret = contacts_svc_delete_contact(index_list[i]);
-       if(CTS_SUCCESS != ret) {
-          contacts_svc_end_trans(false);
-          return;
-       }
-    }
-    ret = contacts_svc_end_trans(true);
-    if(ret < CTS_SUCCESS){
-       printf("all work were rollbacked");
-       return;
-    }
-#endif
- }
- * @endcode
- */
-int contacts_svc_delete_contact(int index);
-
-/**
- * This function updates a contact in the database.
- * \n If you want to add to list, store list.(refer to example)
- * \n To remove from list, set the value's VAL_DELETE_BOOL field.
- *
- * @param[in] contact A contact information of #CTSstruct.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @par example
- * @code
-
- void update_test()
- {
-    GSList *numbers, *cursor;
-    CTSvalue *number=NULL;
-    CTSstruct *contact=NULL;
-
-    contacts_svc_get_contact(1, &contact);
-
-    numbers = NULL;
-    contacts_svc_struct_get_list(contact, CTS_CF_NUMBER_LIST, &numbers);
-    cursor = numbers;
-    if(cursor) {
-       //char *temp = contacts_svc_value_get_str(cursor->data, CTS_NUM_VAL_NUMBER_STR);
-       contacts_svc_value_set_str(cursor->data, CTS_NUM_VAL_NUMBER_STR, "0987651234");
-
-       cursor = g_slist_next(cursor);
-       if(cursor)
-          contacts_svc_value_set_bool(cursor->data, CTS_NUM_VAL_DELETE_BOOL, true);
-
-       number = contacts_svc_value_new(CTS_VALUE_NUMBER);
-       if(number) {
-          contacts_svc_value_set_str(number, CTS_NUM_VAL_NUMBER_STR, "0125439876");
-          contacts_svc_value_set_int(number, CTS_NUM_VAL_TYPE_INT, CTS_NUM_TYPE_CELL);
-          contacts_svc_value_set_bool(number, CTS_NUM_VAL_DEFAULT_BOOL, true);
-       }
-       numbers = g_slist_append(numbers, number);
-    }
-
-    contacts_svc_struct_store_list(contact, CTS_CF_NUMBER_LIST, numbers);
-    contacts_svc_value_free(number);
-    //free("0125439876");
-    contacts_svc_update_contact(contact);
-
-    contacts_svc_struct_free(contact);
- }
- * @endcode
- */
-int contacts_svc_update_contact(CTSstruct* contact);
-
-/**
- * Use for contacts_svc_put_contact_value().
- */
-typedef enum{
-       CTS_PUT_VAL_REPLACE_RINGTONE=0,/**< Use #CTS_VALUE_CONTACT_BASE_INFO */
-       CTS_PUT_VAL_REPLACE_NOTE=2,/**< Use #CTS_VALUE_CONTACT_BASE_INFO */
-       CTS_PUT_VAL_ADD_NUMBER=3,/**< Use #CTS_VALUE_NUMBER */
-       CTS_PUT_VAL_ADD_EMAIL=4,/**< Use #CTS_VALUE_EMAIL */
-}cts_put_contact_val_op;
-
-/**
- * This function puts contacts service value(#CTSvalue) with op_code(#cts_put_contact_val_op).
- *
- * @param[in] op_code #cts_put_contact_val_op
- * @param[in] contact_id The index of the contact to put value.
- * @param[in] value The contacts service value which is put.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @par example
- * @code
- void put_value_test()
- {
-    CTSvalue *value, *number;
-
-    value = contacts_svc_value_new(CTS_VALUE_CONTACT_BASE_INFO);
-    if(value) {
-       contacts_svc_value_set_str(value, CTS_BASE_VAL_RINGTONE_PATH_STR,
-                                  "/opt/test/test.mp3");
-       contacts_svc_put_contact_value(CTS_PUT_VAL_REPLACE_RINGTONE, 1, value);
-       contacts_svc_value_free(value);
-       //free("/opt/test/test.mp3")
-    }
-
-    number = contacts_svc_value_new(CTS_VALUE_NUMBER);
-    if(number) {
-       contacts_svc_value_set_str(number, CTS_NUM_VAL_NUMBER_STR, "0123337777");
-       contacts_svc_value_set_int(number, CTS_NUM_VAL_TYPE_INT, CTS_NUM_TYPE_CELL);
-       contacts_svc_value_set_bool(number, CTS_NUM_VAL_DEFAULT_BOOL, true);
-
-       contacts_svc_put_contact_value(CTS_PUT_VAL_ADD_NUMBER, 1, number);
-       contacts_svc_value_free(number);
-       //free("0123337777")
-    }
- }
- * @endcode
- */
-int contacts_svc_put_contact_value(cts_put_contact_val_op op_code,
-               int contact_id, CTSvalue* value);
-
-
-/**
- * Use for contacts_svc_get_contact_value().
- */
-typedef enum {
-       CTS_GET_NAME_VALUE, /**< Use #NAMEVALUE */
-       CTS_GET_DEFAULT_EMAIL_VALUE,/**< related with contact id. Use #EMAILVALUE */
-       CTS_GET_DEFAULT_NUMBER_VALUE,/**< related with contact id. Use #NUMBERVALUE */
-       CTS_GET_NUMBER_VALUE, /**< related with number id. Use #NUMBERVALUE */
-       CTS_GET_EMAIL_VALUE, /**< related with email id. Use #EMAILVALUE */
-       CTS_GET_COMPANY_VALUE, /**< related with contact id. Use #COMPANYVALUE */
-}cts_get_contact_val_op;
-/**
- * This function can get a value data related with id and op_code.
- * The value data is decided by op_code(#cts_get_contact_val_op)
- * The gotten value is readonly.
- * If id is not contact id, it returns the related contact id.
- * Obtained contact record should be freed by using contacts_svc_value_free().
- * @return #CTS_SUCCESS or the related contact id on success, Negative value(#cts_error) on error
- * @param[in] op_code #cts_get_contact_val_op
- * @param[in] id The related index
- * @param[out] value Points of the contacts service value(#CTSvalue) which is returned
- * @par example
- * @code
- void get_contact_default_num(void)
- {
-    int index, ret;
-    CTSvalue *number=NULL;
-    const char *default_num;
-
-    index = contacts_svc_find_contact_by(CTS_FIND_BY_NUMBER, "0125439876");
-
-    ret = contacts_svc_get_contact_value(CTS_GET_DEFAULT_NUMBER_VALUE, index, &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_contact_value(cts_get_contact_val_op op_code,
-               int id, CTSvalue **value);
-
-
-/**
- * This function gets contact record which has the index from the database.
- * Obtained contact record should be freed by using contacts_svc_struct_free().
- * @param[in] index The index of contact to get
- * @param[out] contact Points of the contact record which is returned
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @par example
- * @code
- void get_contact(void)
- {
-    int ret=-1;
-    CTSstruct *contact = NULL;
-    CTSvalue *name;
-    GSList *get_list, *cursor;
-
-    ret = contacts_svc_get_contact(1, &contact);
-    if(ret < 0)
-    {
-       printf("No found record\n");
-       return;
-    }
-
-    contacts_svc_struct_get_value(contact, 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(contact, 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(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));
-    }
-
-    contacts_svc_struct_free(contact);
- }
- * @endcode
- */
-int contacts_svc_get_contact(int index, CTSstruct **contact);
-
-/**
- * Use for contacts_svc_find_contact_by(), contacts_svc_find_person_by()
- */
-typedef enum {
-       CTS_FIND_NONE,
-       CTS_FIND_BY_NAME,
-       CTS_FIND_BY_NUMBER,
-       CTS_FIND_BY_EMAIL,
-       CTS_FIND_BY_UID,
-}cts_find_op;
-/**
- * This function gets index of contact 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 contact on success, Negative value(#cts_error) on error
- * @par example
- * @code
- void get_contact(void)
- {
-    int index, ret=-1;
-    CTSstruct *contact = NULL;
-
-    index = contacts_svc_find_contact_by(CTS_FIND_BY_NUMBER, "0123456789");
-    if(index > CTS_SUCCESS)
-      ret = contacts_svc_get_contact(index, &contact);
-    if(ret < 0)
-    {
-       printf("No found record\n");
-       return;
-    }
- }
- * @endcode
- */
-int contacts_svc_find_contact_by(cts_find_op op_code, const char *user_data);
-
-/**
- * @}
- */
-
-//-->
-#endif //__CTS_CONTACT_H__
-
diff --git a/src/cts-errors.h b/src/cts-errors.h
deleted file mode 100755 (executable)
index 55a2c9a..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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_ERRORS_H__
-#define __CTS_ERRORS_H__
-
-//<!--
-typedef enum
-{
-       CTS_ERR_DB_LOCK = -204, /**< -204 */
-       CTS_ERR_DB_RECORD_NOT_FOUND = -203, /**< -203 */
-       CTS_ERR_DB_FAILED = -202, /**< -202 */
-       CTS_ERR_DB_NOT_OPENED= -201, /**< -201 */
-
-       CTS_ERR_ICU_FAILED = -106, /**< -106 */
-       CTS_ERR_TAPI_FAILED = -105, /**< -105 */
-       CTS_ERR_SOCKET_FAILED = -104, /**< -104 */
-       CTS_ERR_INOTIFY_FAILED = -103, /**< -103 */
-       CTS_ERR_VCONF_FAILED = -102, /**< -102 */
-       CTS_ERR_VOBJECT_FAILED = -101, /**< -101 */
-
-       CTS_ERR_NO_SPACE = -13, /**< -13 */
-       CTS_ERR_IO_ERR = -12, /**< -12 */
-       CTS_ERR_MSG_INVALID = -11, /**< -11 */
-       CTS_ERR_ALREADY_RUNNING = -10, /**< -10 */
-       CTS_ERR_EXCEEDED_LIMIT = -9, /**< -9 */
-       CTS_ERR_OUT_OF_MEMORY = -8, /**< -8 */
-       CTS_ERR_ALREADY_EXIST = -7, /**< -7 */
-       CTS_ERR_ENV_INVALID = -6, /**< -6 */
-       CTS_ERR_ARG_NULL = -5, /**< -5 */
-       CTS_ERR_ARG_INVALID = -4, /**< -4 */
-       CTS_ERR_NO_DATA = -3, /**< -3 */
-       CTS_ERR_FINISH_ITER= -2, /**< -2 */
-       CTS_ERR_FAIL= -1, /**< -1 */
-       CTS_SUCCESS = 0, /**< 0 */
-       CTS_FALSE = 0, /**< 0 */
-       CTS_TRUE = 1 /**< 1 */
-}cts_error;
-//-->
-
-#endif //__CTS_ERRORS_H__
-
diff --git a/src/cts-favorite.c b/src/cts-favorite.c
deleted file mode 100755 (executable)
index b43e436..0000000
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * 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-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)
-{
-       int ret;
-       double prio = 0.0;
-       cts_stmt stmt;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       retvm_if(CTS_FAVOR_PERSON != op && CTS_FAVOR_NUMBER != op, CTS_ERR_ARG_INVALID,
-                       "op(%d) is invalid", op);
-
-       snprintf(query, sizeof(query),
-                       "SELECT MAX(favorite_prio) FROM %s", CTS_TABLE_FAVORITES);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_TRUE == ret) {
-               prio = cts_stmt_get_dbl(stmt, 0);
-       }
-       else if (CTS_SUCCESS != ret) {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-       cts_stmt_finalize(stmt);
-
-       prio = prio + 1.0;
-       snprintf(query, sizeof(query),
-                       "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)
-       {
-               ERR("cts_query_exec() Failed(%d)", ret);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-
-       cts_set_favor_noti();
-
-       ret = contacts_svc_end_trans(true);
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-API int contacts_svc_unset_favorite(cts_favor_type op, int related_id)
-{
-       int ret;
-       cts_stmt stmt;
-       char query[CTS_SQL_MIN_LEN] = {0};
-
-       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");
-
-       ret = contacts_svc_begin_trans();
-       if (ret) {
-               cts_stmt_finalize(stmt);
-               ERR("contacts_svc_begin_trans() Failed(%d)", ret);
-               return ret;
-       }
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_SUCCESS != ret)
-       {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-       ret = cts_db_change();
-       cts_stmt_finalize(stmt);
-
-       if (0 < ret) {
-               cts_set_favor_noti();
-               ret = contacts_svc_end_trans(true);
-       }
-       else {
-               contacts_svc_end_trans(false);
-               ret = CTS_ERR_NO_DATA;
-       }
-
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-API int contacts_svc_delete_favorite(int favorite_id)
-{
-       int ret;
-       cts_stmt stmt;
-       char query[CTS_SQL_MIN_LEN] = {0};
-
-       snprintf(query, sizeof(query), "DELETE FROM %s WHERE id = %d",
-                       CTS_TABLE_FAVORITES, favorite_id);
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() 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_SUCCESS != ret)
-       {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-       ret = cts_db_change();
-       cts_stmt_finalize(stmt);
-
-       if (0 < ret) {
-               cts_set_favor_noti();
-               ret = contacts_svc_end_trans(true);
-       }
-       else {
-               contacts_svc_end_trans(false);
-               ret = CTS_ERR_NO_DATA;
-       }
-
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-static inline int cts_modify_favorite_prio(int favorite_id, int front, int back)
-{
-       int ret;
-       cts_stmt stmt;
-       double front_prio=0.0, back_prio=0.0, prio;
-       char query[CTS_SQL_MIN_LEN] = {0};
-
-       snprintf(query, sizeof(query), "SELECT favorite_prio FROM %s WHERE id = ?",
-                       CTS_TABLE_FAVORITES);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       cts_stmt_bind_int(stmt, 1, front);
-       ret = cts_stmt_step(stmt);
-       if (CTS_TRUE == ret)
-               front_prio = cts_stmt_get_dbl(stmt, 0);
-
-       cts_stmt_reset(stmt);
-       cts_stmt_bind_int(stmt, 1, back);
-       ret = cts_stmt_step(stmt);
-       if (CTS_TRUE == ret)
-               back_prio = cts_stmt_get_dbl(stmt, 0);
-
-       cts_stmt_finalize(stmt);
-
-       retvm_if(0.0 == front_prio && 0.0 == back_prio, CTS_ERR_ARG_INVALID,
-                       "The indexes for front and back are invalid.");
-
-       if (0.0 == back_prio)
-               prio = front_prio + 1;
-       else
-               prio = (front_prio + back_prio) / 2;
-
-       snprintf(query, sizeof(query),
-                       "UPDATE %s SET favorite_prio = %f WHERE id = %d",
-                       CTS_TABLE_FAVORITES, prio, favorite_id);
-
-       ret = cts_query_exec(query);
-       if (CTS_SUCCESS != ret)
-       {
-               ERR("cts_query_exec() Failed(%d)", ret);
-               return ret;
-       }
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_favorite_order(int favorite_id,
-               int front_favorite_id, int back_favorite_id)
-{
-       int ret;
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       ret = cts_modify_favorite_prio(favorite_id, front_favorite_id, back_favorite_id);
-
-       if (CTS_SUCCESS != ret)
-       {
-               ERR("cts_modify_favorite_prio() Failed(%d)", ret);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-       cts_set_favor_noti();
-
-       ret = contacts_svc_end_trans(true);
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-API int contacts_svc_set_speeddial(int speed_num, int number_id)
-{
-       int ret;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       snprintf(query, sizeof(query),
-                       "INSERT INTO %s(speed_num, number_id) VALUES(%d, %d)",
-                       CTS_TABLE_SPEEDDIALS, speed_num, number_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_speed_noti();
-
-       ret = contacts_svc_end_trans(true);
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-API int contacts_svc_unset_speeddial(int speed_num)
-{
-       int ret;
-       cts_stmt stmt;
-       char query[CTS_SQL_MIN_LEN] = {0};
-
-       snprintf(query, sizeof(query), "DELETE FROM %s WHERE speed_num = %d",
-                       CTS_TABLE_SPEEDDIALS, speed_num);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       ret = contacts_svc_begin_trans();
-       if (ret) {
-               cts_stmt_finalize(stmt);
-               ERR("contacts_svc_begin_trans() Failed(%d)", ret);
-               return ret;
-       }
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_SUCCESS != ret) {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-       ret = cts_db_change();
-       cts_stmt_finalize(stmt);
-
-       if (0 < ret) {
-               cts_set_speed_noti();
-               ret = contacts_svc_end_trans(true);
-       }
-       else {
-               contacts_svc_end_trans(false);
-               ret = CTS_ERR_NO_DATA;
-       }
-
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-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",
-                       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");
-
-       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;
-               number->id = cts_stmt_get_int(stmt, 0);
-               number->type = cts_stmt_get_int(stmt, 1);
-               number->number = SAFE_STRDUP(cts_stmt_get_text(stmt, 2));
-               ret = cts_stmt_get_int(stmt, 3);
-
-               *value = (CTSvalue*) number;
-
-               cts_stmt_finalize(stmt);
-               return ret;
-       }
-       else {
-               ERR("contacts_svc_value_new() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               return CTS_ERR_OUT_OF_MEMORY;
-       }
-}
diff --git a/src/cts-favorite.h b/src/cts-favorite.h
deleted file mode 100755 (executable)
index 59e0f9d..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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_FAVORITE_H__
-#define __CTS_FAVORITE_H__
-
-//<!--
-
-/**
- * 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
- * @{
- *
- * This interface provides methods to insert/update/delete the Favorite(speeddial).
- *
- */
-
-/**
- * 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.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_set_favorite(cts_favor_type op, int related_id);
-
-/**
- * This function unsets a number or a contact to the favorite.
- * @param[in] op favorite type(#cts_favor_type).
- * @param[in] related_id a contact or number id which is related op.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_unset_favorite(cts_favor_type op, int related_id);
-
-/**
- * This function deletes a favorite from favorite list.
- * @param[in] favorite_id index of favorite.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_delete_favorite(int favorite_id);
-
-/**
- * This function modifies priority of favorite.
- * The priority of favorite will be between a front favorite and a back favorite.
- *
- * @param[in] favorite_id The index of a favorite data
- * @param[in] front_favorite_id Id of the front favorite.
- * @param[in] back_favorite_id Id of the back favorite.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_favorite_order(int favorite_id, int front_favorite_id, int back_favorite_id);
-
-/**
- * This function sets a number to the speeddial.
- * @param[in] speed_num speed dial number.
- * @param[in] number_id the index of number
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_set_speeddial(int speed_num, int number_id);
-
-/**
- * This function unsets speed dial number.
- * @param[in] speed_num speed dial number.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_unset_speeddial(int speed_num);
-
-/**
- * @}
- */
-
-//-->
-
-#endif //__CTS_FAVORITE_H__
diff --git a/src/cts-group.c b/src/cts-group.c
deleted file mode 100755 (executable)
index 6277f74..0000000
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * 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-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)
-{
-       char query[CTS_SQL_MIN_LEN];
-
-       retv_if(NULL == name, CTS_ERR_ARG_NULL);
-
-       snprintf(query, sizeof(query), "SELECT group_id FROM %s "
-                       "WHERE group_name = '%s' LIMIT 1",
-                       CTS_TABLE_GROUPS, name);
-
-       return cts_query_get_first_int_result(query);
-}
-
-API int contacts_svc_get_group(int index, CTSvalue **retgroup)
-{
-       int ret;
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       retv_if(NULL == retgroup, CTS_ERR_ARG_NULL);
-
-       snprintf(query, sizeof(query),
-                       "SELECT group_id, addrbook_id, group_name, ringtone "
-                       "FROM %s WHERE group_id = %d", CTS_TABLE_GROUPS, 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;
-       }
-       cts_group *group;
-       group = (cts_group *)contacts_svc_value_new(CTS_VALUE_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);
-
-       *retgroup = (CTSvalue *)group;
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_update_group(CTSvalue *group)
-{
-       int ret;
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MIN_LEN] = {0};
-       cts_group *record = (cts_group *)group;
-
-       retv_if(NULL == group, CTS_ERR_ARG_NULL);
-       retvm_if(CTS_VALUE_GROUP != group->v_type, CTS_ERR_ARG_INVALID,
-                       "group is invalid type(%d)", group->v_type);
-       retvm_if(NULL == record->name, CTS_ERR_ARG_INVALID,
-                       "The name of group is empty.");
-
-       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");
-               contacts_svc_end_trans(false);
-               return CTS_ERR_DB_FAILED;
-       }
-
-       cts_stmt_bind_text(stmt, 1, record->name);
-       if (record->ringtone_path)
-               cts_stmt_bind_text(stmt, 2, record->ringtone_path);
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_SUCCESS != ret)
-       {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-       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);
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-API int contacts_svc_insert_group(int addressbook_id, CTSvalue *group)
-{
-       int ret, index, ver;
-       cts_stmt stmt = NULL;
-       cts_group *record = (cts_group *)group;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       retv_if(NULL == group, CTS_ERR_ARG_NULL);
-       retvm_if(CTS_VALUE_GROUP != group->v_type, CTS_ERR_ARG_INVALID,
-                       "group is invalid type(%d)", group->v_type);
-       retvm_if(NULL == record->name, CTS_ERR_ARG_INVALID,
-                       "The name of group is empty.");
-
-       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");
-               contacts_svc_end_trans(false);
-               return CTS_ERR_DB_FAILED;
-       }
-
-       cts_stmt_bind_text(stmt, 1, record->name);
-
-       if (record->ringtone_path)
-               cts_stmt_bind_text(stmt, 2, record->ringtone_path);
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_SUCCESS != ret)
-       {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-       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,
-                       "contacts_svc_end_trans(true) Failed(%d)", ret);
-
-       return index;
-}
-
-API int contacts_svc_delete_group_with_members(int index)
-{
-       int ret;
-       char  query[CTS_SQL_MAX_LEN] = {0};
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       snprintf(query, sizeof(query), "DELETE FROM %s WHERE contact_id "
-                       "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)
-       {
-               ERR("cts_query_exec() Failed(%d)", ret);
-               contacts_svc_end_trans(false);
-               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);
-       if (CTS_SUCCESS != ret)
-       {
-               ERR("cts_query_exec() Failed(%d)", ret);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-
-       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);
-       } else {
-               contacts_svc_end_trans(false);
-               ret = CTS_ERR_NO_DATA;
-       }
-
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-API int contacts_svc_delete_group(int index)
-{
-       int ret;
-       char  query[CTS_SQL_MAX_LEN] = {0};
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       snprintf(query, sizeof(query), "DELETE FROM %s WHERE group_id=%d",
-                       CTS_TABLE_GROUPS, index);
-
-       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_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 {
-               contacts_svc_end_trans(false);
-               ret = CTS_ERR_NO_DATA;
-       }
-
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               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",
-                       CTS_TABLE_GROUPS, group_id);
-       int grp_acc = cts_query_get_first_int_result(query);
-       retvm_if(CTS_ERR_DB_RECORD_NOT_FOUND == grp_acc, CTS_ERR_ARG_INVALID,
-                       "group_id(%d) is Invalid", group_id);
-
-       retvm_if(contact_acc != grp_acc, CTS_ERR_ARG_INVALID,
-                       "addrbook_id(%d) of the contact and addrbook_id(%d) of the group is not same",
-                       contact_acc, grp_acc);
-
-       snprintf(query, sizeof(query), "INSERT OR IGNORE INTO %s VALUES(%d, %d)",
-                       CTS_TABLE_GROUPING_INFO, group_id, contact_id);
-
-       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);
-
-       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;
-}
-
-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",
-                       CTS_TABLE_CONTACTS, contact_id);
-       ct_acc = cts_query_get_first_int_result(query);
-       retvm_if(CTS_ERR_DB_RECORD_NOT_FOUND == ct_acc, CTS_ERR_ARG_INVALID,
-                       "contact_id(%d) is Invalid", contact_id);
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", 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)", changed);
-               return changed;
-       }
-
-       ret = cts_update_contact_changed_time(contact_id);
-       if (CTS_SUCCESS != ret) {
-               ERR("cts_update_contact_changed_time() Failed(%d)", ret);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-
-       cts_set_contact_noti();
-       if (0 < changed)
-               cts_set_group_rel_noti();
-       ret = contacts_svc_end_trans(true);
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-int cts_group_unset_relation(int group_id, int contact_id)
-{
-       int ret;
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MIN_LEN];
-
-       snprintf(query, sizeof(query),
-                       "DELETE FROM %s WHERE group_id = %d AND contact_id = %d",
-                       CTS_TABLE_GROUPING_INFO, group_id, contact_id);
-
-       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);
-
-       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");
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", 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)", changed);
-               return changed;
-       }
-
-       ret = cts_update_contact_changed_time(contact_id);
-       if (CTS_SUCCESS != ret) {
-               ERR("cts_update_contact_changed_time() Failed(%d)", ret);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-
-       cts_set_contact_noti();
-       if (0 < changed)
-               cts_set_group_rel_noti();
-       ret = contacts_svc_end_trans(true);
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
diff --git a/src/cts-group.h b/src/cts-group.h
deleted file mode 100755 (executable)
index 472b68f..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * 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_GROUP_H__
-#define __CTS_GROUP_H__
-
-int cts_group_set_relation(int group_id, int contact_id, int contact_acc);
-int cts_group_unset_relation(int group_id, int contact_id);
-
-/**
- * This function gets index of group found by name.
- * @param[in] addressbook_id The index of addressbook. 0 is local(phone internal)
- * @param[in] name The group name for searching
- * @return index of found group on success, Negative value(#cts_error) on error
- * @par example
- * @code
- void get_group(void)
- {
-    int index, ret=-1;
-    CTSvalue *group = NULL;
-
-    index = contacts_svc_find_group(0, "Family");
-    if(index > CTS_SUCCESS)
-       ret = contacts_svc_get_group(index, &group);
-    if(ret < CTS_SUCCESS) {
-         printf("contacts_svc_get_group() Failed");
-         return;
-    }
- }
- * @endcode
- */
-int contacts_svc_find_group(int addressbook_id, const char *name);
-
-
-//<!--
-/**
- * @defgroup   CONTACTS_SVC_GROUP Group information
- * @ingroup    CONTACTS_SVC
- * @addtogroup CONTACTS_SVC_GROUP
- * @{
- *
- * This interface provides methods for group information.
- *
- */
-
-/**
- * This function sets the relationship between a group and a contact.
- * It is low level api. It is recommanded to use contacts_svc_update_contact()
- * \n The contact and the group must have the same addressbook index.
- * (It is not checked internally for performance.)
- *
- * @param[in] group_id Index of group record
- * @param[in] contact_id Index of contact record to add to group
- * @return the index of group on success, Negative value(#cts_error) on error
- * @par example
- * @code
-
- * @endcode
- */
-int contacts_svc_group_set_relation(int group_id, int contact_id);
-
-/**
- * This function removes relation between a group and a contact.
- * It is low level api. It is recommanded to use contacts_svc_update_contact()
- *
- * @param[in] group_id Index of group record
- * @param[in] contact_id Index of contact record to add to group
- * @return the index of group on success, Negative value(#cts_error) on error
- * @par example
- * @code
-
- * @endcode
- */
-int contacts_svc_group_unset_relation(int group_id, int contact_id);
-
-/**
- * This function inserts a group into database.
- * This api assigns a index of the group automatically.
- * \n The returned index is unique & non-reusable.
- *
- * @param[in] addressbook_id The index of addressbook. 0 is local(phone internal)
- * @param[in] group A group information of CTSvalue() created by contacts_svc_value_new(CTS_VALUE_GROUP).
- * @return the index of group on success, Negative value(#cts_error) on error
- * @par example
- * @code
- void insert_group(const char *group_name)
- {
-    int ret;
-    CTSvalue *group;
-    group = contacts_svc_value_new(CTS_VALUE_GROUP);
-
-    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");
-
-    ret = contacts_svc_insert_group(0, group);
-    if(ret < CTS_SUCCESS)
-       printf("contacts_svc_insert_group() Failed\n");
-
-    contacts_svc_value_free(group);
- }
- * @endcode
- */
-int contacts_svc_insert_group(int addressbook_id, CTSvalue *group);
-
-/**
- * This function updates a group in the database.
- *
- * @param[in] group A group information of #CTSvalue.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @par example
- * @code
- void update_group(void)
- {
-    int ret;
-    CTSvalue *group = NULL;
-    ret = contacts_svc_get_group(2, &group);
-    if(CTS_SUCCESS != ret) {
-         printf("contacts_svc_get_group() Failed");
-         return;
-    }
-
-    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");
-
-    //free("Fix-Friends");
-    //free("/tmp/change.mp3");
-    ret = contacts_svc_update_group(group);
-    if(ret < CTS_SUCCESS)
-       printf("contacts_svc_update_group() Failed\n");
-
-    contacts_svc_value_free(group);
- }
- * @endcode
- */
-int contacts_svc_update_group(CTSvalue *group);
-
-/**
- * This function deletes a group in database.
- *
- * @param[in] index The index of group to delete in database.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @par example
- * @code
- void delete_group(void)
- {
-    int ret;
-    ret = contacts_svc_delete_group(3);
-    if(CTS_SUCCESS != ret)
-       printf("Error : contacts_svc_delete_group() Failed(%d)", ret);
- }
- * @endcode
- */
-int contacts_svc_delete_group(int index);
-
-/**
- * This function deletes contacts inclued the group and the group in database.
- * But if the contact has another group, it deletes the group relations only.
- *
- * @param[in] index The index of group to delete in database.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @par example
- * @code
- void delete_group_members(void)
- {
-    int ret;
-    ret = contacts_svc_delete_group_with_members(3);
-    if(CTS_SUCCESS != ret)
-       printf("Error : contacts_svc_delete_group_with_members() Failed(%d)", ret);
- }
- * @endcode
- */
-int contacts_svc_delete_group_with_members(int index);
-
-/**
- * This function gets a group record which has the index from the database.
- * Obtained group record should be free using by contacts_svc_value_free().
- * @param[in] index The index of group to get
- * @param[out] retgroup Points of the group record which is returned
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @par example
- * @code
- void get_group(void)
- {
-    int ret;
-    CTSvalue *group = NULL;
-    ret = contacts_svc_get_group(2, &group);
-    if(CTS_SUCCESS != ret) {
-         printf("contacts_svc_get_list() Failed");
-         return;
-    }
-
-    printf("Account ID : %d\n",
-             contacts_svc_value_get_int(group, CTS_GROUP_VAL_ADDRESSBOOK_ID_INT));
-    printf("Name : %s\n",
-       contacts_svc_value_get_str(group, CTS_GROUP_VAL_NAME_STR));
-    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));
- }
- * @endcode
- */
-int contacts_svc_get_group(int index, CTSvalue **retgroup);
-
-/**
- * @}
- */
-//-->
-#endif //__CTS_GROUP_H__
-
diff --git a/src/cts-im.h b/src/cts-im.h
deleted file mode 100755 (executable)
index 36d52c9..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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-inotify.c b/src/cts-inotify.c
deleted file mode 100755 (executable)
index 553fe3c..0000000
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * 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 <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/inotify.h>
-
-#include "cts-internal.h"
-
-typedef struct
-{
-       int wd;
-       void (*cb)(void *);
-       void *cb_data;
-}noti_info;
-
-static int cts_inoti_fd = -1;
-static guint cts_inoti_handler;
-static GSList *cts_noti_list;
-
-static inline void handle_callback(GSList *noti_list, int wd, uint32_t mask)
-{
-       noti_info *noti;
-       GSList *it = NULL;
-
-       for (it = noti_list;it;it=it->next)
-       {
-               noti = (noti_info *)it->data;
-               if (noti->wd == wd) {
-                       if ((mask & IN_CLOSE_WRITE) && noti->cb)
-                               noti->cb(noti->cb_data);
-               }
-       }
-}
-
-static gboolean cts_inotify_gio_cb(GIOChannel *src, GIOCondition cond, gpointer data)
-{
-       int fd, ret;
-       struct inotify_event ie;
-       char name[FILENAME_MAX];
-
-       fd = g_io_channel_unix_get_fd(src);
-
-       while (0 < (ret = read(fd, &ie, sizeof(ie)))) {
-               if (sizeof(ie) == ret) {
-                       if (cts_noti_list)
-                               handle_callback(cts_noti_list, ie.wd, ie.mask);
-
-                       while (0 < ie.len) {
-                               ret = read(fd, name, (ie.len<sizeof(name))?ie.len:sizeof(name));
-                               if (-1 == ret) {
-                                       if (EINTR == errno)
-                                               continue;
-                                       else
-                                               break;
-                               }
-                               ie.len -= ret;
-                       }
-               }else {
-                       while (ret < sizeof(ie)) {
-                               int read_size;
-                               read_size = read(fd, name, sizeof(ie)-ret);
-                               if (-1 == read_size) {
-                                       if (EINTR == errno)
-                                               continue;
-                                       else
-                                               break;
-                               }
-                               ret += read_size;
-                       }
-               }
-       }
-
-       return TRUE;
-}
-
-static inline int cts_inotify_attach_handler(int fd)
-{
-       guint ret;
-       GIOChannel *channel;
-
-       retvm_if(fd < 0, CTS_ERR_ARG_INVALID, "fd is invalid");
-
-       channel = g_io_channel_unix_new(fd);
-       retvm_if(NULL == channel, CTS_ERR_INOTIFY_FAILED, "g_io_channel_unix_new() Failed");
-
-       g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL);
-
-       ret = g_io_add_watch(channel, G_IO_IN, cts_inotify_gio_cb, NULL);
-       g_io_channel_unref(channel);
-
-       return ret;
-}
-
-int cts_inotify_init(void)
-{
-       cts_inoti_fd = inotify_init();
-       retvm_if(-1 == cts_inoti_fd, CTS_ERR_INOTIFY_FAILED,
-                       "inotify_init() Failed(%d)", errno);
-
-       fcntl(cts_inoti_fd, F_SETFD, FD_CLOEXEC);
-       fcntl(cts_inoti_fd, F_SETFL, O_NONBLOCK);
-
-       cts_inoti_handler = cts_inotify_attach_handler(cts_inoti_fd);
-       if (cts_inoti_handler <= 0) {
-               ERR("cts_inotify_attach_handler() Failed");
-               close(cts_inoti_fd);
-               cts_inoti_fd = -1;
-               cts_inoti_handler = 0;
-               return CTS_ERR_INOTIFY_FAILED;
-       }
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_inotify_get_wd(int fd, const char *notipath)
-{
-       return inotify_add_watch(fd, notipath, IN_ACCESS);
-}
-
-static inline int cts_inotify_watch(int fd, const char *notipath)
-{
-       int ret;
-
-       ret = inotify_add_watch(fd, notipath, IN_CLOSE_WRITE);
-       retvm_if(-1 == ret, CTS_ERR_INOTIFY_FAILED,
-                       "inotify_add_watch() Failed(%d)", errno);
-
-       return CTS_SUCCESS;
-}
-
-int cts_inotify_subscribe(const char *path, void (*cb)(void *), void *data)
-{
-       int ret, wd;
-       noti_info *noti, *same_noti = NULL;
-       GSList *it;
-
-       retv_if(NULL==path, CTS_ERR_ARG_NULL);
-       retv_if(NULL==cb, CTS_ERR_ARG_NULL);
-       retvm_if(cts_inoti_fd < 0, CTS_ERR_ENV_INVALID,
-                       "cts_inoti_fd(%d) is invalid", cts_inoti_fd);
-
-       wd = cts_inotify_get_wd(cts_inoti_fd, path);
-       retvm_if(-1 == wd, CTS_ERR_INOTIFY_FAILED,
-                       "cts_inotify_get_wd() Failed(%d)", errno);
-
-       for (it=cts_noti_list;it;it=it->next)
-       {
-               if (it->data)
-               {
-                       same_noti = it->data;
-                       if (same_noti->wd == wd && same_noti->cb == cb && same_noti->cb_data == data) {
-                               break;
-                       }
-                       else {
-                               same_noti = NULL;
-                       }
-               }
-       }
-
-       if (same_noti) {
-               cts_inotify_watch(cts_inoti_fd, path);
-               ERR("The same callback(%s) is already exist", path);
-               return CTS_ERR_ALREADY_EXIST;
-       }
-
-       ret = cts_inotify_watch(cts_inoti_fd, path);
-       retvm_if(CTS_SUCCESS != ret, ret, "cts_inotify_watch() Failed");
-
-       noti = calloc(1, sizeof(noti_info));
-       retvm_if(NULL == noti, CTS_ERR_OUT_OF_MEMORY, "calloc() Failed");
-
-       noti->wd = wd;
-       noti->cb_data = data;
-       noti->cb = cb;
-       cts_noti_list = g_slist_append(cts_noti_list, noti);
-
-       return CTS_SUCCESS;
-}
-
-static inline int del_noti_with_data(GSList **noti_list, int wd,
-               void (*cb)(void *), void *user_data)
-{
-       int del_cnt, remain_cnt;
-       GSList *it, *result;
-
-       del_cnt = 0;
-       remain_cnt = 0;
-
-       it = result = *noti_list;
-       while (it)
-       {
-               noti_info *noti = it->data;
-               if (noti && wd == noti->wd)
-               {
-                       if (cb == noti->cb && user_data == noti->cb_data) {
-                               it = it->next;
-                               result = g_slist_remove(result , noti);
-                               free(noti);
-                               del_cnt++;
-                               continue;
-                       }
-                       else {
-                               remain_cnt++;
-                       }
-               }
-               it = it->next;
-       }
-       retvm_if(del_cnt == 0, CTS_ERR_NO_DATA, "nothing deleted");
-
-       *noti_list = result;
-
-       return remain_cnt;
-}
-
-static inline int del_noti(GSList **noti_list, int wd, void (*cb)(void *))
-{
-       int del_cnt, remain_cnt;
-       GSList *it, *result;
-
-       del_cnt = 0;
-       remain_cnt = 0;
-
-       it = result = *noti_list;
-       while (it)
-       {
-               noti_info *noti = it->data;
-               if (noti && wd == noti->wd)
-               {
-                       if (NULL == cb || noti->cb == cb) {
-                               it = it->next;
-                               result = g_slist_remove(result, noti);
-                               free(noti);
-                               del_cnt++;
-                               continue;
-                       }
-                       else {
-                               remain_cnt++;
-                       }
-               }
-               it = it->next;
-       }
-       retvm_if(del_cnt == 0, CTS_ERR_NO_DATA, "nothing deleted");
-
-       *noti_list = result;
-
-       return remain_cnt;
-}
-
-int cts_inotify_unsubscribe(const char *path, void (*cb)(void *))
-{
-       int ret, wd;
-
-       retv_if(NULL == path, CTS_ERR_ARG_NULL);
-       retvm_if(cts_inoti_fd < 0, CTS_ERR_ENV_INVALID,
-                       "cts_inoti_fd(%d) is invalid", cts_inoti_fd);
-
-       wd = cts_inotify_get_wd(cts_inoti_fd, path);
-       retvm_if(-1 == wd, CTS_ERR_INOTIFY_FAILED,
-                       "cts_inotify_get_wd() Failed(%d)", errno);
-
-       ret = del_noti(&cts_noti_list, wd, cb);
-       warn_if(ret < CTS_SUCCESS, "del_noti() Failed(%d)", ret);
-
-       if (0 == ret)
-               return inotify_rm_watch(cts_inoti_fd, wd);
-
-       return cts_inotify_watch(cts_inoti_fd, path);
-}
-
-int cts_inotify_unsubscribe_with_data(const char *path,
-               void (*cb)(void *), void *user_data)
-{
-       int ret, wd;
-
-       retv_if(NULL==path, CTS_ERR_ARG_NULL);
-       retv_if(NULL==cb, CTS_ERR_ARG_NULL);
-       retvm_if(cts_inoti_fd < 0, CTS_ERR_ENV_INVALID,
-                       "cts_inoti_fd(%d) is invalid", cts_inoti_fd);
-
-       wd = cts_inotify_get_wd(cts_inoti_fd, path);
-       retvm_if(-1 == wd, CTS_ERR_INOTIFY_FAILED,
-                       "cts_inotify_get_wd() Failed(%d)", errno);
-
-       ret = del_noti_with_data(&cts_noti_list, wd, cb, user_data);
-       warn_if(ret < CTS_SUCCESS, "del_noti_with_data() Failed(%d)", ret);
-
-       if (0 == ret)
-               return inotify_rm_watch(cts_inoti_fd, wd);
-
-       return cts_inotify_watch(cts_inoti_fd, path);
-}
-
-static void clear_nslot_list(gpointer data, gpointer user_data)
-{
-       free(data);
-}
-
-static inline gboolean cts_inotify_detach_handler(guint id)
-{
-       return g_source_remove(id);
-}
-
-void cts_inotify_close(void)
-{
-       if (cts_inoti_handler) {
-               cts_inotify_detach_handler(cts_inoti_handler);
-               cts_inoti_handler = 0;
-       }
-
-       if (cts_noti_list) {
-               g_slist_foreach(cts_noti_list, clear_nslot_list, NULL);
-               g_slist_free(cts_noti_list);
-               cts_noti_list = NULL;
-       }
-
-       if (0 <= cts_inoti_fd) {
-               close(cts_inoti_fd);
-               cts_inoti_fd = -1;
-       }
-}
diff --git a/src/cts-internal.h b/src/cts-internal.h
deleted file mode 100755 (executable)
index 66cc489..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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_INTERNAL_H__
-#define __CTS_INTERNAL_H__
-
-#include <stdio.h>
-#include "cts-errors.h"
-#include "cts-struct.h"
-
-#ifndef API
-#define API __attribute__ ((visibility("default")))
-#endif
-
-#define SAFE_STR(src) (src)?src:""
-
-#define CTS_DLOG_OUT
-//#define CTS_DEBUGGING
-//#define CTS_TIMECHECK
-
-#ifdef CTS_DLOG_OUT
-#define LOG_TAG "CONTACTS_SVC"
-#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 ERR(fmt, arg...) SLOGE("%s(%d): " fmt, __FUNCTION__, __LINE__, ##arg)
-#define DBG(fmt, arg...) SLOGD("%s:" fmt, __FUNCTION__, ##arg)
-#else
-#include <unistd.h>
-#define PRT(prio, fmt, arg...) \
-       do { fprintf((prio?stderr:stdout),"[Contacts-service]" fmt"\n", ##arg); } while (0)
-#define INFO(fmt, arg...) PRT(0, fmt, ##arg)
-#define ERR(fmt, arg...) PRT(1,"%s(%d): " fmt, __FUNCTION__, __LINE__, ##arg)
-#define DBG(fmt, arg...) \
-       do { \
-               printf("\x1b[105;37m[%d]\x1b[0m(%s)" fmt "\n", getpid(), __FUNCTION__, ##arg); \
-       } while (0)
-#endif
-
-#ifdef CTS_DEBUGGING
-#define CTS_FN_CALL DBG(">>>>>>>> called")
-#define CTS_FN_END DBG("<<<<<<<< ended")
-#define CTS_DBG(fmt, arg...) DBG("(%d) " fmt, __LINE__, ##arg)
-#else /* CTS_DEBUGGING */
-#define CTS_FN_CALL
-#define CTS_FN_END
-#define CTS_DBG(fmt, arg...)
-#endif /* CTS_DEBUGGING */
-
-#define warn_if(expr, fmt, arg...) do { \
-       if (expr) { \
-               ERR(fmt, ##arg); \
-       } \
-} while (0)
-#define ret_if(expr) do { \
-       if (expr) { \
-               ERR("(%s)", #expr); \
-               return; \
-       } \
-} while (0)
-#define retv_if(expr, val) do { \
-       if (expr) { \
-               ERR("(%s)", #expr); \
-               return (val); \
-       } \
-} while (0)
-#define retm_if(expr, fmt, arg...) do { \
-       if (expr) { \
-               ERR(fmt, ##arg); \
-               return; \
-       } \
-} while (0)
-#define retvm_if(expr, val, fmt, arg...) do { \
-       if (expr) { \
-               ERR(fmt, ##arg); \
-               return (val); \
-       } \
-} while (0)
-
-/************** TimeCheck ***************/
-#ifdef CTS_TIMECHECK
-
-double correction, startT;
-double cts_set_start_time(void);
-double cts_exec_time(double start);
-int cts_init_time(void);
-#define CTS_START_TIME_CHECK \
-       cts_init_time();\
-startT = cts_set_start_time()
-#define CTS_END_TIME_CHECK(fmt, arg...) \
-       DBG(fmt" time = %f ms\n", ##arg, cts_exec_time(startT))
-
-#else /* CTS_TIMECHECK */
-
-#define CTS_START_TIME_CHECK
-#define CTS_END_TIME_CHECK(arg)
-
-#endif /* CTS_TIMECHECK */
-
-#endif /* __CTS_INTERNAL_H__ */
-
diff --git a/src/cts-list-filter.c b/src/cts-list-filter.c
deleted file mode 100755 (executable)
index 33d5445..0000000
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
- * 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
deleted file mode 100755 (executable)
index a2af59c..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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
deleted file mode 100755 (executable)
index a88b059..0000000
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * 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-normalize.h"
-#include "cts-utils.h"
-#include "cts-list.h"
-
-static inline CTSvalue* cts_iter_get_info_contact(cts_stmt stmt, int type)
-{
-       int i, lang;
-       char *temp;
-       contact_list *result;
-
-       result = (contact_list *)contacts_svc_value_new(CTS_VALUE_LIST_CONTACT);
-       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++);
-
-       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);
-       }
-       if (CTS_ITER_CONTACTS_WITH_NAME != type) {
-               temp = cts_stmt_get_text(stmt, i++);
-               result->normalize = SAFE_STRDUP(temp);
-       }
-
-       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;
-       char *temp;
-       contact_list *result;
-
-       result = (contact_list *)contacts_svc_value_new(CTS_VALUE_LIST_CONTACT);
-       retvm_if(NULL == result, NULL, "contacts_svc_value_new() Failed");
-       if (CTS_ITER_EMAILINFOS_WITH_EMAIL == type)
-               result->v_type = CTS_VALUE_LIST_EMAILINFO;
-       else if (CTS_ITER_NUMBERS_EMAILS == type)
-               result->v_type = CTS_VALUE_LIST_NUMS_EMAILS;
-       else
-               result->v_type = CTS_VALUE_LIST_NUMBERINFO;
-
-       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);
-       temp = cts_stmt_get_text(stmt, i++);
-       result->connect = SAFE_STRDUP(temp);
-       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_ITER_NUMBERS_EMAILS == type) {
-               result->addrbook_id = cts_stmt_get_int(stmt, i++);
-               temp = cts_stmt_get_text(stmt, i++);
-               result->normalize = 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);
-       }
-
-       return (CTSvalue *)result;
-}
-
-static inline CTSvalue* cts_iter_get_info_sdn(cts_stmt stmt, int type)
-{
-       char *temp;
-       sdn_list *result;
-
-       result = (sdn_list *)contacts_svc_value_new(CTS_VALUE_LIST_SDN);
-       retvm_if(NULL == result, NULL, "contacts_svc_value_new() Failed");
-
-       temp = cts_stmt_get_text(stmt, 0);
-       result->name = SAFE_STRDUP(temp);
-       temp = cts_stmt_get_text(stmt, 1);
-       result->number = SAFE_STRDUP(temp);
-
-       return (CTSvalue *)result;
-}
-
-static inline CTSvalue* cts_iter_get_info_change(updated_record *cursor)
-{
-       change_list *result;
-
-       result = (change_list *)contacts_svc_value_new(CTS_VALUE_LIST_CHANGE);
-       retvm_if(NULL == result, NULL, "contacts_svc_value_new() Failed");
-
-       result->changed_type = cursor->type;
-       result->id = cursor->id;
-       result->changed_ver = cursor->ver;
-       result->addressbook_id = cursor->addressbook_id;
-
-       return (CTSvalue *)result;
-}
-
-static inline CTSvalue* cts_iter_get_info_plog(int type, cts_stmt stmt)
-{
-       int lang, cnt=0;
-       char *temp;
-       plog_list *result;
-
-       result = (plog_list *)contacts_svc_value_new(CTS_VALUE_LIST_PLOG);
-       retvm_if(NULL == result, NULL, "contacts_svc_value_new() Failed");
-
-       switch (type)
-       {
-       case CTS_ITER_GROUPING_PLOG:
-               result->id = cts_stmt_get_int(stmt, cnt++);
-               lang = cts_stmt_get_int(stmt, cnt++);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->first = SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->last = SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               result->display = SAFE_STRDUP(temp);
-               temp = cts_stmt_get_text(stmt, cnt++);
-               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);
-               }
-               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, cnt++);
-               result->number = SAFE_STRDUP(temp);
-               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++);
-               result->num_type = cts_stmt_get_int(stmt, cnt++);
-               break;
-       case CTS_ITER_PLOGS_OF_NUMBER:
-               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++);
-               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);
-               return NULL;
-       }
-       return (CTSvalue *)result;
-}
-
-static inline CTSvalue* cts_iter_get_info_custom_num_type(cts_stmt stmt)
-{
-       numtype_list *result;
-
-       result = (numtype_list *)contacts_svc_value_new(CTS_VALUE_LIST_CUSTOM_NUM_TYPE);
-       retvm_if(NULL == result, NULL, "contacts_svc_value_new() Failed");
-
-       result->id = cts_stmt_get_int(stmt, 0);
-       result->name = SAFE_STRDUP(cts_stmt_get_text(stmt, 1));
-
-       return (CTSvalue *)result;
-}
-
-static inline CTSvalue* cts_iter_get_info_addrbook(cts_stmt stmt)
-{
-       cts_addrbook *result;
-
-       result = (cts_addrbook *)contacts_svc_value_new(CTS_VALUE_LIST_ADDRBOOK);
-       retvm_if(NULL == result, NULL, "contacts_svc_value_new() Failed");
-
-       cts_stmt_get_addressbook(stmt, result);
-
-       return (CTSvalue *)result;
-}
-
-static inline CTSvalue* cts_iter_get_info_group(cts_stmt stmt)
-{
-       cts_group *result;
-
-       result = (cts_group *)contacts_svc_value_new(CTS_VALUE_LIST_GROUP);
-       retvm_if(NULL == result, NULL, "contacts_svc_value_new() Failed");
-
-       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;
-}
-
-static inline CTSvalue* cts_iter_get_info_shortcut(int type, cts_stmt stmt)
-{
-       int i, lang;
-       char *temp;
-       shortcut_list *result;
-
-       result = (shortcut_list *)contacts_svc_value_new(CTS_VALUE_LIST_SHORTCUT);
-       retvm_if(NULL == result, NULL, "contacts_svc_value_new() Failed");
-
-       i = 0;
-       result->contact_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);
-       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->id = cts_stmt_get_int(stmt, i++);
-       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);
-       }
-
-       if (CTS_ITER_ALL_CONTACT_FAVORITE != type) {
-               result->num_type = cts_stmt_get_int(stmt, i++);
-               temp = cts_stmt_get_text(stmt, i++);
-               result->number = SAFE_STRDUP(temp);
-
-               if (CTS_ITER_ALL_SPEEDDIAL == type)
-                       result->speeddial = cts_stmt_get_int(stmt, i++);
-       }
-
-       return (CTSvalue *)result;
-}
-
-API CTSvalue* contacts_svc_iter_get_info(CTSiter *iter)
-{
-       CTSvalue *result;
-
-       retvm_if(NULL == iter, NULL, "iter is NULL");
-
-       switch (iter->i_type)
-       {
-       case CTS_ITER_CONTACTS:
-       case CTS_ITER_CONTACTS_WITH_NAME:
-               result = cts_iter_get_info_contact(iter->stmt, iter->i_type);
-               retvm_if(NULL == result, NULL, "cts_iter_get_info_contact() Failed");
-               break;
-       case CTS_ITER_NUMBERINFOS:
-       case CTS_ITER_EMAILINFOS_WITH_EMAIL:
-       case CTS_ITER_NUMBERS_EMAILS:
-               result = cts_iter_get_info_number_email(iter->stmt, iter->i_type);
-               retvm_if(NULL == result, NULL, "cts_iter_get_info_number() Failed");
-               break;
-       case CTS_ITER_ALL_SDN:
-               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_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;
-       case CTS_ITER_ALL_CUSTOM_NUM_TYPE:
-               result = cts_iter_get_info_custom_num_type(iter->stmt);
-               retvm_if(NULL == result, NULL, "cts_iter_get_info_custom_num_type() Failed");
-               break;
-       case CTS_ITER_ADDRESSBOOKS:
-               result = cts_iter_get_info_addrbook(iter->stmt);
-               retvm_if(NULL == result, NULL, "cts_iter_get_info_addrbook() Failed");
-               break;
-       case CTS_ITER_GROUPS:
-               result = cts_iter_get_info_group(iter->stmt);
-               retvm_if(NULL == result, NULL, "cts_iter_get_info_group() Failed");
-               break;
-       case CTS_ITER_ALL_NUM_FAVORITE:
-       case CTS_ITER_ALL_CONTACT_FAVORITE:
-       case CTS_ITER_ALL_SPEEDDIAL:
-               result = cts_iter_get_info_shortcut(iter->i_type, iter->stmt);
-               retvm_if(NULL == result, NULL, "cts_iter_get_info_shortcut() Failed");
-               break;
-       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;
-       }
-
-       return result;
-}
-
diff --git a/src/cts-list.c b/src/cts-list.c
deleted file mode 100755 (executable)
index 727fb09..0000000
+++ /dev/null
@@ -1,1394 +0,0 @@
-/*
- * 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-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_record* cts_updated_info_add_mempool(void)
-{
-       int i;
-       updated_record *mempool;
-
-       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_record *mempool)
-{
-       updated_record *memseg, *tmp;
-
-       retv_if(NULL == mempool, CTS_ERR_ARG_NULL);
-
-       memseg = mempool;
-       while (memseg) {
-               tmp = memseg[CTS_MALLOC_DEFAULT_NUM-1].next;
-               free(memseg);
-               memseg = tmp;
-       }
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_iter_next(CTSiter *iter)
-{
-       int ret;
-
-       retv_if(NULL == iter, CTS_ERR_ARG_NULL);
-       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_INFO_AFTER_VER == iter->i_type)
-       {
-               retv_if(NULL == iter->info, CTS_ERR_ARG_INVALID);
-
-               if (NULL == iter->info->cursor)
-                       iter->info->cursor = iter->info->head;
-               else
-                       iter->info->cursor = iter->info->cursor->next;
-               if (NULL == iter->info->cursor || 0 == iter->info->cursor->id) {
-                       iter->info->cursor = NULL;
-                       cts_updated_contact_free_mempool(iter->info->head);
-                       iter->info->head = NULL;
-                       return CTS_ERR_FINISH_ITER;
-               }
-       }
-       else
-       {
-               ret = cts_stmt_step(iter->stmt);
-               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 ret;
-               }
-       }
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_iter_remove(CTSiter *iter)
-{
-       retv_if(NULL == iter, CTS_ERR_ARG_NULL);
-       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_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);
-               free(iter->info);
-       }
-       else {
-               cts_stmt_finalize(iter->stmt);
-       }
-
-       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, *data;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       retv_if(NULL == iter, CTS_ERR_ARG_NULL);
-
-       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:
-               iter->i_type = CTS_ITER_CONTACTS;
-
-               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;
-
-               snprintf(query, sizeof(query),
-                               "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);
-               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_ADDRESSBOOK:
-               iter->i_type = CTS_ITER_ADDRESSBOOKS;
-               snprintf(query, sizeof(query),
-                               "SELECT addrbook_id, addrbook_name, acc_id, acc_type, mode "
-                               "FROM %s ORDER BY acc_id, addrbook_id",
-                               CTS_TABLE_ADDRESSBOOKS);
-
-               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_GROUP:
-               iter->i_type = CTS_ITER_GROUPS;
-               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);
-
-               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_CUSTOM_NUM_TYPE:
-               iter->i_type = CTS_ITER_ALL_CUSTOM_NUM_TYPE;
-               snprintf(query, sizeof(query), "SELECT id, name FROM %s WHERE class = %d",
-                               CTS_TABLE_CUSTOM_TYPES, CTS_TYPE_CLASS_NUM);
-
-               stmt = cts_query_prepare(query);
-               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-               iter->stmt = stmt;
-               break;
-       case CTS_LIST_GROUPING_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.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 "
-                               "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, 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_GROUPING_MSG_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.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 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, 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;
-               break;
-       case CTS_LIST_GROUPING_CALL_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.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 "
-                               "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, 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;
-               break;
-       case CTS_LIST_ALL_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.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 "
-                               "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_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;
-               break;
-       case CTS_LIST_ALL_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 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, data, CTS_DATA_NUMBER, data, CTS_DATA_NUMBER,
-                               CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN, CTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN,
-                               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_NUMBER_FAVORITE:
-               iter->i_type = CTS_ITER_ALL_NUM_FAVORITE;
-               snprintf(query, sizeof(query),
-                               "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.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",
-                               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");
-               iter->stmt = stmt;
-               break;
-       case CTS_LIST_ALL_CONTACT_FAVORITE:
-               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.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.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",
-                               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;
-               break;
-       case CTS_LIST_ALL_SPEEDDIAL:
-               iter->i_type = CTS_ITER_ALL_SPEEDDIAL;
-               snprintf(query, sizeof(query),
-                               "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.person_id "
-                               "ORDER BY C.speed_num",
-                               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");
-               iter->stmt = stmt;
-               break;
-       case CTS_LIST_ALL_SDN:
-               iter->i_type = CTS_ITER_ALL_SDN;
-               snprintf(query, sizeof(query),"SELECT name, number FROM %s",
-                               CTS_TABLE_SIM_SERVICES);
-               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_HAD_NUMBER:
-               iter->i_type = CTS_ITER_CONTACTS;
-
-               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;
-
-               snprintf(query, sizeof(query),
-                               "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);
-               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_HAD_EMAIL:
-               iter->i_type = CTS_ITER_CONTACTS;
-               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;
-
-               snprintf(query, sizeof(query),
-                               "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);
-               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_NUMBER:
-               iter->i_type = CTS_ITER_NUMBERS_EMAILS;
-
-               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;
-
-               snprintf(query, sizeof(query),
-                               "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.person_id "
-                               "WHERE A.datatype = %d AND (B.datatype = %d OR B.datatype = %d) "
-                               "ORDER BY A.data1, A.%s",
-                               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");
-               iter->stmt = stmt;
-               break;
-       case CTS_LIST_OFTEN_USED_CONTACT:
-               iter->i_type = CTS_ITER_CONTACTS;
-
-               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;
-
-               snprintf(query, sizeof(query),
-                               "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 "
-                               "ORDER BY A.outgoing_count DESC, data1, %s",
-                               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");
-               iter->stmt = stmt;
-               break;
-       case CTS_LIST_ALL_NUMBER:
-               iter->i_type = CTS_ITER_NUMBERS_EMAILS;
-
-               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;
-
-               snprintf(query, sizeof(query),
-                               "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.person_id "
-                               "WHERE A.datatype = %d AND B.datatype = %d "
-                               "ORDER BY A.data1, A.%s",
-                               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");
-               iter->stmt = stmt;
-               break;
-       default:
-               ERR("Invalid parameter : The op_code(%d) is not supported", op_code);
-               return CTS_ERR_ARG_INVALID;
-       }
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_get_list(cts_get_list_op op_code, CTSiter **iter)
-{
-       int ret;
-       CTSiter *result;
-
-       retv_if(NULL == iter, CTS_ERR_ARG_NULL);
-
-       result = calloc(1, sizeof(CTSiter));
-       retvm_if(NULL == result, CTS_ERR_OUT_OF_MEMORY, "calloc() Failed");
-
-       ret = cts_get_list(op_code, result);
-       if (ret) {
-               ERR("cts_get_list() Failed(%d)", ret);
-               free(result);
-               return ret;
-       }
-
-       *iter = (CTSiter *)result;
-       INFO(",CTSiter,1");
-       return CTS_SUCCESS;
-}
-
-static inline int cts_get_list_with_str(cts_get_list_str_op op_code,
-               const char *search_value, CTSiter *iter)
-{
-       int ret;
-       cts_stmt stmt = NULL;
-       const char *display, *data;
-       char query[CTS_SQL_MAX_LEN] = {0};
-       char remake_val[CTS_SQL_MIN_LEN];
-
-       CTS_START_TIME_CHECK;
-
-       retv_if(NULL == iter, CTS_ERR_ARG_NULL);
-
-       iter->i_type = CTS_ITER_NONE;
-       iter->stmt = NULL;
-
-       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:
-               iter->i_type = CTS_ITER_PLOGS_OF_NUMBER;
-               if (search_value && *search_value) {
-                       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 {
-                       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);
-               }
-               stmt = cts_query_prepare(query);
-               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-               if (search_value) {
-                       const char *normal_num;
-                       ret = cts_clean_number(search_value, remake_val, sizeof(remake_val));
-                       retvm_if(ret <= 0, CTS_ERR_ARG_INVALID, "Number(%s) is invalid", search_value);
-
-                       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, search_value, strlen(search_value));
-               }
-               iter->stmt = stmt;
-               break;
-       case CTS_LIST_CONTACTS_WITH_NAME:
-               retvm_if(CTS_SQL_MIN_LEN <= strlen(search_value), 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(search_value, remake_val, CTS_SQL_MIN_LEN);
-               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))
-                       display = CTS_SCHEMA_DATA_NAME_REVERSE_LOOKUP;
-               else
-                       display = CTS_SCHEMA_DATA_NAME_LOOKUP;
-
-               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);
-               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));
-               iter->stmt = stmt;
-               break;
-       case CTS_LIST_NUMBERINFOS_WITH_NAME:
-               retvm_if(CTS_SQL_MIN_LEN <= strlen(search_value), 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(search_value, remake_val, CTS_SQL_MIN_LEN);
-               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))
-                       display = CTS_SCHEMA_DATA_NAME_REVERSE_LOOKUP;
-               else
-                       display = CTS_SCHEMA_DATA_NAME_LOOKUP;
-
-               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);
-
-               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));
-               iter->stmt = stmt;
-               break;
-       case CTS_LIST_NUMBERINFOS_WITH_NUM:
-               iter->i_type = CTS_ITER_NUMBERINFOS;
-
-               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_NUMBER, 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, search_value, strlen(search_value));
-               iter->stmt = stmt;
-               break;
-       case CTS_LIST_EMAILINFOS_WITH_EMAIL:
-               iter->i_type = CTS_ITER_EMAILINFOS_WITH_EMAIL;
-               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);
-               stmt = cts_query_prepare(query);
-               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-               cts_stmt_bind_copy_text(stmt, 1, search_value, strlen(search_value));
-               iter->stmt = stmt;
-               break;
-       case 10000: /* It is not supported. use only inhouse phone and message application */
-               retvm_if(CTS_SQL_MIN_LEN - 50 < strlen(search_value),
-                               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%%' 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");
-               iter->stmt = stmt;
-               break;
-       default:
-               ERR("Invalid parameter : The op_code(%d) is not supported", op_code);
-               return CTS_ERR_ARG_INVALID;
-       }
-       CTS_START_TIME_CHECK;
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_get_list_with_str(cts_get_list_str_op op_code,
-               const char *search_value, CTSiter **iter)
-{
-       int ret;
-       CTSiter *result;
-
-       retv_if(NULL == iter, CTS_ERR_ARG_NULL);
-
-       result = calloc(1, sizeof(CTSiter));
-       retvm_if(NULL == result, CTS_ERR_OUT_OF_MEMORY, "calloc() Failed");
-
-       ret = cts_get_list_with_str(op_code, search_value, result);
-       if (ret) {
-               ERR("cts_get_list_with_str() Failed(%d)", ret);
-               free(result);
-               return ret;
-       }
-
-       *iter = (CTSiter *)result;
-       INFO(",CTSiter,1");
-       return CTS_SUCCESS;
-}
-
-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, *data;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       retv_if(NULL == iter, CTS_ERR_ARG_NULL);
-       iter->i_type = CTS_ITER_NONE;
-       iter->stmt = NULL;
-
-       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 (op_code) {
-       case CTS_LIST_MEMBERS_OF_GROUP_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.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, 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_NO_GROUP_MEMBERS_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 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_MEMBERS_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 "
-                               "GROUP BY B.person_id "
-                               "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_GROUPS_OF_ADDRESSBOOK_ID:
-               iter->i_type = CTS_ITER_GROUPS;
-               snprintf(query, sizeof(query),
-                               "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);
-               stmt = cts_query_prepare(query);
-               retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-               iter->stmt = stmt;
-               break;
-       case CTS_LIST_ADDRESSBOOKS_OF_ACCOUNT_ID:
-               iter->i_type = CTS_ITER_ADDRESSBOOKS;
-               snprintf(query, sizeof(query),
-                               "SELECT addrbook_id, addrbook_name, acc_id, acc_type, mode "
-                               "FROM %s WHERE acc_id = %d "
-                               "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;
-       }
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_get_list_with_int(cts_get_list_int_op op_code,
-               unsigned int search_value, CTSiter **iter)
-{
-       int ret;
-       CTSiter *result;
-
-       retv_if(NULL == iter, CTS_ERR_ARG_NULL);
-
-       result = calloc(1, sizeof(CTSiter));
-       retvm_if(NULL == result, CTS_ERR_OUT_OF_MEMORY, "calloc() Failed");
-
-       ret = cts_get_list_with_int(op_code, search_value, result);
-       if (ret) {
-               ERR("cts_get_list_with_int() Failed(%d)", ret);
-               free(result);
-               return ret;
-       }
-
-       *iter = (CTSiter *)result;
-       INFO(",CTSiter,1");
-       return CTS_SUCCESS;
-}
-
-static inline int cts_get_updated_contacts(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, 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");
-
-       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_contacts(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_contacts(addressbook_id, version, result);
-       if (ret) {
-               ERR("cts_get_updated_contacts() Failed(%d)", ret);
-               free(result->info);
-               free(result);
-               return ret;
-       }
-
-       *iter = (CTSiter *)result;
-       INFO(",CTSiter,1");
-       return CTS_SUCCESS;
-}
-
-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;
-               CTSvalue *value;
-               value = contacts_svc_iter_get_info(iter);
-
-               ret = cb(value, data);
-               if (CTS_SUCCESS != ret) {
-                       ERR("cts_foreach_fn(%p) Failed(%d)", cb, ret);
-                       contacts_svc_value_free(value);
-                       break;
-               }
-
-               contacts_svc_value_free(value);
-       }
-       cts_stmt_finalize(iter->stmt);
-}
-
-API int contacts_svc_list_foreach(cts_get_list_op op_code,
-               cts_foreach_fn cb, void *user_data)
-{
-       int ret;
-       CTSiter iter = {0};
-
-       ret = cts_get_list(op_code, &iter);
-       retvm_if(CTS_SUCCESS != ret, ret, "cts_get_list() Failed(%d)", ret);
-
-       cts_foreach_run(&iter, cb, user_data);
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_list_with_int_foreach(cts_get_list_int_op op_code,
-               unsigned int search_value, cts_foreach_fn cb, void *user_data)
-{
-       int ret;
-       CTSiter iter = {0};
-
-       ret = cts_get_list_with_int(op_code, search_value, &iter);
-       retvm_if(CTS_SUCCESS != ret, ret, "cts_get_list_with_int() Failed(%d)", ret);
-
-       cts_foreach_run(&iter, cb, user_data);
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_list_with_str_foreach(cts_get_list_str_op op_code,
-               const char *search_value, cts_foreach_fn cb, void *user_data)
-{
-       int ret;
-       CTSiter iter = {0};
-
-       ret = cts_get_list_with_str(op_code, search_value, &iter);
-       retvm_if(CTS_SUCCESS != ret, ret, "cts_get_list_with_str() Failed(%d)", ret);
-
-       cts_foreach_run(&iter, cb, user_data);
-
-       return CTS_SUCCESS;
-}
-
-// same with check_dirty_number()
-static inline bool cts_is_number(const char *str)
-{
-       int i;
-
-       for (i=0;i<strlen(str);i++)
-       {
-               switch (str[i])
-               {
-               case '0' ... '9':
-               case 'p':
-               case 'w':
-               case 'P':
-               case 'W':
-               case '#':
-               case '*':
-               case '+':
-                       break;
-               default:
-                       return false;
-               }
-       }
-       return true;
-}
-
-static inline int cts_escape_like_patten(const char *src, char *dest, int dest_size)
-{
-       int s_pos=0, d_pos=0;
-
-       if (NULL == src) {
-               ERR("The parameter(src) is NULL");
-               dest[d_pos] = '\0';
-               return 0;
-       }
-
-       while (src[s_pos] != 0) {
-               if (dest_size == d_pos - 1)
-                       break;
-               if ('%' == src[s_pos] || '_' == src[s_pos]) {
-                       dest[d_pos++] = '\\';
-               }
-               dest[d_pos++] = src[s_pos++];
-       }
-
-       dest[d_pos] = '\0';
-       return d_pos;
-}
-
-API int contacts_svc_smartsearch_excl(const char *search_str, int limit, int offset,
-               cts_foreach_fn cb, void *user_data)
-{
-       int ret, len;
-       CTSiter iter = {0};
-       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];
-
-       retv_if(NULL == search_str, CTS_ERR_ARG_NULL);
-       retvm_if(CTS_SQL_MIN_LEN <= strlen(search_str), CTS_ERR_ARG_INVALID,
-                       "search_str is too long");
-
-       iter.i_type = CTS_ITER_NUMBERINFOS;
-
-       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 (cts_is_number(search_str)) {
-               len = snprintf(query, sizeof(query),
-                               "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",
-                               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 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",
-                               data, CTS_TABLE_CONTACTS, CTS_DATA_NAME,
-                               data, CTS_DATA_NUMBER,
-                               display, CTS_SCHEMA_DATA_NAME_SORTING_KEY);
-       }
-
-       if (limit)
-               snprintf(query+len, sizeof(query)-len, " LIMIT %d OFFSET %d", limit, offset);
-
-       ret = cts_normalize_str(search_str, remake_name, sizeof(remake_name));
-       retvm_if(ret < CTS_SUCCESS, ret, "cts_normalize_str() Failed(%d)", ret);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       cts_escape_like_patten(remake_name, escape_name, sizeof(escape_name));
-       cts_stmt_bind_copy_text(stmt, 1, escape_name, strlen(escape_name));
-       iter.stmt = stmt;
-
-       cts_foreach_run(&iter, cb, user_data);
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_group_get_relation_changes(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;
-
-       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");
-
-       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->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_info_add_mempool();
-               result = result->next;
-       }while(CTS_TRUE == cts_stmt_step(stmt));
-
-       cts_stmt_finalize(stmt);
-
-       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
deleted file mode 100755 (executable)
index 05b15e3..0000000
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * 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_H__
-#define __CTS_LIST_H__
-
-#include "cts-sqlite.h"
-
-enum
-{
-       CTS_ITER_NONE,
-       CTS_ITER_CONTACTS,
-       CTS_ITER_ALL_CUSTOM_NUM_TYPE,
-       CTS_ITER_GROUPING_PLOG,
-       CTS_ITER_ALL_CONTACT_FAVORITE,
-       CTS_ITER_ALL_NUM_FAVORITE,
-       CTS_ITER_ALL_SPEEDDIAL,
-       CTS_ITER_ALL_SDN,
-       CTS_ITER_PLOGS_OF_NUMBER,
-       CTS_ITER_PLOGNUMBERS_WITH_NUM,
-       CTS_ITER_CONTACTS_WITH_NAME,
-       CTS_ITER_NUMBERINFOS,
-       CTS_ITER_EMAILINFOS_WITH_EMAIL,
-       CTS_ITER_NUMBERS_EMAILS,
-       CTS_ITER_GROUPS,
-       CTS_ITER_ADDRESSBOOKS,
-       CTS_ITER_EMAILS_OF_CONTACT_ID,
-       CTS_ITER_NUMBERS_OF_CONTACT_ID,
-       CTS_ITER_UPDATED_INFO_AFTER_VER,
-       CTS_ITER_PLOGS_OF_PERSON_ID,
-       CTS_ITER_OSP,
-       CTS_ITER_MAX
-};
-
-typedef struct _updated_record {
-       int type;
-       int id;
-       int ver;
-       int addressbook_id;
-       struct _updated_record *next;
-}updated_record;
-
-typedef struct {
-       updated_record *head;
-       updated_record *cursor;
-}updated_info;
-
-struct _cts_iter {
-       int i_type;
-       cts_stmt stmt;
-       updated_info *info;
-};
-
-//<!--
-/**
- * @defgroup   CONTACTS_SVC_LIST List handling
- * @ingroup    CONTACTS_SVC
- * @addtogroup CONTACTS_SVC_LIST
- * @{
- *
- * 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.
- * Iterator can get by contacts_svc_get_list(), contacts_svc_get_list_with_int(),
- * contacts_svc_get_list_with_str(), contacts_svc_get_list_with_filter(), contacts_svc_get_updated_contacts().
- * \n And Iterator can handle by contacts_svc_iter_next(), contacts_svc_iter_remove(), contacts_svc_iter_get_info().
- */
-typedef struct _cts_iter CTSiter;
-
-//////////////////// read only value ////////////////////
-//////////////////// List row info ////////////////////
-/**
- * Phone Log List
- * 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,/**< . */
-       CTS_LIST_PLOG_NUM_TYPE_INT,/**< you can use #NUMBERTYPE or contacts_svc_find_custom_type(). */
-       CTS_LIST_PLOG_FIRST_NAME_STR,/**< . */
-       CTS_LIST_PLOG_LAST_NAME_STR,/**< . */
-       CTS_LIST_PLOG_DISPLAY_NAME_STR,/**< . */
-       CTS_LIST_PLOG_NUMBER_STR,/**< . */
-       CTS_LIST_PLOG_IMG_PATH_STR,/**< . */
-       CTS_LIST_PLOG_LOG_TIME_INT,/**< The time since the Epoch (00:00:00 UTC, January 1, 1970), measured in seconds. */
-       CTS_LIST_PLOG_LOG_TYPE_INT,/**< #PLOGTYPE  */
-       CTS_LIST_PLOG_DURATION_INT,/**< seconds */
-       CTS_LIST_PLOG_MSGID_INT,/**< . */
-       CTS_LIST_PLOG_SHORTMSG_STR,/**< . */
-       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
- * Usually, This is sorted by name related with #CTS_ORDER_OF_SORTING
- */
-enum CONTACTLIST{
-       CTS_LIST_CONTACT_ID_INT,/**< . */
-       CTS_LIST_CONTACT_IMG_PATH_STR,/**< . */
-       CTS_LIST_CONTACT_FIRST_STR,/**< . */
-       CTS_LIST_CONTACT_LAST_STR,/**< . */
-       CTS_LIST_CONTACT_DISPLAY_STR,/**< . */
-       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,/**< . */
-};
-
-/**
- * Number List
- */
-enum NUMBERLIST{
-       CTS_LIST_NUM_CONTACT_ID_INT,/**< . */
-       CTS_LIST_NUM_CONTACT_IMG_PATH_STR,/**< . */
-       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_PERSON_ID_INT,/**< . */
-};
-
-/**
- * Email List
- */
-enum EMAILLIST{
-       CTS_LIST_EMAIL_CONTACT_ID_INT,/**< . */
-       CTS_LIST_EMAIL_CONTACT_IMG_PATH_STR,/**< . */
-       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_PERSON_ID_INT /**< . */
-};
-
-
-/**
- * Change List
- */
-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 {
-       CTS_OPERATION_UPDATED, /**< . */
-       CTS_OPERATION_DELETED, /**< . */
-       CTS_OPERATION_INSERTED /**< . */
-};
-
-/**
- * Addressbook List
- * Usually, This is sorted by acc_id and addressbook id
- * Though it is same with ADDRESSBOOKVALUE, Use this for list
- */
-enum ADDRESSBOOKLIST{
-       CTS_LIST_ADDRESSBOOK_ID_INT, /**< . */
-       CTS_LIST_ADDRESSBOOK_NAME_STR, /**< . */
-       CTS_LIST_ADDRESSBOOK_ACC_ID_INT, /**< The related account id */
-       CTS_LIST_ADDRESSBOOK_ACC_TYPE_INT, /**< #ADDRESSBOOKTYPE */
-       CTS_LIST_ADDRESSBOOK_MODE_INT, /**< #ADDRESSBOOKPERMISSION */
-};
-
-/**
- * Custom Number Type List
- */
-enum CUSTOMNUMTYPELIST{
-       CTS_LIST_CUSTOM_NUM_TYPE_ID_INT,/**< . */
-       CTS_LIST_CUSTOM_NUM_TYPE_NAME_STR,/**< . */
-};
-
-
-/**
- * Group List
- * Usually, This is sorted by addressbook_id and name.
- */
-enum GROUPLIST{
-       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,/**< . */
-};
-
-/**
- * Favorite List or Speeddial List
- */
-enum SHORTCUTLIST{
-       CTS_LIST_SHORTCUT_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,/**< . */
-       CTS_LIST_SHORTCUT_IMG_PATH_STR,/**< . */
-       CTS_LIST_SHORTCUT_NUMBER_STR,/**< only for #CTS_FAVOR_NUMBER */
-       CTS_LIST_SHORTCUT_NUMBER_TYPE_INT,/**< only for #CTS_FAVOR_NUMBER */
-       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
- */
-enum SDNLIST{
-       CTS_LIST_SDN_NAME_STR,/**< . */
-       CTS_LIST_SDN_NUMBER_STR,/**< . */
-};
-
-/**
- * Use for contacts_svc_get_list().
- */
-typedef enum{
-       CTS_LIST_ALL_CONTACT, /**< #CONTACTLIST */
-       CTS_LIST_ALL_GROUP,/**< #GROUPLIST */
-       CTS_LIST_ALL_CUSTOM_NUM_TYPE,/**< #CUSTOMNUMTYPELIST */
-       CTS_LIST_ALL_CONTACT_FAVORITE,/**< #SHORTCUTLIST */
-       CTS_LIST_ALL_SPEEDDIAL,/**< #SHORTCUTLIST */
-       CTS_LIST_GROUPING_PLOG,/**< #PHONELOGLIST */
-       CTS_LIST_GROUPING_MSG_PLOG,/**< #PHONELOGLIST */
-       CTS_LIST_GROUPING_CALL_PLOG,/**< #PHONELOGLIST */
-       CTS_LIST_ALL_SDN,/**< #SDNLIST */
-       CTS_LIST_ALL_CONTACT_HAD_NUMBER,/**< #CONTACTLIST */
-       CTS_LIST_ALL_CONTACT_HAD_EMAIL,/**< #CONTACTLIST */
-       CTS_LIST_ALL_EMAIL_NUMBER,/**< #CONTACTLIST */
-       CTS_LIST_ALL_NUMBER_FAVORITE,/**< #SHORTCUTLIST */
-       CTS_LIST_OFTEN_USED_CONTACT, /**< #CONTACTLIST. sorted by count of using(using means outgoing call/video call)*/
-       CTS_LIST_ALL_ADDRESSBOOK, /**< #ADDRESSBOOKLIST */
-       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.
- * \n Obtained iterator should be free using by contacts_svc_iter_remove().
- *
- * @param[in] op_code #cts_get_list_op
- * @param[out] iter Point of data iterator
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @see contacts_svc_get_list_with_str(), contacts_svc_get_list_with_int()
- * @par example
- * @code
- void get_contact_list(void)
- {
-    CTSiter *iter = NULL;
-    contacts_svc_get_list(CTS_LIST_ALL_CONTACT, &iter);
-
-    while(CTS_SUCCESS == contacts_svc_iter_next(iter))
-    {
-       CTSvalue *contact = NULL;
-       char *first, *last, *display;
-       contacts_svc_iter_get_info(iter, &contact);
-
-       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);
- }
- * @endcode
- */
-int contacts_svc_get_list(cts_get_list_op op_code, CTSiter **iter);
-
-/**
- * Use for contacts_svc_get_list_with_str().
- */
-typedef enum{
-       CTS_LIST_PLOGS_OF_NUMBER,/**< #PHONELOGLIST */
-       CTS_LIST_CONTACTS_WITH_NAME,/**< #CONTACTLIST */
-       CTS_LIST_NUMBERINFOS_WITH_NAME,/**< #NUMBERLIST */
-       CTS_LIST_NUMBERINFOS_WITH_NUM,/**< #NUMBERLIST */
-       CTS_LIST_EMAILINFOS_WITH_EMAIL,/**< #EMAILLIST */
-       //CTS_LIST_NUMBERS_EMAILS_WITH_NAME,/**< #EMAILLIST */
-}cts_get_list_str_op;
-/**
- * This function gets iterator of the gotten data by op_code with string search value.
- * \n search_value is related with op_code. The Word after preposition is a property of search_value.
- * \n Obtained iterator should be free using by contacts_svc_iter_remove().
- *
- * @param[in] op_code #cts_get_list_str_op
- * @param[in] search_value String search value
- * @param[out] iter Point of data iterator to be got
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @see contacts_svc_get_list(), contacts_svc_get_list_with_int()
- */
-int contacts_svc_get_list_with_str(cts_get_list_str_op op_code, const char *search_value, CTSiter **iter);
-
-/**
- * Use for contacts_svc_get_list_with_int().
- */
-typedef enum{
-       CTS_LIST_MEMBERS_OF_GROUP_ID,/**< #CONTACTLIST */
-       CTS_LIST_MEMBERS_OF_ADDRESSBOOK_ID,/**< #CONTACTLIST */
-       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;
-/**
- * This function gets iterator of the gotten data by op_code with integer search value.
- * \n search_value is related with op_code. The Word after preposition is a property of search_value.
- * \n Obtained iterator should be free using by contacts_svc_iter_remove().
- *
- * @param[in] op_code #cts_get_list_int_op
- * @param[in] search_value Integer search value
- * @param[out] iter Point of data iterator to be got
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @see contacts_svc_get_list(), contacts_svc_get_list_with_str()
- */
-int contacts_svc_get_list_with_int(cts_get_list_int_op op_code, unsigned int search_value, CTSiter **iter);
-
-/**
- * This function gets iterator of the gotten data related to updated contacts since the version(not include version).
- * If contact includes both insert and update changes after version, the change type of contact is #CTS_OPERATION_INSERTED.
- * If you want to get the last contacts version, use transaction explicitly.
- * contacts_svc_end_trans() return the last contacts version.
- * Obtained iterator should be free using by contacts_svc_iter_remove().
- *
- * @param[in] addressbook_id The index of addressbook. 0 is local(phone internal)
- * @param[in] version The contact version gotten by contacts_svc_end_trans().
- * @param[out] iter Point of data iterator to be got(#CHANGELIST)
- * @return #CTS_SUCCESS on success, #CTS_ERR_DB_RECORD_NOT_FOUND on No change, Other negative value(#cts_error) on error,
- *
- * @see #CHANGELIST
- * @par example
- * @code
-  void sync_data(void)
-  {
-     int ret, version=0, index_num;
-     CTSiter *iter = NULL;
-     contacts_svc_get_updated_contacts(0, version, &iter);
-
-     while(CTS_SUCCESS == contacts_svc_iter_next(iter))
-     {
-        CTSstruct *contact= NULL;
-        CTSvalue *row_info = NULL;
-        row_info = contacts_svc_iter_get_info(iter);
-
-        index_num = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_ID_INT);
-        printf("(%8d)\n", index_num);
-        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_TIME_INT);
-
-        if(CTS_OPERATION_UPDATED == type || CTS_OPERATION_INSERTED == type) {
-           contacts_svc_get_contact(index_num, &contact);
-           void *vcard_stream;
-           char file[128];
-           snprintf(file, sizeof(file), "test%d.vcf", index_num);
-           ret = contacts_svc_get_vcard_from_contact(contact, &vcard_stream);
-           if(CTS_SUCCESS == ret) {
-              //int fd = open(file, O_RDWR | O_CREAT);
-              //write(fd, (char *)vcard_stream, strlen((char *)vcard_stream));
-              //close(fd);
-              CTSstruct *new_contact = NULL;
-              ret = contacts_svc_get_contact_from_vcard(vcard_stream, &new_contact);
-              if(CTS_SUCCESS == ret) {
-                 get_contact(new_contact);
-                 contacts_svc_struct_free(new_contact);
-              }
-              free(vcard_stream);
-           }
-           if(CTS_OPERATION_INSERTED == type)
-              printf("Added : %d \n", ver);
-           else
-              printf("Updated : %d \n", ver);
-           contacts_svc_struct_free(contact);
-        }
-        else
-           printf("Deleted : %d \n", ver);
-
-        contacts_svc_value_free(row_info);
-     }
-     contacts_svc_iter_remove(iter);
-  }
- * @endcode
- */
-int contacts_svc_get_updated_contacts(int addressbook_id,
-      int version, CTSiter **iter);
-
-/**
- * This function reads information from the iterator.
- * Obtained information should be free using by contacts_svc_value_free().
- *
- * @param[in] iter The data iterator
- * @return The gotten information, or NULL if no value is obtained or error
- */
-CTSvalue* contacts_svc_iter_get_info(CTSiter *iter);
-
-/**
- * This function removes the iterator.
- * \n You should call this function after using iterator.
- *
- * @param[in] iter The data iterator
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_iter_remove(CTSiter *iter);
-
-/**
- * This function moves the iterator to the next record, if any.
- * Must also be called before reading first record, to determine
- * whether there is such a record at all.
- * If there's no next record, returns #CTS_ERR_FINISH_ITER.
- *
- * @param[in] iter The data iterator
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_iter_next(CTSiter *iter);
-
-/**
- * This is the signature of a callback function added with contacts_svc_list_foreach(),
- * contacts_svc_list_with_int_foreach() and contacts_svc_list_with_str_foreach().
- * \n This function is invoked in the above functions.
- * \n If this function doesn't return #CTS_SUCCESS, foreach function is terminated.
- *
- * @param[in] value data of a record.
- * @param[in] user_data The data which is set by contacts_svc_list_foreach(),
- * contacts_svc_list_with_int_foreach() and contacts_svc_list_with_str_foreach().
- * @return #CTS_SUCCESS on success, other value on error
- */
-typedef int (*cts_foreach_fn)(CTSvalue *value, void *user_data);
-
-
-/**
- * This function calls #cts_foreach_fn for each record of list gotten by op_code.
- *
- * @param[in] op_code #cts_get_list_op
- * @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
- * @see contacts_svc_get_list()
- */
-int contacts_svc_list_foreach(cts_get_list_op op_code,
-   cts_foreach_fn cb, void *user_data);
-
-/**
- * This function calls #cts_foreach_fn for each record of list gotten by op_code.
- *
- * @param[in] op_code #cts_get_list_int_op
- * @param[in] search_value Integer search value
- * @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
- * @see contacts_svc_get_list_with_int()
- */
-int contacts_svc_list_with_int_foreach(cts_get_list_int_op op_code,
-   unsigned int search_value, cts_foreach_fn cb, void *user_data);
-
-/**
- * This function calls #cts_foreach_fn for each record of list gotten by op_code.
- *
- * @param[in] op_code #cts_get_list_str_op
- * @param[in] search_value String search value
- * @param[in] cb callback function pointer(#cts_foreach_fn)
- * @param[in] data data which is passed to callback function
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @see contacts_svc_get_list_with_str()
- */
-int contacts_svc_list_with_str_foreach(cts_get_list_str_op op_code,
-   const char *search_value, cts_foreach_fn cb, void *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.
- *
- * @param[in] search_str String search value(number or name)
- * @param[in] limit an upper bound on the number of result. If it has a negative value, there is no upper bound.
- * @param[in] offset It omits offset rows for the result.
- * @param[in] cb callback function pointer(#cts_foreach_fn) with #CTSvalue(#NUMBERLIST)
- * @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_smartsearch_excl(const char *search_str, int limit, int offset,
-   cts_foreach_fn cb, void *user_data);
-
-/**
- * @}
- */
-//-->
-
-void cts_foreach_run(CTSiter *iter, cts_foreach_fn cb, void *data);
-
-
-#endif //__CTS_LIST_H__
-
diff --git a/src/cts-normalize.c b/src/cts-normalize.c
deleted file mode 100755 (executable)
index aa8a52c..0000000
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- * Contacts Service
- *
- * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Youngjae Shin <yj99.shin@samsung.com>
- *          Donghee Ye <donghee.ye@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 <string.h>
-
-#include "cts-internal.h"
-#include "cts-normalize.h"
-#include "cts-socket.h"
-#include "cts-pthread.h"
-#include "cts-utils.h"
-
-static int (*extra_normalize_fn)(char dest[][CTS_SQL_MAX_LEN]);
-
-static inline int check_utf8(char c)
-{
-       if ((c & 0xff) < (128 & 0xff))
-               return 1;
-       else if ((c & (char)0xe0) == (char)0xc0)
-               return 2;
-       else if ((c & (char)0xf0) == (char)0xe0)
-               return 3;
-       else if ((c & (char)0xf8) == (char)0xf0)
-               return 4;
-       else if ((c & (char)0xfc) == (char)0xf8)
-               return 5;
-       else if ((c & (char)0xfe) == (char)0xfc)
-               return 6;
-       else
-               return CTS_ERR_FAIL;
-}
-
-static inline bool check_dirty_number(char digit)
-{
-       switch (digit)
-       {
-       case '0' ... '9':
-       case 'p':
-       case 'w':
-       case 'P':
-       case 'W':
-       case '#':
-       case '*':
-               return false;
-       case '+': //only first position
-       default:
-               return true;
-       }
-}
-
-int cts_clean_number(const char *src, char *dest, int dest_size)
-{
-       int s_pos=0, d_pos=0, char_type;
-
-       if (NULL == src)
-               ERR("The parameter(src) is NULL");
-       else
-       {
-               if ('+' == src[s_pos])
-                       dest[d_pos++] = src[s_pos++];
-
-               while (src[s_pos] != 0)
-               {
-                       if (d_pos >= dest_size-2) break;
-                       char_type = check_utf8(src[s_pos]);
-                       if (char_type <= 1) {
-                               if (check_dirty_number(src[s_pos])) {
-                                       s_pos++;
-                                       continue;
-                               }
-                               dest[d_pos++] = src[s_pos++];
-                       }
-                       else
-                               s_pos += char_type;
-               }
-       }
-
-       dest[d_pos] = 0;
-       return d_pos;
-}
-
-static int cts_remove_special_char(const char *src, char *dest, int dest_size)
-{
-       int s_pos=0, d_pos=0, char_type, src_size;
-
-       if (NULL == src) {
-               ERR("The parameter(src) is NULL");
-               dest[d_pos] = '\0';
-               return 0;
-       }
-       src_size = strlen(src);
-
-       while (src[s_pos] != 0)
-       {
-               char_type = check_utf8(src[s_pos]);
-
-               if (0 < char_type && char_type < dest_size - d_pos && char_type <= src_size - s_pos) {
-                       memcpy(dest+d_pos, src+s_pos, char_type);
-                       d_pos += char_type;
-                       s_pos += char_type;
-               }
-               else {
-                       ERR("The parameter(src:%s) has invalid character set", src);
-                       dest[d_pos] = '\0';
-                       return CTS_ERR_ARG_INVALID;
-               }
-       }
-
-       dest[d_pos] = '\0';
-       return d_pos;
-}
-
-int cts_normalize_str(const char *src, char *dest, int dest_size)
-{
-       int ret;
-       ret = cts_remove_special_char(src, dest, dest_size);
-       retvm_if(ret < CTS_SUCCESS, ret, "cts_remove_special_char() Failed(%d)", ret);
-       ret = CTS_SUCCESS;
-
-       cts_mutex_lock(CTS_MUTEX_SOCKET_FD);
-       ret = cts_request_normalize_str(dest, dest, dest_size);
-       cts_mutex_unlock(CTS_MUTEX_SOCKET_FD);
-
-       return ret;
-}
-
-void cts_set_extra_normalize_fn(int (*fn)(char dest[][CTS_SQL_MAX_LEN]))
-{
-       extra_normalize_fn = fn;
-}
-
-int cts_normalize_name(cts_name *src,
-               char dest[][CTS_SQL_MAX_LEN], bool is_display)
-{
-       int ret;
-       if (is_display) {
-               ret = cts_remove_special_char(src->display, dest[CTS_NN_FIRST],
-                               sizeof(dest[CTS_NN_FIRST]));
-               warn_if(ret < CTS_SUCCESS, "cts_remove_special_char() Failed(%d)", ret);
-               snprintf(dest[CTS_NN_SORTKEY], sizeof(dest[CTS_NN_SORTKEY]), "%s", dest[CTS_NN_FIRST]);
-               ret = CTS_SUCCESS;
-       }
-       else {
-               ret = cts_remove_special_char(src->first, dest[CTS_NN_FIRST],
-                               sizeof(dest[CTS_NN_FIRST]));
-               warn_if(ret < CTS_SUCCESS, "cts_remove_special_char() Failed(%d)", ret);
-               ret = CTS_SUCCESS;
-
-               ret = cts_remove_special_char(src->last, dest[CTS_NN_LAST],
-                               sizeof(dest[CTS_NN_LAST]));
-               warn_if(ret < CTS_SUCCESS, "cts_remove_special_char() Failed(%d)", ret);
-               ret = CTS_SUCCESS;
-
-               if (!*dest[CTS_NN_LAST])
-                       snprintf(dest[CTS_NN_SORTKEY], sizeof(dest[CTS_NN_SORTKEY]), "%s", dest[CTS_NN_FIRST]);
-               else if (!*dest[CTS_NN_FIRST])
-                       snprintf(dest[CTS_NN_SORTKEY], sizeof(dest[CTS_NN_SORTKEY]), "%s", dest[CTS_NN_LAST]);
-               else if (CTS_ORDER_NAME_FIRSTLAST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
-                       snprintf(dest[CTS_NN_SORTKEY], sizeof(dest[CTS_NN_SORTKEY]), "%s %s", dest[CTS_NN_FIRST], dest[CTS_NN_LAST]);
-               else
-                       snprintf(dest[CTS_NN_SORTKEY], sizeof(dest[CTS_NN_SORTKEY]), "%s, %s", dest[CTS_NN_LAST], dest[CTS_NN_FIRST]);
-       }
-
-       if (extra_normalize_fn)
-               ret = extra_normalize_fn(dest);
-       else {
-               cts_mutex_lock(CTS_MUTEX_SOCKET_FD);
-               ret = cts_request_normalize_name(dest);
-               cts_mutex_unlock(CTS_MUTEX_SOCKET_FD);
-       }
-
-       return ret;
-}
-
-/**
- * This function make searchable string.
- * The string can use at contacts_svc_normalized_strstr().
- *
- * @param[in] src the string to convert
- * @param[out] dest The pointer to get normalized string.
- * @param[out] dest_len the size of dest.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @par example
- * @code
-       char normalized_str[512];
-       const char *name = "Test"
-
-       ret = contacts_svc_normalize_str(name, normalized_str, sizeof(normalized_str));
-
-       if(CTS_SUCCESS != ret)
-               printf("Error : contacts_svc_normalize_str() Failed(%d)", ret);
-       else
-               printf("original string is %s, normalized string is %s", name, normalized_str);
- * @endcode
- */
-API int contacts_svc_normalize_str(const char *src, char *dest, const int dest_len)
-{
-       int ret;
-       retv_if(NULL == dest, CTS_ERR_ARG_NULL);
-       retvm_if(dest_len <= 0, CTS_ERR_ARG_INVALID, "dest_len(%d) is Invalid", dest_len);
-
-       ret = cts_normalize_str(src, dest, dest_len);
-       retvm_if(ret < CTS_SUCCESS, ret, "cts_normalize_str() Failed(%d)", ret);
-
-       return CTS_SUCCESS;
-}
-
-static inline bool is_choseong(const char *src)
-{
-       unsigned short tmp;
-
-       tmp = (src[1] << 8) | src[2];
-       if (((char)0xE1 == src[0] && CTS_COMPARE_BETWEEN(0x8480, tmp, 0x859F)) /* korean -Hangul Jamo*/
-                       || ((char)0xEA == src[0] && CTS_COMPARE_BETWEEN(0xA5A0, tmp, 0xA5BC))) /* korean -Hangul Jamo extended A*/
-       {
-               return true;
-       }
-       return false;
-}
-
-static inline bool is_jungseong(const char *src)
-{
-       unsigned short tmp;
-
-       tmp = (src[1] << 8) | src[2];
-       if (((char)0xE1 == src[0] && CTS_COMPARE_BETWEEN(0x85A0, tmp, 0x86A7))/* korean -Hangul Jamo*/
-                       || ((char)0xED == src[0] && CTS_COMPARE_BETWEEN(0x9EB0, tmp, 0x9F86)))/* korean -Hangul Jamo extended B */
-       {
-               return true;
-       }
-       return false;
-}
-
-static inline bool is_diacritical(const char *src)
-{
-       unsigned short tmp;
-
-       if (!src || !*src || !*(src+1))
-               return false;
-
-       tmp = (src[0] << 8) | src[1];
-       if (CTS_COMPARE_BETWEEN(0xCC80, tmp, 0xCCBF)
-                       || CTS_COMPARE_BETWEEN(0xCD80, tmp, 0xCDAF))
-       {
-               return true;
-       }
-       return false;
-}
-
-static inline bool compare_unicode(const char *str1, const char *str2, int str2_len)
-{
-       int k;
-       for (k=0; k<str2_len;k++)
-               if (!str1[k] || !str2[k] || str1[k] != str2[k])
-                       return false;
-       return true;
-}
-
-/**
- * This function compares compares two strings which must have been normalized already.
- * If search_str is included in str, this function return #CTS_SUCCESS. \n
- * The behavior of this function cannot fix because of localization.
- * So, The behavior can be different from each other.
- *
- * @param[in] haystack Base string.
- * @param[in] needle searching string
- * @param[out] len substring length
- * @return a position of the beginning of the substring, Negative value(#cts_error) on error or difference.
- * @par example
- * @code
-       ret = contacts_svc_compare_normalized_str(str1, str2, &len);
-       if(CTS_SUCCESS == ret) {
-               snprintf(first, ret+1, "%s", item_data->display);
-               snprintf(middle, len+1, "%s", item_data->display + ret);
-               printf("%s -> %s, %s, %s", item_data->display, first, middle, item_data->display + ret + len);
-       } else
-               printf("str1 doesn't has str2");
- * @endcode
- */
-API int contacts_svc_normalized_strstr(const char *haystack,
-               const char *needle, int *len)
-{
-       int i, j, wind, h_len, n_len;
-       int first_needle_len;
-       int equal_index;
-       int equal_length;
-       int equal_wind = 0;
-       bool counted = false;
-       retvm_if(NULL == haystack, -1, "The parameter(haystack) is NULL");
-       retvm_if(NULL == needle, -1, "The parameter(needle) is NULL");
-       CTS_DBG("haystack = %s, needle = %s", haystack, needle);
-
-       h_len = 1;
-       n_len = 1;
-       equal_index = 0;
-       first_needle_len = check_utf8(needle[0]);
-       for (i=0, j=0;i<strlen(haystack);i = wind?wind:(i+h_len)) {
-               if (equal_wind) {
-                       equal_index = equal_wind;
-                       counted = false;
-               }
-               wind = 0;
-               equal_length = 0;
-               equal_wind = 0;
-               for (j=0;j<strlen(needle);) {
-                       bool equal;
-                       h_len = check_utf8(haystack[i]);
-
-                       if (h_len == 1 && haystack[i] == 0x1) {         //skip seperator
-                               counted = false;
-                               i+=h_len;
-                               continue;
-                       }
-
-                       n_len = check_utf8(needle[j]);
-                       if (n_len == 1 && needle[j] == 0x1) {           //skip seperator
-                               j++;
-                               continue;
-                       }
-
-                       if (wind == 0 && j && 0 < i) {
-                               if (h_len == first_needle_len && compare_unicode(&haystack[i], needle, first_needle_len)
-                                               && !is_diacritical(&haystack[i])) {
-                                       unsigned short tmp;
-
-                                       tmp = (haystack[i+1] << 8) | haystack[i+2];
-                                       if (!counted) {
-                                               wind = i;
-                                               equal_wind = equal_index + equal_length;
-                                       }
-                               }
-                       }
-
-                       if ((2 == h_len && is_diacritical(&haystack[i]))
-                                       && (2 != n_len || !is_diacritical(&needle[j]))) {
-                               if (j == 0) {
-                                       if (counted)
-                                               equal_index++;
-                                       else {
-                                               equal_index += h_len;
-                                               counted = true;
-                                       }
-                               }
-                               else if (!counted) {
-                                       equal_length += h_len;
-                                       counted = true;
-                               }
-                               else if (counted)
-                                       equal_length++;
-                               i+=h_len;
-                               continue;
-                       }
-
-                       if (h_len != n_len) {
-                               if (!counted) {
-                                       equal_index += (equal_length + h_len);
-                                       counted = true;
-                               }
-                               break;
-                       }
-
-                       if (3 == n_len && is_choseong(&needle[j]) && !(is_choseong(&haystack[i]))) {
-                               if (j < (n_len+1) || !is_choseong(&needle[j-n_len-1])) {                // skip 강나 search by 가나
-                                       if (!counted) {
-                                               equal_index += (equal_length + h_len);
-                                               counted = true;
-                                       }
-                                       break;
-                               }
-                               else {
-                                       if (j == 0) {
-                                               if (!counted) {
-                                                       equal_index += h_len;
-                                                       counted = true;
-                                               }
-                                       }
-                                       else if (!counted) {
-                                               equal_length += h_len;
-                                               counted = true;
-                                       }
-                                       i+=h_len;
-                                       continue;
-                               }
-                       }
-
-                       equal = compare_unicode(&haystack[i], &needle[j], n_len);
-
-                       if (equal) {
-                               if (!counted) {
-                                       equal_length += h_len;
-                                       counted = true;
-                               }
-                               else if (2 == n_len && is_diacritical(&needle[j]))
-                                       equal_length ++;
-                               j += n_len;
-                               i+=h_len;
-                               continue;
-                       }
-                       else {
-                               if (!counted) {
-                                       equal_index += (equal_length + h_len);
-                                       counted = true;
-                               }
-                               else {
-                                       if (2 == n_len && is_diacritical(&needle[j]))
-                                               equal_index += (equal_length + 1);
-                                       else
-                                               equal_index += equal_length;
-                               }
-                               break;
-                       }
-               }
-
-               if ('\0' == needle[j]) {
-                       if ('\0' != haystack[i]) {
-                               h_len = check_utf8(haystack[i]);
-                               if(h_len == 2 && is_diacritical(&haystack[i]))
-                                       equal_length++;
-                       }
-                       *len = equal_length;
-                       return equal_index;
-               }
-       }
-
-       CTS_DBG("NOT match");
-       return -1;
-}
-
-static inline const char* cts_clean_country_code(const char *src)
-{
-       int ret = 1;
-       switch (src[ret++]-'0')
-       {
-       case 1:
-       case 7:
-               break;
-       case 2:
-               switch (src[ret++]-'0')
-               {
-               case 0:
-               case 7:
-                       break;
-               case 1:
-               case 2:
-               case 3:
-               case 4:
-               case 5:
-               case 6:
-               case 8:
-               case 9:
-                       ret += 1;
-                       break;
-               default:
-                       ERR("The parameter(src:%s) has invalid character set", src);
-               }
-               break;
-       case 3:
-               switch (src[ret++]-'0')
-               {
-               case 0:
-               case 1:
-               case 2:
-               case 3:
-               case 4:
-               case 6:
-               case 9:
-                       break;
-               case 5:
-               case 7:
-               case 8:
-                       ret += 1;
-                       break;
-               default:
-                       ERR("The parameter(src:%s) has invalid character set", src);
-               }
-               break;
-       case 4:
-               switch (src[ret++]-'0')
-               {
-               case 0:
-               case 1:
-               case 3:
-               case 4:
-               case 5:
-               case 6:
-               case 7:
-               case 8:
-               case 9:
-                       break;
-               case 2:
-                       ret += 1;
-                       break;
-               default:
-                       ERR("The parameter(src:%s) has invalid character set", src);
-               }
-               break;
-       case 5:
-               switch (src[ret++]-'0')
-               {
-               case 1:
-               case 2:
-               case 3:
-               case 4:
-               case 5:
-               case 6:
-               case 7:
-               case 8:
-                       break;
-               case 0:
-               case 9:
-                       ret += 1;
-                       break;
-               default:
-                       ERR("The parameter(src:%s) has invalid character set", src);
-               }
-               break;
-       case 6:
-               switch (src[ret++]-'0')
-               {
-               case 0:
-               case 1:
-               case 2:
-               case 3:
-               case 4:
-               case 5:
-               case 6:
-                       break;
-               case 7:
-               case 8:
-               case 9:
-                       ret += 1;
-                       break;
-               default:
-                       ERR("The parameter(src:%s) has invalid character set", src);
-               }
-               break;
-       case 8:
-               switch (src[ret++]-'0')
-               {
-               case 1:
-               case 2:
-               case 4:
-               case 6:
-                       break;
-               case 0:
-               case 3:
-               case 5:
-               case 7:
-               case 8:
-               case 9:
-                       ret += 1;
-                       break;
-               default:
-                       ERR("The parameter(src:%s) has invalid character set", src);
-               }
-               break;
-       case 9:
-               switch (src[ret++]-'0')
-               {
-               case 0:
-               case 1:
-               case 2:
-               case 3:
-               case 4:
-               case 5:
-               case 8:
-                       break;
-               case 6:
-               case 7:
-               case 9:
-                       ret += 1;
-                       break;
-               default:
-                       ERR("The parameter(src:%s) has invalid character set", src);
-               }
-               break;
-       case 0:
-       default:
-               ERR("The parameter(src:%s) has invalid character set", src);
-               return src;
-       }
-
-       return &src[ret];
-}
-
-const char* cts_normalize_number(const char *src)
-{
-       const char *normalized_number;
-
-       if ('+' == src[0])
-               normalized_number = cts_clean_country_code(src);
-       else if ('0' == src[0])
-               normalized_number = src+1;
-       else
-               normalized_number = src;
-
-       CTS_DBG("src = %s, normalized = %s", src, normalized_number);
-
-       return normalized_number;
-}
diff --git a/src/cts-normalize.h b/src/cts-normalize.h
deleted file mode 100755 (executable)
index d5036bd..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Contacts Service
- *
- * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact: Youngjae Shin <yj99.shin@samsung.com>
- *          Donghee Ye <donghee.ye@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_NORMALIZE_H__
-#define __CTS_NORMALIZE_H__
-
-#include "cts-sqlite.h"
-
-#define CTS_COMPARE_BETWEEN(left_range, value, right_range) (((left_range) <= (value)) && ((value) <= (right_range)))
-#define CTS_VCONF_DEFAULT_LANGUAGE "file/private/contacts-service/default_lang"
-
-/**
- * Language Type
- */
-enum LANGTYPE{
-       CTS_LANG_NUMBER = 0,
-       CTS_LANG_DEFAULT = 1,
-       CTS_LANG_SYMBOL = 2,
-       CTS_LANG_ENGLISH = 3,
-       CTS_LANG_KOREAN = 4, /* always last-first */
-       CTS_LANG_CHINESE = 5,
-       CTS_LANG_JAPANESE = 6,
-       CTS_LANG_FRENCH = 7,
-       CTS_LANG_GERMAN = 8,
-       CTS_LANG_ITALIAN = 9,
-       CTS_LANG_RUSSIAN = 10,
-       CTS_LANG_DUTCH = 11,
-       CTS_LANG_PORTUGUESE = 12,
-       CTS_LANG_TURKISH = 13,
-       CTS_LANG_GREEK = 14,
-       CTS_LANG_SPANISH = 15,
-       CTS_LANG_OTHERS = 16,
-};
-
-enum{
-       CTS_NN_FIRST,
-       CTS_NN_LAST,
-       CTS_NN_SORTKEY,
-       CTS_NN_MAX,
-};
-
-int cts_normalize_str(const char *src, char *dest, int dest_size);
-int cts_normalize_name(cts_name *src, char dest[][CTS_SQL_MAX_LEN], bool is_display);
-void cts_set_extra_normalize_fn(int (*fn)(char dest[][CTS_SQL_MAX_LEN]));
-const char* cts_normalize_number(const char *src);
-int cts_clean_number(const char *src, char *dest, int dest_size);
-
-#endif //__CTS_NORMALIZE_H__
diff --git a/src/cts-person.c b/src/cts-person.c
deleted file mode 100755 (executable)
index 09db7f5..0000000
+++ /dev/null
@@ -1,654 +0,0 @@
-/*
- * 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
deleted file mode 100755 (executable)
index e2e0a01..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * 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
deleted file mode 100755 (executable)
index 42e0412..0000000
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * 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 <sys/types.h>
-#include <regex.h>
-
-#include "cts-internal.h"
-#include "cts-schema.h"
-#include "cts-sqlite.h"
-#include "cts-contact.h"
-#include "cts-utils.h"
-#include "cts-types.h"
-#include "cts-normalize.h"
-#include "cts-phonelog.h"
-
-#define CTS_NAME_LEN_MAX 128
-
-static int cts_phonelog_accumulation_handle(cts_plog *plog)
-{
-       int ret, cnt, duration, total_cnt, total_duration, deal_cnt=0;
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       snprintf(query, sizeof(query), "SELECT * FROM %s WHERE id <= 2",
-                       CTS_TABLE_PHONELOG_ACC);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       while (CTS_TRUE == cts_stmt_step(stmt))
-       {
-               ret = cts_stmt_get_int(stmt, 0);
-               if (1 == ret) {
-                       cnt = cts_stmt_get_int(stmt, 1);
-                       duration = cts_stmt_get_int(stmt, 3);
-                       deal_cnt++;
-               }else if (2 == ret) {
-                       total_cnt = cts_stmt_get_int(stmt, 1);
-                       total_duration = cts_stmt_get_int(stmt, 3);
-                       deal_cnt++;
-               }
-       }
-       cts_stmt_finalize(stmt);
-
-       if (deal_cnt != 2) {
-               ERR("Getting plog accumulation data is Failed");
-               return CTS_ERR_DB_FAILED;
-       }
-
-       snprintf(query, sizeof(query), "INSERT OR REPLACE INTO %s VALUES(?, ?, NULL, ?)",
-                       CTS_TABLE_PHONELOG_ACC);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       cts_stmt_bind_int(stmt, 1, 1);
-       cts_stmt_bind_int(stmt, 2, cnt+1);
-       cts_stmt_bind_int(stmt, 3, duration + plog->extra_data1);
-
-       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_stmt_bind_int(stmt, 1, 2);
-       cts_stmt_bind_int(stmt, 2, total_cnt+1);
-       cts_stmt_bind_int(stmt, 3, total_duration + plog->extra_data1);
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_SUCCESS != ret)
-       {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               return ret;
-       }
-
-       cts_stmt_finalize(stmt);
-
-       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] = {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);
-
-       snprintf(query, sizeof(query), "INSERT INTO %s("
-                       "number, normal_num, related_id, log_type, log_time, data1, data2) "
-                       "VALUES(?, ?, ?, %d, %d, %d, ?)",
-                       CTS_TABLE_PHONELOGS, plog->log_type,
-                       plog->log_time, plog->extra_data1);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       if (plog->number) {
-               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)
-               cts_stmt_bind_int(stmt, 3, plog->related_id);
-
-       if (plog->extra_data2)
-               cts_stmt_bind_text(stmt, 4, plog->extra_data2);
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_SUCCESS != ret)
-       {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               return ret;
-       }
-       cts_stmt_finalize(stmt);
-
-       if (CTS_PLOG_TYPE_VOICE_OUTGOING == plog->log_type
-                       || CTS_PLOG_TYPE_VIDEO_OUTGOING == plog->log_type)
-       {
-               ret = cts_phonelog_accumulation_handle(plog);
-               retvm_if(CTS_SUCCESS != ret, ret, "cts_phonelog_accumulation_handle() Failed");
-       }
-
-       if (CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN == plog->log_type ||
-                       CTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN == plog->log_type)
-               cts_set_missed_call_noti();
-
-       cts_set_plog_noti();
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_insert_phonelog(CTSvalue* phone_log)
-{
-       int ret;
-       cts_plog *plog = (cts_plog *)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);
-       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);
-       }
-
-       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, ...)
-{
-       int id, ret;
-       char *number;
-       char query[CTS_SQL_MAX_LEN];
-       va_list args;
-
-       switch (op_code)
-       {
-       case CTS_PLOG_DEL_BY_ID:
-               va_start(args, op_code);
-               id = va_arg(args, int);
-               va_end(args);
-               snprintf(query, sizeof(query), "DELETE FROM %s WHERE id = %d",
-                               CTS_TABLE_PHONELOGS, id);
-               break;
-       case CTS_PLOG_DEL_BY_NUMBER:
-               va_start(args, op_code);
-               number = va_arg(args, char *);
-               va_end(args);
-               retv_if(NULL == number, CTS_ERR_ARG_NULL);
-               snprintf(query, sizeof(query), "DELETE FROM %s WHERE number = '%s'",
-                               CTS_TABLE_PHONELOGS, number);
-               break;
-       case CTS_PLOG_DEL_BY_MSGID:
-               va_start(args, op_code);
-               id = va_arg(args, int);
-               va_end(args);
-               snprintf(query, sizeof(query), "DELETE FROM %s "
-                               "WHERE data1 = %d AND %d <= log_type AND log_type <= %d",
-                               CTS_TABLE_PHONELOGS,
-                               id, CTS_PLOG_TYPE_MMS_INCOMMING, CTS_PLOG_TYPE_MMS_BLOCKED);
-               break;
-       case CTS_PLOG_DEL_NO_NUMBER:
-               snprintf(query, sizeof(query), "DELETE FROM %s WHERE number ISNULL",
-                               CTS_TABLE_PHONELOGS);
-               break;
-       default:
-               ERR("Invalid op_code. Your op_code(%d) is not supported.", op_code);
-               return CTS_ERR_ARG_INVALID;
-       }
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       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_plog_noti();
-       if (CTS_PLOG_DEL_BY_MSGID != op_code)
-               cts_set_missed_call_noti();
-
-       ret = contacts_svc_end_trans(true);
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-API int contacts_svc_get_phonelog(int plog_id, CTSvalue **phonelog)
-{
-       int ret;
-       cts_stmt stmt;
-       cts_plog *plog;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       snprintf(query, sizeof(query),
-                       "SELECT id, number, related_id, log_type, log_time, data1, data2 "
-                       "FROM %s WHERE id = %d",
-                       CTS_TABLE_PHONELOGS, plog_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;
-       }
-
-       plog = (cts_plog *)contacts_svc_value_new(CTS_VALUE_PHONELOG);
-       if (plog) {
-               ret = CTS_SUCCESS;
-               plog->v_type = CTS_VALUE_RDONLY_PLOG;
-               plog->id = cts_stmt_get_int(stmt, 0);
-               plog->number = SAFE_STRDUP(cts_stmt_get_text(stmt, 1));
-               plog->related_id = cts_stmt_get_int(stmt, 2);
-               plog->log_type = cts_stmt_get_int(stmt, 3);
-               plog->log_time = cts_stmt_get_int(stmt, 4);
-               plog->extra_data1 = cts_stmt_get_int(stmt, 5);
-               plog->extra_data2 = SAFE_STRDUP(cts_stmt_get_text(stmt, 6));
-
-               *phonelog = (CTSvalue*)plog;
-
-               cts_stmt_finalize(stmt);
-               return CTS_SUCCESS;
-       }
-       else {
-               ERR("contacts_svc_value_new() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               return CTS_ERR_OUT_OF_MEMORY;
-       }
-}
-
-
-API int contacts_svc_phonelog_set_seen(int index, int type)
-{
-       int ret;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       retvm_if(CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN != type &&
-                       CTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN != type &&
-                       CTS_PLOG_TYPE_NONE != type,
-                       CTS_ERR_ARG_INVALID,
-                       "The type is invalid. It must be CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN"
-                       " or CTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN");
-
-       if (0 == index) {
-               if (CTS_PLOG_TYPE_NONE == type)
-                       snprintf(query, sizeof(query), "UPDATE %s SET log_type = log_type + 1 WHERE log_type = %d OR log_type = %d",
-                                       CTS_TABLE_PHONELOGS, CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN,
-                                       CTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN);
-               else
-                       snprintf(query, sizeof(query), "UPDATE %s SET log_type = %d WHERE log_type = %d",
-                                       CTS_TABLE_PHONELOGS, type+1, type);
-       }
-       else {
-               snprintf(query, sizeof(query), "UPDATE %s SET log_type = %d WHERE id = %d",
-                               CTS_TABLE_PHONELOGS, type+1, index);
-       }
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       ret = cts_query_exec(query);
-       if (CTS_SUCCESS != ret) {
-               ERR("cts_query_exec() Failed(%d)", ret);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-
-       if (cts_db_change()) {
-               cts_set_plog_noti();
-               cts_set_missed_call_noti();
-       }
-
-       ret = contacts_svc_end_trans(true);
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-/**
- * This is the signature of a callback function added with contacts_svc_phonelog_get_all_number(),
- * \n This function is invoked in the above functions.
- * \n If this function doesn't return #CTS_SUCCESS, foreach function is terminated.
- *
- * @param[in] number number.
- * @param[in] user_data The data which is set by contacts_svc_phonelog_get_all_number(),
- * @return #CTS_SUCCESS on success, other value on error
- */
-typedef int (*cts_plog_foreach_fn)(const char *number, void *user_data);
-
-/**
- * This function calls #cts_plog_foreach_fn for each number of all number list.
- * The all number list doesn't have duplicated numbers.
- *
- * @param[in] cb callback function pointer(#cts_plog_foreach_fn)
- * @param[in] user_data data which is passed to callback function
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-API int contacts_svc_phonelog_get_all_number(cts_plog_foreach_fn cb,
-               void *user_data)
-{
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       retv_if(NULL == cb, CTS_ERR_ARG_NULL);
-
-       snprintf(query, sizeof(query),
-                       "SELECT DISTINCT number FROM %s", CTS_TABLE_PHONELOGS);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       while (CTS_TRUE == cts_stmt_step(stmt)) {
-               if (cb(cts_stmt_get_text(stmt, 0), user_data))
-                       break;
-       }
-       cts_stmt_finalize(stmt);
-
-       return CTS_SUCCESS;
-}
-
-API char* contacts_svc_phonelog_get_last_number(cts_plog_get_last_op op)
-{
-       int ret;
-       cts_stmt stmt;
-       char *number;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       switch (op) {
-       case CTS_PLOG_LAST_ALL:
-               snprintf(query, sizeof(query),
-                               "SELECT id, number FROM %s "
-                               "WHERE id = (SELECT MAX(id) FROM %s WHERE log_type = %d OR log_type = %d)",
-                               CTS_TABLE_PHONELOGS, CTS_TABLE_PHONELOGS,
-                               CTS_PLOG_TYPE_VOICE_OUTGOING, CTS_PLOG_TYPE_VIDEO_OUTGOING);
-               break;
-       case CTS_PLOG_LAST_CALL_ONLY:
-               snprintf(query, sizeof(query),
-                               "SELECT id, number FROM %s "
-                               "WHERE id = (SELECT MAX(id) FROM %s WHERE log_type = %d)",
-                               CTS_TABLE_PHONELOGS, CTS_TABLE_PHONELOGS, CTS_PLOG_TYPE_VOICE_OUTGOING);
-               break;
-       case CTS_PLOG_LAST_VIDEO_CALL_ONLY:
-               snprintf(query, sizeof(query),
-                               "SELECT id, number FROM %s "
-                               "WHERE id = (SELECT MAX(id) FROM %s WHERE log_type = %d)",
-                               CTS_TABLE_PHONELOGS, CTS_TABLE_PHONELOGS, CTS_PLOG_TYPE_VIDEO_OUTGOING);
-               break;
-       default:
-               ERR("Invalid op(%d)", op);
-               return NULL;
-       }
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, NULL, "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 NULL;
-       }
-       number = SAFE_STRDUP(cts_stmt_get_text(stmt, 1));
-
-       cts_stmt_finalize(stmt);
-
-       return number;
-}
diff --git a/src/cts-phonelog.h b/src/cts-phonelog.h
deleted file mode 100755 (executable)
index 71bda48..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * 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_PHONELOG_H__
-#define __CTS_PHONELOG_H__
-
-//<!--
-/**
- * @defgroup   CONTACTS_SVC_PLOG Phone Logs Modification
- * @ingroup    CONTACTS_SVC
- * @addtogroup CONTACTS_SVC_PLOG
- * @{
- *
- * This interface provides methods to insert/update/delete the Phone Logs.
- *
- */
-
-/**
- * This function inserts a phone log to database.
- *
- * @param[in] phone_log A phone log information of CTSvalue() created by contacts_svc_value_new(CTS_VALUE_PHONELOG).
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @par example
- * @code
- void phonelog_insert_test(void)
- {
-    CTSvalue *plog;
-
-    plog = contacts_svc_value_new(CTS_VALUE_PHONELOG);
-    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_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_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);
-    contacts_svc_value_set_int(plog, CTS_PLOG_VAL_DURATION_INT, 65);
-    contacts_svc_insert_phonelog(plog);
-
-
-    contacts_svc_value_free(plog);
- }
- * @endcode
- */
-int contacts_svc_insert_phonelog(CTSvalue* phone_log);
-
-/**
- * Use for contacts_svc_delete_phonelog().
- */
-typedef enum{
-       CTS_PLOG_DEL_BY_ID, /**< .*/
-       CTS_PLOG_DEL_BY_NUMBER, /**< number or email address */
-       CTS_PLOG_DEL_NO_NUMBER, /**< .*/
-       CTS_PLOG_DEL_BY_MSGID, /**< .*/
-}cts_del_plog_op;
-/**
- * This function deletes a phone log with op_code(#CTS_PLOG_DEL_BY_ID, #CTS_PLOG_DEL_BY_NUMBER).
- * @par int contacts_svc_delete_phonelog(CTS_PLOG_DEL_BY_ID, int index)
- * @par int contacts_svc_delete_phonelog(CTS_PLOG_DEL_BY_NUMBER, char *number)
- * Delete all phone logs related with number.
- *
- * @param[in] op_code #cts_del_plog_op
- * @param[in] index (optional) Index of the phone log
- * @param[in] number (optional) Number to be deleted
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @par example
- * @code
- contacts_svc_delete_phonelog(CTS_PLOG_DEL_BY_ID, 3);
- contacts_svc_delete_phonelog(CTS_PLOG_DEL_BY_NUMBER, "0123456789");
- * @endcode
- */
-int contacts_svc_delete_phonelog(cts_del_plog_op op_code, ...);
-
-/**
- * This function modifies a phone log from unseen to seen.
- * \n Type should be #CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN or #CTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN
- *
- * @param[in] index Index of the phone log
- * @param[in] type The current type of phone log
- * @par example
- * @code
- contacts_svc_phonelog_set_seen(2, CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN);
- * @endcode
- */
-int contacts_svc_phonelog_set_seen(int index, int type);
-
-/**
- * Use for contacts_svc_phonelog_get_last_number().
- */
-typedef enum{
-       CTS_PLOG_LAST_ALL, /**< .*/
-       CTS_PLOG_LAST_CALL_ONLY, /**< .*/
-       CTS_PLOG_LAST_VIDEO_CALL_ONLY, /**< .*/
-}cts_plog_get_last_op;
-
-/**
- * This function gets the string of the most recent outgoing call number.
- * \n It specifys by op(#cts_plog_get_last_op).
- * \n It checks voice and video call(Not SMS/MMS).
- * \n It doesn't include the rejected and blocked numbers.
- * \n The obtained string should be free using by free().
- * @return string of the last number, or NULL if no value is obtained or on error
- */
-char* contacts_svc_phonelog_get_last_number(cts_plog_get_last_op op);
-
-/**
- * This function gets phonelog record which has the index from the database.
- * Obtained phonelog record should be freed by using contacts_svc_value_free().
- * @param[in] plog_id The index of phonelog to get
- * @param[out] phonelog Points of the phonelog record which is returned
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @par example
- * @code
- void get_phonelog(void)
- {
-    int ret;
-    CTSvalue *plog;
-
-    ret = contacts_svc_get_phonelog(1, &plog);
-    if(ret < 0)
-    {
-       printf("No found record\n");
-       return;
-    }
-
-    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));
-    printf("Duration : %d\n", contacts_svc_value_get_int(plog, CTS_PLOG_VAL_DURATION_INT));
-    printf("Related ID : %d\n", contacts_svc_value_get_int(plog, CTS_PLOG_VAL_RELATED_ID_INT));
-
-    contacts_svc_value_free(plog);
- }
- * @endcode
- */
-int contacts_svc_get_phonelog(int plog_id, CTSvalue **phonelog);
-
-/**
- * @}
- */
-
-//-->
-
-#endif //__CTS_PHONELOG_H__
-
diff --git a/src/cts-pthread.c b/src/cts-pthread.c
deleted file mode 100755 (executable)
index 4111afd..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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 <pthread.h>
-
-#include "cts-internal.h"
-#include "cts-pthread.h"
-
-typedef struct {
-       int (* lock) (pthread_mutex_t *mutex);
-       int (* unlock) (pthread_mutex_t *mutex);
-}cts_thread_fns;
-
-static cts_thread_fns cts_thread_funtions =
-{
-       pthread_mutex_lock,
-       pthread_mutex_unlock
-};
-
-static pthread_mutex_t conn_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t sockfd_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t trans_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-
-static inline pthread_mutex_t* cts_pthread_get_mutex(int type)
-{
-       pthread_mutex_t *ret_val;
-
-       switch (type) {
-       case CTS_MUTEX_CONNECTION:
-               ret_val = &conn_mutex;
-               break;
-       case CTS_MUTEX_SOCKET_FD:
-               ret_val = &sockfd_mutex;
-               break;
-       case CTS_MUTEX_TRANSACTION:
-               ret_val = &trans_mutex;
-               break;
-       default:
-               ERR("unknown type(%d)", type);
-               ret_val = NULL;
-       }
-       return ret_val;
-}
-
-void cts_mutex_lock(int type)
-{
-       int ret;
-       pthread_mutex_t *mutex;
-
-       mutex = cts_pthread_get_mutex(type);
-
-       if (cts_thread_funtions.lock) {
-               ret = cts_thread_funtions.lock(mutex);
-               warn_if(ret, "pthread_mutex_lock Failed(%d)", ret);
-       }
-}
-
-void cts_mutex_unlock(int type)
-{
-       int ret;
-       pthread_mutex_t *mutex;
-
-       mutex = cts_pthread_get_mutex(type);
-
-       if (cts_thread_funtions.unlock) {
-               ret = cts_thread_funtions.unlock(mutex);
-               warn_if(ret, "pthread_mutex_unlock Failed(%d)", ret);
-       }
-}
-
-void contacts_svc_thread_init(void)
-{
-       cts_thread_funtions.lock = pthread_mutex_lock;
-       cts_thread_funtions.unlock = pthread_mutex_unlock;
-}
diff --git a/src/cts-restriction.c b/src/cts-restriction.c
deleted file mode 100755 (executable)
index ab2b7ab..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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-schema.h b/src/cts-schema.h
deleted file mode 100755 (executable)
index c0028c3..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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_SCHEMA_H__
-#define __CTS_SCHEMA_H__
-
-#define CTS_DB_PATH "/opt/dbspace/.contacts-svc.db"
-#define CTS_DB_JOURNAL_PATH "/opt/dbspace/.contacts-svc.db-journal"
-
-// For Security
-#define CTS_SECURITY_FILE_GROUP 6005
-#define CTS_SECURITY_DEFAULT_PERMISSION 0660
-#define CTS_SECURITY_DIR_DEFAULT_PERMISSION 0770
-
-#define CTS_SCHEMA_TABLE_TOTAL 10
-
-// Tables
-#define CTS_TABLE_PERSONS "persons"
-#define CTS_TABLE_CONTACTS "contacts"
-#define CTS_TABLE_GROUPS "groups"
-#define CTS_TABLE_ADDRESSBOOKS "addressbooks"
-#define CTS_TABLE_DATA "data"     // This is the data table for contact all fields
-#define CTS_TABLE_FAVORITES "favorites"
-#define CTS_TABLE_PHONELOGS "phonelogs"
-#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"
-#define CTS_SCHEMA_DATA_NAME_REVERSE_LOOKUP "data9"
-#define CTS_SCHEMA_DATA_NAME_SORTING_KEY "data10"
-
-#define CTS_SCHEMA_SQLITE_SEQ "sqlite_sequence"
-
-
-#endif /* __CTS_SCHEMA_H__ */
-
diff --git a/src/cts-service.c b/src/cts-service.c
deleted file mode 100755 (executable)
index a1e5fd6..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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 <stdarg.h>
-#include <dlfcn.h>
-
-#include "cts-internal.h"
-#include "cts-schema.h"
-#include "cts-sqlite.h"
-#include "cts-utils.h"
-#include "cts-socket.h"
-#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;
-
-API int contacts_svc_connect(void)
-{
-       CTS_FN_CALL;
-       int ret;
-
-       cts_mutex_lock(CTS_MUTEX_CONNECTION);
-       if (0 < cts_conn_refcnt) {
-               CTS_DBG("The contacts-service is already connected. refcnt=%d", cts_conn_refcnt);
-               cts_conn_refcnt++;
-       }
-       else
-       {
-               ret = cts_socket_init();
-               if (CTS_SUCCESS != ret) {
-                       void *handle, *fn;
-                       handle = dlopen(NULL, RTLD_GLOBAL);
-                       fn = dlsym(handle, "cts_helper_normalize_name");
-                       if (NULL == fn) {
-                               ERR("cts_socket_init() Failed(%d)", ret);
-                               cts_mutex_unlock(CTS_MUTEX_CONNECTION);
-                               return ret;
-                       }
-                       cts_set_extra_normalize_fn(fn);
-               }
-
-               ret = cts_db_open();
-               if (ret != CTS_SUCCESS) {
-                       ERR("cts_db_open() Failed(%d)", ret);
-                       cts_socket_final();
-                       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;
-       }
-       cts_mutex_unlock(CTS_MUTEX_CONNECTION);
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_disconnect(void)
-{
-       CTS_FN_CALL;
-       retvm_if(0 == cts_conn_refcnt, CTS_ERR_ENV_INVALID,
-                       "Contacts service was not connected");
-       CTS_DBG("CTS DB refcnt = %d", cts_conn_refcnt);
-
-       cts_mutex_lock(CTS_MUTEX_CONNECTION);
-       if (1 == cts_conn_refcnt)
-       {
-               cts_socket_final();
-               cts_deregister_noti();
-               cts_db_close();
-               cts_restriction_final();
-               cts_conn_refcnt--;
-       }
-       else
-               cts_conn_refcnt--;
-       cts_mutex_unlock(CTS_MUTEX_CONNECTION);
-
-       return CTS_SUCCESS;
-}
-
-#if 0
-typedef enum {
-       CTS_DELETE_ALL_CONTACT_OF_ACCOUNT,
-       CTS_DELETE_ALL_GROUP_OF_ACCOUNT,
-       CTS_DELETE_ALL_PLOG
-};
-int contacts_svc_delete_all(int op_code, int index)
-{
-       int ret;
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       switch (op_code)
-       {
-       case CTS_DELETE_ALL_CONTACT_OF_ACCOUNT:
-               snprintf(query, sizeof(query),
-                               "DELETE FROM %s WHERE account_id=%d"
-                               CTS_TABLE_CONTACTS, CTS_SCHEMA_NUMBERS, CTS_PLOG_TYPE_MMS_INCOMMING);
-               break;
-       case CTS_DELETE_ALL_GROUP_OF_ACCOUNT:
-       default:
-               ERR("Invalid op_code. Your op_code(%d) is not supported.", op_code);
-               return CTS_ERR_ARG_INVALID;
-       }
-
-
-}
-#endif
diff --git a/src/cts-service.h b/src/cts-service.h
deleted file mode 100755 (executable)
index c2dc31d..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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_SERVICE_H__
-#define __CTS_SERVICE_H__
-
-//<!--
-/**
- * This function connect to contacts service.
- * \n Though the connection already exists, #CTS_SUCCESS is returned.
- * \n It has to disconnect as it connect.
- *
- * for example, if you connect 3 times you have to disconnect 3 times.
- * \n To disconnect early minimizes the runtime resource consumption.
- * On the other hand, a pair of connection and disconnection is expensive.
- * Don't call frequently.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @see contacts_svc_disconnect()
- */
-int contacts_svc_connect(void);
-
-/**
- * This function disconnect to contacts service.
- * If connection is called many times,
- * disconnection operation is valid at the last of the times.
- *
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @see contacts_svc_connect()
- */
-int contacts_svc_disconnect(void);
-//-->
-
-#endif //__CTS_SERVICE_H__
diff --git a/src/cts-socket.c b/src/cts-socket.c
deleted file mode 100755 (executable)
index a4cf002..0000000
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * 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 <errno.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include "cts-internal.h"
-#include "cts-normalize.h"
-#include "cts-socket.h"
-
-static int cts_csockfd = -1;
-
-static inline int cts_safe_write(int fd, const char *buf, int buf_size)
-{
-       int ret, writed=0;
-       while (buf_size) {
-               ret = write(fd, buf+writed, buf_size);
-               if (-1 == ret) {
-                       if (EINTR == errno)
-                               continue;
-                       else
-                               return ret;
-               }
-               writed += ret;
-               buf_size -= ret;
-       }
-       return writed;
-}
-
-static inline int cts_safe_read(int fd, char *buf, int buf_size)
-{
-       int ret, read_size=0;
-       while (buf_size) {
-               ret = read(fd, buf+read_size, buf_size);
-               if (-1 == ret) {
-                       if (EINTR == errno)
-                               continue;
-                       else
-                               return ret;
-               }
-               read_size += ret;
-               buf_size -= ret;
-       }
-       return read_size;
-}
-
-static int cts_socket_handle_return(int fd, cts_socket_msg *msg)
-{
-       CTS_FN_CALL;
-       int ret;
-
-       ret = cts_safe_read(fd, (char *)msg, sizeof(cts_socket_msg));
-       retvm_if(-1 == ret, CTS_ERR_SOCKET_FAILED, "cts_safe_read() Failed(errno = %d)", errno);
-
-       warn_if(CTS_REQUEST_RETURN_VALUE != msg->type,
-                       "Unknown Type(%d), ret=%d, attach_num= %d,"
-                       "attach1 = %d, attach2 = %d, attach3 = %d, attach4 = %d",
-                       msg->type, msg->val, msg->attach_num,
-                       msg->attach_sizes[0],msg->attach_sizes[1],msg->attach_sizes[2],
-                       msg->attach_sizes[3]);
-
-       retvm_if(CTS_REQUEST_MAX_ATTACH < msg->attach_num, CTS_ERR_SOCKET_FAILED,
-                       "Invalid msg(attach_num = %d)", msg->attach_num);
-
-       return CTS_SUCCESS;
-}
-
-static void cts_remove_invalid_msg(int fd, int size)
-{
-       int ret;
-       char dummy[CTS_SOCKET_MSG_SIZE];
-
-       while (size) {
-               if (sizeof(dummy) < size) {
-                       ret = read(fd, dummy, sizeof(dummy));
-                       if (-1 == ret) {
-                               if (EINTR == errno)
-                                       continue;
-                               else
-                                       return;
-                       }
-                       size -= ret;
-               }
-               else {
-                       ret = read(fd, dummy, size);
-                       if (-1 == ret) {
-                               if (EINTR == errno)
-                                       continue;
-                               else
-                                       return;
-                       }
-                       size -= ret;
-               }
-       }
-}
-
-int cts_request_sim_import(void)
-{
-       int i, ret;
-       cts_socket_msg msg={0};
-
-       retvm_if(-1 == cts_csockfd, CTS_ERR_ENV_INVALID, "socket is not connected");
-
-       msg.type = CTS_REQUEST_IMPORT_SIM;
-       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_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_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;
-       cts_socket_msg msg={0};
-
-       retvm_if(-1 == cts_csockfd, CTS_ERR_ENV_INVALID, "socket is not connected");
-
-       msg.type = CTS_REQUEST_NORMALIZE_STR;
-       msg.attach_num = CTS_NS_ATTACH_NUM;
-       msg.attach_sizes[0] = strlen(src);
-       if (0 == msg.attach_sizes[0]) {
-               ERR("The parameter(src) is empty string");
-               dest[0] = '\0';
-               return CTS_SUCCESS;
-       }
-
-       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);
-       CTS_DBG("Send message : %s(%d)", src, msg.attach_sizes[0]);
-
-       ret = cts_socket_handle_return(cts_csockfd, &msg);
-       retvm_if(CTS_SUCCESS != ret, ret, "cts_socket_handle_return() Failed(%d)", ret);
-
-       warn_if(CTS_NS_ATTACH_NUM != msg.attach_num,
-                       "Invalid attachments(attach_num = %d)", msg.attach_num);
-
-       if (dest_size <= msg.attach_sizes[0]) {
-               ret = cts_safe_read(cts_csockfd, dest, dest_size);
-               retvm_if(-1 == ret, CTS_ERR_SOCKET_FAILED, "cts_safe_read() Failed(errno = %d)", errno);
-
-               msg.attach_sizes[0] -= ret;
-               dest[dest_size-1] = '\0';
-               cts_remove_invalid_msg(cts_csockfd, msg.attach_sizes[0]);
-       }
-       else {
-               ret = cts_safe_read(cts_csockfd, dest, msg.attach_sizes[0]);
-               retvm_if(-1 == ret, CTS_ERR_SOCKET_FAILED, "cts_safe_read() Failed(errno = %d)", errno);
-
-               dest[msg.attach_sizes[0]] = '\0';
-       }
-
-       for (i=CTS_NS_ATTACH_NUM;i<msg.attach_num;i++)
-               cts_remove_invalid_msg(cts_csockfd, msg.attach_sizes[i]);
-
-       return msg.val;
-}
-
-int cts_request_normalize_name(char dest[][CTS_SQL_MAX_LEN])
-{
-       int i, ret;
-       cts_socket_msg msg={0};
-
-       retvm_if(-1 == cts_csockfd, CTS_ERR_ENV_INVALID, "socket is not connected");
-
-       msg.type = CTS_REQUEST_NORMALIZE_NAME;
-       msg.attach_num = CTS_NN_ATTACH_NUM;
-       msg.attach_sizes[CTS_NN_FIRST] = strlen(dest[CTS_NN_FIRST]);
-       msg.attach_sizes[CTS_NN_LAST] = strlen(dest[CTS_NN_LAST]);
-       msg.attach_sizes[CTS_NN_SORTKEY] = strlen(dest[CTS_NN_SORTKEY]);
-
-       if (!msg.attach_sizes[CTS_NN_FIRST] && !msg.attach_sizes[CTS_NN_LAST]){
-               return CTS_SUCCESS;
-       }
-       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, dest[CTS_NN_FIRST], msg.attach_sizes[CTS_NN_FIRST]);
-       retvm_if(-1 == ret, CTS_ERR_SOCKET_FAILED, "cts_safe_write() Failed(errno = %d)", errno);
-       ret = cts_safe_write(cts_csockfd, dest[CTS_NN_LAST], msg.attach_sizes[CTS_NN_LAST]);
-       retvm_if(-1 == ret, CTS_ERR_SOCKET_FAILED, "cts_safe_write() Failed(errno = %d)", errno);
-       ret = cts_safe_write(cts_csockfd, dest[CTS_NN_SORTKEY], msg.attach_sizes[CTS_NN_SORTKEY]);
-       retvm_if(-1 == ret, CTS_ERR_SOCKET_FAILED, "cts_safe_write() Failed(errno = %d)", errno);
-       CTS_DBG("request_first = %s(%d), request_last = %s(%d), request_sortkey = %s(%d)",
-                       dest[CTS_NN_FIRST], msg.attach_sizes[CTS_NN_FIRST],
-                       dest[CTS_NN_LAST], msg.attach_sizes[CTS_NN_LAST],
-                       dest[CTS_NN_SORTKEY], msg.attach_sizes[CTS_NN_SORTKEY]);
-
-       ret = cts_socket_handle_return(cts_csockfd, &msg);
-       retvm_if(CTS_SUCCESS != ret, ret, "cts_socket_handle_return() Failed(%d)", ret);
-
-       if (CTS_NN_MAX < msg.attach_num) {
-               ERR("Invalid attachments(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 CTS_ERR_MSG_INVALID;
-       }
-
-       for (i=0;i<msg.attach_num;i++)
-       {
-               CTS_DBG("msg_size = %d", msg.attach_sizes[i]);
-               if (CTS_SQL_MAX_LEN <= msg.attach_sizes[i])
-               {
-                       ret = cts_safe_read(cts_csockfd, dest[i], sizeof(dest[i]));
-                       retvm_if(-1 == ret, CTS_ERR_SOCKET_FAILED, "cts_safe_read() Failed(errno = %d)", errno);
-
-                       msg.attach_sizes[i] -= ret;
-                       dest[i][CTS_SQL_MAX_LEN-1] = '\0';
-                       cts_remove_invalid_msg(cts_csockfd, msg.attach_sizes[i]);
-               }
-               else {
-                       ret = cts_safe_read(cts_csockfd, dest[i], msg.attach_sizes[i]);
-                       retvm_if(-1 == ret, CTS_ERR_SOCKET_FAILED, "cts_safe_read() Failed(errno = %d)", errno);
-
-                       dest[i][msg.attach_sizes[i]] = '\0';
-               }
-       }
-
-       return msg.val;
-}
-
-int cts_socket_init(void)
-{
-       int ret;
-       struct sockaddr_un caddr;
-
-       bzero(&caddr, sizeof(caddr));
-       caddr.sun_family = AF_UNIX;
-       snprintf(caddr.sun_path, sizeof(caddr.sun_path), "%s", CTS_SOCKET_PATH);
-
-       cts_csockfd = socket(PF_UNIX, SOCK_STREAM, 0);
-       retvm_if(-1 == cts_csockfd, CTS_ERR_SOCKET_FAILED,
-                       "socket() Failed(errno = %d)", errno);
-
-       ret = connect(cts_csockfd, (struct sockaddr *)&caddr, sizeof(caddr));
-       if (-1 == ret) {
-               ERR("connect() Failed(errno = %d)", errno);
-               close(cts_csockfd);
-               cts_csockfd = -1;
-               return CTS_ERR_SOCKET_FAILED;
-       }
-
-       return CTS_SUCCESS;
-}
-
-void cts_socket_final(void)
-{
-       close(cts_csockfd);
-       cts_csockfd = -1;
-}
diff --git a/src/cts-socket.h b/src/cts-socket.h
deleted file mode 100755 (executable)
index 2563d07..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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_SOCKET_H__
-#define __CTS_SOCKET_H__
-
-#include "cts-struct.h"
-#include "cts-sqlite.h"
-
-#define CTS_SOCKET_PATH "/opt/data/contacts-svc/.contacts-svc.sock"
-#define CTS_SOCKET_MSG_SIZE 128
-
-//Message TYPE
-enum{
-       CTS_REQUEST_RETURN_VALUE,
-       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"
-//#define CTS_REQUEST_RETURN_VALUE "cts_request_return_value"
-#define CTS_REQUEST_MAX_ATTACH 5
-
-#define CTS_NS_ATTACH_NUM 1 //NS = Normalize String
-#define CTS_NN_ATTACH_NUM 3 //NN = Normalize Name
-
-typedef struct{
-       int type;
-       int val;
-       int attach_num;
-       int attach_sizes[CTS_REQUEST_MAX_ATTACH];
-}cts_socket_msg;
-
-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
deleted file mode 100755 (executable)
index bc47d5a..0000000
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * 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 <string.h>
-#include <db-util.h>
-
-#include "cts-internal.h"
-#include "cts-schema.h"
-#include "cts-im.h"
-#include "cts-sqlite.h"
-
-static sqlite3 *cts_db;
-
-int cts_db_open(void)
-{
-       CTS_FN_CALL;
-       int ret;
-
-       if (!cts_db) {
-               ret = db_util_open(CTS_DB_PATH, &cts_db, 0);
-               retvm_if(SQLITE_OK != ret, CTS_ERR_DB_NOT_OPENED,
-                               "db_util_open() Failed(%d)", ret);
-       }
-       return CTS_SUCCESS;
-}
-
-int cts_db_close(void)
-{
-       int ret = 0;
-
-       if (cts_db) {
-               ret = db_util_close(cts_db);
-               warn_if(SQLITE_OK != ret, "db_util_close() Failed(%d)", ret);
-               cts_db = NULL;
-               CTS_DBG("The database disconnected really.");
-       }
-
-       return CTS_SUCCESS;
-}
-
-int cts_db_change(void)
-{
-       return sqlite3_changes(cts_db);
-}
-
-int cts_db_get_last_insert_id(void)
-{
-       return sqlite3_last_insert_rowid(cts_db);
-}
-
-int cts_db_get_next_id(const char *table)
-{
-       int ret;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       snprintf(query, sizeof(query), "SELECT seq FROM %s WHERE name = '%s'",
-                       CTS_SCHEMA_SQLITE_SEQ, table);
-
-       ret = cts_query_get_first_int_result(query);
-       if (ret < CTS_SUCCESS) {
-               if (CTS_ERR_DB_RECORD_NOT_FOUND == ret)
-                       return 1;
-               else
-                       return ret;
-       } else {
-               return (1 + ret);
-       }
-}
-
-int cts_query_get_first_int_result(const char *query)
-{
-       int ret;
-       cts_stmt stmt = NULL;
-       retvm_if(NULL == cts_db, CTS_ERR_DB_NOT_OPENED, "Database is not opended");
-
-       ret = sqlite3_prepare_v2(cts_db, query, strlen(query), &stmt, NULL);
-       retvm_if(SQLITE_OK != ret, CTS_ERR_DB_FAILED,
-                       "sqlite3_prepare_v2(%s) Failed(%s)", query, sqlite3_errmsg(cts_db));
-
-       ret = sqlite3_step(stmt);
-       if (SQLITE_ROW != ret) {
-               ERR("sqlite3_step() Failed(%d, %s)", ret, sqlite3_errmsg(cts_db));
-               sqlite3_finalize(stmt);
-               if (SQLITE_DONE == ret) return CTS_ERR_DB_RECORD_NOT_FOUND;
-               return CTS_ERR_DB_FAILED;
-       }
-
-       ret = sqlite3_column_int(stmt, 0);
-       sqlite3_finalize(stmt);
-
-       return ret;
-}
-
-int cts_query_exec(const char *query)
-{
-       int ret;
-       char *err_msg = NULL;
-
-       retvm_if(NULL == cts_db, CTS_ERR_DB_NOT_OPENED, "Database is not opended");
-       CTS_DBG("query : %s", query);
-
-       ret = sqlite3_exec(cts_db, query, NULL, NULL, &err_msg);
-       if (SQLITE_OK != ret) {
-               ERR("sqlite3_exec(%s) Failed(%d, %s)", query, ret, err_msg);
-               sqlite3_free(err_msg);
-               switch (ret) {
-               case SQLITE_BUSY:
-               case SQLITE_LOCKED:
-                       return CTS_ERR_DB_LOCK;
-               case SQLITE_IOERR:
-                       return CTS_ERR_IO_ERR;
-               case SQLITE_FULL:
-                       return CTS_ERR_NO_SPACE;
-               default:
-                       return CTS_ERR_DB_FAILED;
-               }
-       }
-
-       return CTS_SUCCESS;
-}
-
-cts_stmt cts_query_prepare(char *query)
-{
-       int ret = -1;
-       cts_stmt stmt = NULL;
-
-       retvm_if(NULL == cts_db, NULL, "Database is not opended");
-       CTS_DBG("prepare query : %s", query);
-
-       ret = sqlite3_prepare_v2(cts_db, query, strlen(query), &stmt, NULL);
-       retvm_if(SQLITE_OK != ret, NULL,
-                       "sqlite3_prepare_v2(%s) Failed(%s)", query, sqlite3_errmsg(cts_db));
-
-       return stmt;
-}
-
-int cts_stmt_get_first_int_result(cts_stmt stmt)
-{
-       int ret;
-       retvm_if(NULL == cts_db, CTS_ERR_DB_NOT_OPENED, "Database is not opended");
-
-       ret = sqlite3_step(stmt);
-       if (SQLITE_ROW != ret) {
-               ERR("sqlite3_step() Failed(%d, %s)", ret, sqlite3_errmsg(cts_db));
-               sqlite3_finalize(stmt);
-               if (SQLITE_DONE == ret) return CTS_ERR_DB_RECORD_NOT_FOUND;
-               return CTS_ERR_DB_FAILED;
-       }
-
-       ret = sqlite3_column_int(stmt, 0);
-       sqlite3_finalize(stmt);
-
-       return ret;
-}
-
-int cts_stmt_step(cts_stmt stmt)
-{
-       int ret;
-       ret = sqlite3_step(stmt);
-       switch (ret) {
-       case SQLITE_BUSY:
-       case SQLITE_LOCKED:
-               ret = CTS_ERR_DB_LOCK;
-               break;
-       case SQLITE_IOERR:
-               ret = CTS_ERR_IO_ERR;
-               break;
-       case SQLITE_FULL:
-               ret = CTS_ERR_NO_SPACE;
-               break;
-       case SQLITE_CONSTRAINT:
-               ret = CTS_ERR_ALREADY_EXIST;
-               break;
-       case SQLITE_ROW:
-               ret = CTS_TRUE;
-               break;
-       case SQLITE_DONE:
-               ret = CTS_SUCCESS;
-               break;
-       default:
-               ERR("sqlite3_step() Failed(%d)", ret);
-               ret = CTS_ERR_DB_FAILED;
-               break;
-       }
-       return ret;
-}
-
-void cts_stmt_reset(cts_stmt stmt)
-{
-       sqlite3_reset(stmt);
-       sqlite3_clear_bindings(stmt);
-}
-
-void cts_stmt_finalize(cts_stmt stmt)
-{
-       int ret;
-
-       if (NULL == stmt)
-               return;
-
-       ret = sqlite3_finalize(stmt);
-       warn_if(ret != SQLITE_OK,
-                       "sqlite3_finalize Failed(%d, %s)", ret, sqlite3_errmsg(cts_db));
-}
-
-
-int cts_stmt_bind_name(cts_stmt stmt, int start_cnt, cts_name *name_struct)
-{
-       if (name_struct->first)
-               sqlite3_bind_text(stmt, start_cnt+1, name_struct->first,
-                               strlen(name_struct->first), SQLITE_STATIC);
-       if (name_struct->last)
-               sqlite3_bind_text(stmt, start_cnt+2, name_struct->last,
-                               strlen(name_struct->last), SQLITE_STATIC);
-       if (name_struct->addition)
-               sqlite3_bind_text(stmt, start_cnt+3, name_struct->addition,
-                               strlen(name_struct->addition), SQLITE_STATIC);
-       if (name_struct->display)
-               sqlite3_bind_text(stmt, start_cnt+4, name_struct->display,
-                               strlen(name_struct->display), SQLITE_STATIC);
-       if (name_struct->prefix)
-               sqlite3_bind_text(stmt, start_cnt+5, name_struct->prefix,
-                               strlen(name_struct->prefix), SQLITE_STATIC);
-       if (name_struct->suffix)
-               sqlite3_bind_text(stmt, start_cnt+6, name_struct->suffix,
-                               strlen(name_struct->suffix), SQLITE_STATIC);
-       return start_cnt+7;
-}
-
-int cts_stmt_bind_event(cts_stmt stmt, int start_cnt, cts_event *event_struct)
-{
-       sqlite3_bind_int(stmt, start_cnt++, event_struct->type);
-       sqlite3_bind_int(stmt, start_cnt++, event_struct->date);
-       return CTS_SUCCESS;
-}
-
-int cts_stmt_bind_messenger(cts_stmt stmt, int start_cnt, cts_messenger *im_struct)
-{
-       sqlite3_bind_int(stmt, start_cnt, im_struct->type);
-       if (im_struct->im_id)
-               sqlite3_bind_text(stmt, start_cnt+1, im_struct->im_id,
-                               strlen(im_struct->im_id), SQLITE_STATIC);
-       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);
-               if (im_struct->svc_op)
-                       sqlite3_bind_text(stmt, start_cnt+3, im_struct->svc_op,
-                                       strlen(im_struct->svc_op), SQLITE_STATIC);
-       }
-       return CTS_SUCCESS;
-}
-
-int cts_stmt_bind_postal(cts_stmt stmt, int start_cnt, cts_postal *postal_struct)
-{
-       sqlite3_bind_int(stmt, start_cnt, postal_struct->type);
-       if (postal_struct->pobox)
-               sqlite3_bind_text(stmt, start_cnt+1, postal_struct->pobox,
-                               strlen(postal_struct->pobox), SQLITE_STATIC);
-       if (postal_struct->postalcode)
-               sqlite3_bind_text(stmt, start_cnt+2, postal_struct->postalcode,
-                               strlen(postal_struct->postalcode), SQLITE_STATIC);
-       if (postal_struct->region)
-               sqlite3_bind_text(stmt, start_cnt+3, postal_struct->region,
-                               strlen(postal_struct->region), SQLITE_STATIC);
-       if (postal_struct->locality)
-               sqlite3_bind_text(stmt, start_cnt+4, postal_struct->locality,
-                               strlen(postal_struct->locality), SQLITE_STATIC);
-       if (postal_struct->street)
-               sqlite3_bind_text(stmt, start_cnt+5, postal_struct->street,
-                               strlen(postal_struct->street), SQLITE_STATIC);
-       if (postal_struct->extended)
-               sqlite3_bind_text(stmt, start_cnt+6, postal_struct->extended,
-                               strlen(postal_struct->extended), SQLITE_STATIC);
-       if (postal_struct->country)
-               sqlite3_bind_text(stmt, start_cnt+7, postal_struct->country,
-                               strlen(postal_struct->country), SQLITE_STATIC);
-       return CTS_SUCCESS;
-}
-
-int cts_stmt_bind_company(cts_stmt stmt, int start_cnt, cts_company *company_struct)
-{
-       if (company_struct->name)
-               sqlite3_bind_text(stmt, start_cnt+1, company_struct->name,
-                               strlen(company_struct->name), SQLITE_STATIC);
-       if (company_struct->department)
-               sqlite3_bind_text(stmt, start_cnt+2, company_struct->department,
-                               strlen(company_struct->department), SQLITE_STATIC);
-       if (company_struct->jot_title)
-               sqlite3_bind_text(stmt, start_cnt+3, company_struct->jot_title,
-                               strlen(company_struct->jot_title), SQLITE_STATIC);
-       if (company_struct->role)
-               sqlite3_bind_text(stmt, start_cnt+4, company_struct->role,
-                               strlen(company_struct->role), SQLITE_STATIC);
-       if (company_struct->assistant_name)
-               sqlite3_bind_text(stmt, start_cnt+5, company_struct->assistant_name,
-                               strlen(company_struct->assistant_name), SQLITE_STATIC);
-       return CTS_SUCCESS;
-}
-
-int cts_stmt_bind_web(cts_stmt stmt, int start_cnt, cts_web *web_struct)
-{
-       sqlite3_bind_int(stmt, start_cnt++, web_struct->type);
-       if (web_struct->url)
-               sqlite3_bind_text(stmt, start_cnt++, web_struct->url,
-                               strlen(web_struct->url), SQLITE_STATIC);
-       return CTS_SUCCESS;
-}
-
-int cts_stmt_bind_extend(cts_stmt stmt, int start_cnt, cts_extend *extend_struct)
-{
-       sqlite3_bind_int(stmt, start_cnt, extend_struct->data1);
-       if (extend_struct->data2)
-               sqlite3_bind_text(stmt, start_cnt+1, extend_struct->data2,
-                               strlen(extend_struct->data2), SQLITE_STATIC);
-       if (extend_struct->data3)
-               sqlite3_bind_text(stmt, start_cnt+2, extend_struct->data3,
-                               strlen(extend_struct->data3), SQLITE_STATIC);
-       if (extend_struct->data4)
-               sqlite3_bind_text(stmt, start_cnt+3, extend_struct->data4,
-                               strlen(extend_struct->data4), SQLITE_STATIC);
-       if (extend_struct->data5)
-               sqlite3_bind_text(stmt, start_cnt+4, extend_struct->data5,
-                               strlen(extend_struct->data5), SQLITE_STATIC);
-       if (extend_struct->data6)
-               sqlite3_bind_text(stmt, start_cnt+5, extend_struct->data6,
-                               strlen(extend_struct->data6), SQLITE_STATIC);
-       if (extend_struct->data7)
-               sqlite3_bind_text(stmt, start_cnt+6, extend_struct->data7,
-                               strlen(extend_struct->data7), SQLITE_STATIC);
-       if (extend_struct->data8)
-               sqlite3_bind_text(stmt, start_cnt+7, extend_struct->data8,
-                               strlen(extend_struct->data8), SQLITE_STATIC);
-       if (extend_struct->data9)
-               sqlite3_bind_text(stmt, start_cnt+8, extend_struct->data9,
-                               strlen(extend_struct->data9), SQLITE_STATIC);
-       if (extend_struct->data10)
-               sqlite3_bind_text(stmt, start_cnt+9, extend_struct->data10,
-                               strlen(extend_struct->data10), SQLITE_STATIC);
-       return CTS_SUCCESS;
-}
-
-int cts_stmt_get_addressbook(cts_stmt stmt, cts_addrbook *ab)
-{
-       int cnt = 0;
-       char *temp;
-
-       ab->id = cts_stmt_get_int(stmt, cnt++);
-       temp = cts_stmt_get_text(stmt, cnt++);
-       ab->name = SAFE_STRDUP(temp);
-       ab->acc_id = cts_stmt_get_int(stmt, cnt++);
-       ab->acc_type = cts_stmt_get_int(stmt, cnt++);
-       ab->mode = cts_stmt_get_int(stmt, cnt++);
-
-       return CTS_SUCCESS;
-}
-
-int cts_stmt_get_number(cts_stmt stmt, cts_number *result, int start_cnt)
-{
-       char *temp;
-
-       result->id = cts_stmt_get_int(stmt, start_cnt++);
-       result->type = cts_stmt_get_int(stmt, start_cnt++);
-       temp = cts_stmt_get_text(stmt, start_cnt++);
-       result->number = SAFE_STRDUP(temp);
-
-       return start_cnt;
-}
-
-int cts_stmt_get_email(cts_stmt stmt, cts_email *result, int start_cnt)
-{
-       char *temp;
-
-       result->id = cts_stmt_get_int(stmt, start_cnt++);
-       result->type = cts_stmt_get_int(stmt, start_cnt++);
-       temp = cts_stmt_get_text(stmt, start_cnt++);
-       result->email_addr = SAFE_STRDUP(temp);
-
-       return start_cnt;
-}
-
-int cts_stmt_get_name(cts_stmt stmt, cts_name *result, int start_cnt)
-{
-       char *temp;
-
-       result->id = cts_stmt_get_int(stmt, start_cnt++);
-       result->lang_type = cts_stmt_get_int(stmt, start_cnt++);
-       temp = cts_stmt_get_text(stmt, start_cnt++);
-       result->first = SAFE_STRDUP(temp);
-       temp = cts_stmt_get_text(stmt, start_cnt++);
-       result->last = SAFE_STRDUP(temp);
-       temp = cts_stmt_get_text(stmt, start_cnt++);
-       result->addition = SAFE_STRDUP(temp);
-       temp = cts_stmt_get_text(stmt, start_cnt++);
-       result->display = SAFE_STRDUP(temp);
-       temp = cts_stmt_get_text(stmt, start_cnt++);
-       result->prefix = SAFE_STRDUP(temp);
-       temp = cts_stmt_get_text(stmt, start_cnt++);
-       result->suffix = SAFE_STRDUP(temp);
-
-       return CTS_SUCCESS;
-}
-
diff --git a/src/cts-sqlite.h b/src/cts-sqlite.h
deleted file mode 100755 (executable)
index 4a2f708..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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_SQLITE_H__
-#define __CTS_SQLITE_H__
-
-#include <sqlite3.h>
-#include "cts-struct.h"
-
-#define CTS_SQL_MAX_LEN   2048 //normal string length
-#define CTS_SQL_MIN_LEN  1024 //short sql string length
-
-typedef sqlite3_stmt* cts_stmt;
-
-int cts_db_open(void);
-int cts_db_close(void);
-int cts_db_change();
-int cts_db_get_last_insert_id(void);
-int cts_db_get_next_id(const char *table);
-
-int cts_query_get_first_int_result(const char *query);
-int cts_query_exec(const char *query);
-cts_stmt cts_query_prepare(char *query);
-
-int cts_stmt_step(cts_stmt stmt);
-void cts_stmt_reset(cts_stmt stmt);
-void cts_stmt_finalize(cts_stmt stmt);
-
-int cts_stmt_get_first_int_result(cts_stmt stmt);
-
-static inline int cts_stmt_bind_int(cts_stmt stmt, int pos, int num) {
-       return sqlite3_bind_int(stmt, pos, num);
-}
-static inline int cts_stmt_bind_text(cts_stmt stmt, int pos, const char *str) {
-       return sqlite3_bind_text(stmt, pos, str, strlen(str), SQLITE_STATIC);
-}
-static inline int cts_stmt_bind_copy_text(cts_stmt stmt, int pos,
-               const char *str, int strlen){
-       return sqlite3_bind_text(stmt, pos, str, strlen, SQLITE_TRANSIENT);
-}
-
-int cts_stmt_bind_copy_text(cts_stmt stmt, int pos, const char *str, int strlen);
-
-
-int cts_stmt_bind_name(cts_stmt stmt, int start_cnt, cts_name *name_struct);
-int cts_stmt_bind_postal(cts_stmt stmt, int start_cnt, cts_postal *postal_struct);
-int cts_stmt_bind_company(cts_stmt stmt, int start_cnt, cts_company *company_struct);
-int cts_stmt_bind_web(cts_stmt stmt, int start_cnt, cts_web *web_struct);
-int cts_stmt_bind_messenger(cts_stmt stmt, int start_cnt, cts_messenger *im_struct);
-int cts_stmt_bind_event(cts_stmt stmt, int start_cnt, cts_event *event_struct);
-int cts_stmt_bind_extend(cts_stmt stmt, int start_cnt, cts_extend *extend_struct);
-
-static inline double cts_stmt_get_dbl(cts_stmt stmt, int pos) {
-       return sqlite3_column_double(stmt, pos);
-}
-static inline int cts_stmt_get_int(cts_stmt stmt, int pos) {
-       return sqlite3_column_int(stmt, pos);
-}
-static inline char* cts_stmt_get_text(cts_stmt stmt, int pos) {
-       return (char *)sqlite3_column_text(stmt, pos);
-}
-
-int cts_stmt_get_addressbook(cts_stmt stmt, cts_addrbook *ab);
-int cts_stmt_get_number(cts_stmt stmt, cts_number *result, int start_cnt);
-int cts_stmt_get_email(cts_stmt stmt, cts_email *result, int start_cnt);
-int cts_stmt_get_name(cts_stmt stmt, cts_name *result, int start_cnt);
-
-
-#endif //__CTS_SQLITE_H__
-
diff --git a/src/cts-struct-ext.c b/src/cts-struct-ext.c
deleted file mode 100755 (executable)
index 056a17b..0000000
+++ /dev/null
@@ -1,751 +0,0 @@
-/*
- * 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-utils.h"
-#include "cts-struct.h"
-#include "cts-struct-ext.h"
-
-#define CTS_VCARD_MOVE_TO(orig, src, check) \
-       do{ \
-               if (NULL == orig && NULL != src) { \
-                       orig = src; \
-                       check = true; \
-                       src = NULL; \
-               } \
-       }while(false)
-
-static inline int cts_merge_vcard_base(cts_ct_base *orig, cts_ct_base *addition)
-{
-       int ret;
-       char dest[CTS_IMG_PATH_SIZE_MAX];
-
-       retvm_if(NULL == addition, CTS_ERR_ARG_INVALID, "Invalid addition(%p)", addition);
-
-       if (NULL == orig->img_path) {
-               if (orig->id && addition->img_path) {
-                       ret = snprintf(dest, sizeof(dest), "%s/%d-%d.", CTS_IMAGE_LOCATION,
-                                       orig->id, CTS_IMG_NORMAL);
-                       if (0 != strncmp(dest, addition->img_path, ret)) {
-                               orig->img_path = addition->img_path;
-                               orig->img_changed = true;
-                               addition->img_path = NULL;
-                       }
-               } else {
-                       orig->img_path = addition->img_path;
-                       orig->img_changed = true;
-                       addition->img_path = NULL;
-               }
-       }
-
-       if (NULL == orig->full_img_path) {
-               if (orig->id && addition->full_img_path) {
-                       ret = snprintf(dest, sizeof(dest), "%s/%d-%d.", CTS_IMAGE_LOCATION,
-                                       orig->id, CTS_IMG_FULL);
-                       if (0 != strncmp(dest, addition->full_img_path, ret)) {
-                               orig->full_img_path = addition->full_img_path;
-                               orig->full_img_changed = true;
-                               addition->full_img_path = NULL;
-                       }
-               } else {
-                       orig->full_img_path = addition->full_img_path;
-                       orig->full_img_changed = true;
-                       addition->full_img_path = NULL;
-               }
-       }
-
-       CTS_VCARD_MOVE_TO(orig->uid, addition->uid, orig->uid_changed);
-       CTS_VCARD_MOVE_TO(orig->note, addition->note, orig->note_changed);
-       CTS_VCARD_MOVE_TO(orig->ringtone_path, addition->ringtone_path, orig->ringtone_changed);
-       if (NULL == orig->vcard_img_path) {
-               orig->vcard_img_path = addition->vcard_img_path;
-               addition->vcard_img_path = NULL;
-       }
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_merge_vcard_name(cts_name *orig, cts_name *addition)
-{
-       retvm_if(NULL == addition, CTS_ERR_ARG_INVALID, "Invalid addition(%p)", addition);
-
-       if (NULL == orig->first && NULL == orig->last) {
-               CTS_VCARD_MOVE_TO(orig->first, addition->first, orig->is_changed);
-               CTS_VCARD_MOVE_TO(orig->last, addition->last, orig->is_changed);
-       }
-       CTS_VCARD_MOVE_TO(orig->addition, addition->addition, orig->is_changed);
-       CTS_VCARD_MOVE_TO(orig->display, addition->display, orig->is_changed);
-       CTS_VCARD_MOVE_TO(orig->prefix, addition->prefix, orig->is_changed);
-       CTS_VCARD_MOVE_TO(orig->suffix, addition->suffix, orig->is_changed);
-
-       return CTS_SUCCESS;
-}
-
-static inline GSList* cts_merge_vcard_numbers(GSList *orig, GSList *addition)
-{
-       GSList *i, *j;
-       for (i=addition;i;i=i->next) {
-               cts_number *addition = i->data;
-
-               if (NULL == addition->number) continue;
-
-               for (j=orig;j;j=j->next) {
-                       cts_number *org = j->data;
-                       if (org->deleted) continue;
-                       if (addition->number && org->number
-                                       && 0 == strcmp(addition->number, org->number))
-                               break;
-               }
-               if (NULL == j) {
-                       orig = g_slist_append(orig, addition);
-                       i->data = NULL;
-               }
-       }
-
-       return orig;
-}
-
-static inline GSList* cts_merge_vcard_emails(GSList *orig, GSList *addition)
-{
-       GSList *i, *j;
-       for (i=addition;i;i=i->next) {
-               cts_email *addition = i->data;
-
-               if (NULL == addition->email_addr) continue;
-
-               for (j=orig;j;j=j->next) {
-                       cts_email *org = j->data;
-                       if (org->deleted) continue;
-                       if (addition->email_addr && org->email_addr
-                                       && 0 == strcmp(addition->email_addr, org->email_addr))
-                               break;
-               }
-               if (NULL == j) {
-                       orig = g_slist_append(orig, addition);
-                       i->data = NULL;
-               }
-       }
-
-       return orig;
-}
-
-static inline GSList* cts_merge_vcard_events(GSList *orig, GSList *addition)
-{
-       GSList *i, *j;
-       for (i=addition;i;i=i->next) {
-               cts_event *addition = i->data;
-               for (j=orig;j;j=j->next) {
-                       cts_event *org = j->data;
-                       if (org->deleted) continue;
-                       if (addition->date == org->date)
-                               break;
-               }
-               if (NULL == j) {
-                       orig = g_slist_append(orig, addition);
-                       i->data = NULL;
-               }
-       }
-
-       return orig;
-}
-
-static inline GSList* cts_merge_vcard_postals(GSList *orig, GSList *addition)
-{
-       GSList *i, *j;
-       for (i=addition;i;i=i->next) {
-               cts_postal *addition = i->data;
-               for (j=orig;j;j=j->next) {
-                       cts_postal *org = j->data;
-                       if (org->deleted) continue;
-                       char *s1, *s2;
-                       s1 = addition->pobox;
-                       s2 = org->pobox;
-                       if (s1 == s2 || (s1 && s2 && 0 == strcmp(s1, s2))) {
-                               s1 = addition->postalcode;
-                               s2 = org->postalcode;
-                               if (s1 == s2 || (s1 && s2 && 0 == strcmp(s1, s2))) {
-                                       s1 = addition->region;
-                                       s2 = org->region;
-                                       if (s1 == s2 || (s1 && s2 && 0 == strcmp(s1, s2))) {
-                                               s1 = addition->locality;
-                                               s2 = org->locality;
-                                               if (s1 == s2 || (s1 && s2 && 0 == strcmp(s1, s2))) {
-                                                       s1 = addition->street;
-                                                       s2 = org->street;
-                                                       if (s1 == s2 || (s1 && s2 && 0 == strcmp(s1, s2))) {
-                                                               s1 = addition->extended;
-                                                               s2 = org->extended;
-                                                               if (s1 == s2 || (s1 && s2 && 0 == strcmp(s1, s2))) {
-                                                                       s1 = addition->country;
-                                                                       s2 = org->country;
-                                                                       if (s1 == s2 || (s1 && s2 && 0 == strcmp(s1, s2))) {
-                                                                               break;
-                                                                       }
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-               if (NULL == j) {
-                       orig = g_slist_append(orig, addition);
-                       i->data = NULL;
-               }
-       }
-
-       return orig;
-}
-
-static inline GSList* cts_merge_vcard_webs(GSList *orig, GSList *addition)
-{
-       GSList *i, *j;
-       for (i=addition;i;i=i->next) {
-               cts_web *addition = i->data;
-
-               if (NULL == addition->url) continue;
-
-               for (j=orig;j;j=j->next) {
-                       cts_web *org = j->data;
-                       if (org->deleted) continue;
-                       if (addition->url && org->url
-                                       && 0 == strcmp(addition->url, org->url))
-                               break;
-               }
-               if (NULL == j) {
-                       orig = g_slist_append(orig, addition);
-                       i->data = NULL;
-               }
-       }
-
-       return orig;
-}
-
-static inline GSList* cts_merge_vcard_nicknames(GSList *orig, GSList *addition)
-{
-       GSList *i, *j;
-       for (i=addition;i;i=i->next) {
-               cts_nickname *addition = i->data;
-
-               if (NULL == addition->nick) continue;
-
-               for (j=orig;j;j=j->next) {
-                       cts_nickname *org = j->data;
-                       if (org->deleted) continue;
-                       if (addition->nick && org->nick
-                                       && 0 == strcmp(addition->nick, org->nick))
-                               break;
-               }
-               if (NULL == j) {
-                       orig = g_slist_append(orig, addition);
-                       i->data = NULL;
-               }
-       }
-
-       return orig;
-}
-
-static inline GSList* cts_merge_vcard_extends(GSList *orig, GSList *addition)
-{
-       GSList *d, *t;
-       cts_extend *orig_val, *addition_val;
-
-       for (d=addition;d;d=d->next) {
-               addition_val = d->data;
-
-               for (t=orig;t;t=t->next) {
-                       orig_val = t->data;
-                       if (orig_val->deleted) continue;
-                       if (addition_val->type == orig_val->type)
-                               break;
-               }
-               if (NULL == t) {
-                       orig = g_slist_append(orig, addition_val);
-                       d->data = NULL;
-               }
-       }
-
-       return orig;
-}
-
-static inline int cts_merge_vcard_company(cts_company *orig, cts_company *addition)
-{
-       bool temp;
-
-       retvm_if(NULL == addition, CTS_ERR_ARG_INVALID, "Invalid addition(%p)", addition);
-
-       CTS_VCARD_MOVE_TO(orig->name, addition->name, temp);
-       CTS_VCARD_MOVE_TO(orig->department, addition->department, temp);
-       CTS_VCARD_MOVE_TO(orig->jot_title, addition->jot_title, temp);
-       CTS_VCARD_MOVE_TO(orig->role, addition->role, temp);
-       CTS_VCARD_MOVE_TO(orig->assistant_name, addition->assistant_name, temp);
-
-       return CTS_SUCCESS;
-}
-
-static inline GSList* cts_merge_vcard_grouprel(GSList *orig, GSList *addition)
-{
-       GSList *i, *j;
-       for (i=addition;i;i=i->next) {
-               cts_group *addition = i->data;
-
-               if (0 == addition->id) continue;
-
-               for (j=orig;j;j=j->next) {
-                       cts_group *org = j->data;
-                       if (org->deleted) continue;
-                       if (addition->id == org->id)
-                               break;
-               }
-               if (NULL == j) {
-                       orig = g_slist_append(orig, addition);
-                       i->data = NULL;
-               }
-       }
-
-       return orig;
-}
-
-API int contacts_svc_struct_merge(CTSstruct *s1, CTSstruct *s2)
-{
-       contact_t *orig, *addition;
-
-       retv_if(NULL == s1, CTS_ERR_ARG_NULL);
-       retv_if(NULL == s2, CTS_ERR_ARG_NULL);
-
-       orig = (contact_t *)s1;
-       addition = (contact_t *)s2;
-
-       if (orig->base) {
-               cts_merge_vcard_base(orig->base, addition->base);
-       } else {
-               orig->base = addition->base;
-               addition->base = NULL;
-       }
-
-       if (orig->name) {
-               cts_merge_vcard_name(orig->name, addition->name);
-       } else {
-               orig->name = addition->name;
-               addition->name = NULL;
-       }
-
-       if (orig->numbers) {
-               orig->numbers =
-                       cts_merge_vcard_numbers(orig->numbers, addition->numbers);
-       } else {
-               orig->numbers = addition->numbers;
-               addition->numbers = NULL;
-       }
-
-       if (orig->emails) {
-               orig->emails =
-                       cts_merge_vcard_emails(orig->emails, addition->emails);
-       } else {
-               orig->emails = addition->emails;
-               addition->emails = NULL;
-       }
-       //orig->grouprelations does not support.
-
-       if (orig->events) {
-               orig->events =
-                       cts_merge_vcard_events(orig->events, addition->events);
-       } else {
-               orig->events = addition->events;
-               addition->events = NULL;
-       }
-       //orig->messengers does not support.
-
-       if (orig->postal_addrs) {
-               orig->postal_addrs =
-                       cts_merge_vcard_postals(orig->postal_addrs, addition->postal_addrs);
-       } else {
-               orig->postal_addrs = addition->postal_addrs;
-               addition->postal_addrs = NULL;
-       }
-
-       if (orig->web_addrs) {
-               orig->web_addrs =
-                       cts_merge_vcard_webs(orig->web_addrs, addition->web_addrs);
-       } else {
-               orig->web_addrs = addition->web_addrs;
-               addition->web_addrs = NULL;
-       }
-
-       if (orig->nicknames) {
-               orig->nicknames =
-                       cts_merge_vcard_nicknames(orig->nicknames, addition->nicknames);
-       } else {
-               orig->nicknames = addition->nicknames;
-               addition->nicknames = NULL;
-       }
-
-       if (orig->company) {
-               cts_merge_vcard_company(orig->company, addition->company);
-       } else {
-               orig->company = addition->company;
-               addition->company = NULL;
-       }
-
-       if (orig->grouprelations) {
-               cts_merge_vcard_grouprel(orig->grouprelations, addition->grouprelations);
-       } else {
-               orig->grouprelations = addition->grouprelations;
-               addition->grouprelations = NULL;
-       }
-
-       if (orig->extended_values) {
-               orig->extended_values =
-                       cts_merge_vcard_extends(orig->extended_values, addition->extended_values);
-       } else {
-               orig->extended_values = addition->extended_values;
-               addition->extended_values = NULL;
-       }
-
-       return CTS_SUCCESS;
-}
-
-static inline cts_ct_base* cts_struct_dup_base(const cts_ct_base *src)
-{
-       cts_ct_base *result = NULL;
-       if (src) {
-               result = calloc(1, sizeof(cts_ct_base));
-               retvm_if(NULL == result, NULL, "calloc() Failed");
-
-               memcpy(result, src, sizeof(cts_ct_base));
-
-               if (src->uid)
-                       result->uid = strdup(src->uid);
-               if (src->img_path)
-                       result->img_path = strdup(src->img_path);
-               if (src->full_img_path)
-                       result->full_img_path = strdup(src->full_img_path);
-               if (src->ringtone_path)
-                       result->ringtone_path = strdup(src->ringtone_path);
-               if (src->note)
-                       result->note = strdup(src->note);
-               if (src->vcard_img_path)
-                       result->vcard_img_path = strdup(src->vcard_img_path);
-       }
-
-       return result;
-}
-
-static inline cts_name* cts_struct_dup_name(const cts_name *src)
-{
-       cts_name *result = NULL;
-       if (src) {
-               result = calloc(1, sizeof(cts_name));
-               retvm_if(NULL == result, NULL, "calloc() Failed");
-
-               memcpy(result, src, sizeof(cts_name));
-
-               if (src->first)
-                       result->first = strdup(src->first);
-               if (src->last)
-                       result->last = strdup(src->last);
-               if (src->addition)
-                       result->addition = strdup(src->addition);
-               if (src->display)
-                       result->display = strdup(src->display);
-               if (src->prefix)
-                       result->prefix = strdup(src->prefix);
-               if (src->suffix)
-                       result->suffix = strdup(src->suffix);
-       }
-
-       return result;
-}
-
-static inline cts_number* cts_struct_dup_number(const cts_number *src)
-{
-       cts_number *result = NULL;
-       if (src) {
-               result = calloc(1, sizeof(cts_number));
-               retvm_if(NULL == result, NULL, "calloc() Failed");
-
-               memcpy(result, src, sizeof(cts_number));
-
-               if (src->number)
-                       result->number = strdup(src->number);
-       }
-
-       return result;
-}
-
-static inline cts_email* cts_struct_dup_email(const cts_email *src)
-{
-       cts_email *result = NULL;
-       if (src) {
-               result = calloc(1, sizeof(cts_email));
-               retvm_if(NULL == result, NULL, "calloc() Failed");
-
-               memcpy(result, src, sizeof(cts_email));
-
-               if (src->email_addr)
-                       result->email_addr = strdup(src->email_addr);
-       }
-
-       return result;
-}
-
-static inline cts_web* cts_struct_dup_web(const cts_web *src)
-{
-       cts_web *result = NULL;
-       if (src) {
-               result = calloc(1, sizeof(cts_web));
-               retvm_if(NULL == result, NULL, "calloc() Failed");
-
-               memcpy(result, src, sizeof(cts_web));
-
-               if (src->url)
-                       result->url = strdup(src->url);
-       }
-
-       return result;
-}
-
-static inline cts_postal* cts_struct_dup_postal(const cts_postal *src)
-{
-       cts_postal *result = NULL;
-       if (src) {
-               result = calloc(1, sizeof(cts_postal));
-               retvm_if(NULL == result, NULL, "calloc() Failed");
-
-               memcpy(result, src, sizeof(cts_postal));
-
-               if (src->pobox)
-                       result->pobox = strdup(src->pobox);
-               if (src->postalcode)
-                       result->postalcode = strdup(src->postalcode);
-               if (src->region)
-                       result->region = strdup(src->region);
-               if (src->locality)
-                       result->locality = strdup(src->locality);
-               if (src->street)
-                       result->street = strdup(src->street);
-               if (src->extended)
-                       result->extended = strdup(src->extended);
-               if (src->country)
-                       result->country = strdup(src->country);
-       }
-
-       return result;
-}
-
-static inline cts_event* cts_struct_dup_event(const cts_event *src)
-{
-       cts_event *result = NULL;
-       if (src) {
-               result = calloc(1, sizeof(cts_event));
-               retvm_if(NULL == result, NULL, "calloc() Failed");
-
-               memcpy(result, src, sizeof(cts_event));
-       }
-
-       return result;
-}
-
-static inline cts_messenger* cts_struct_dup_messenger(const cts_messenger *src)
-{
-       cts_messenger *result = NULL;
-       if (src) {
-               result = calloc(1, sizeof(cts_messenger));
-               retvm_if(NULL == result, NULL, "calloc() Failed");
-
-               memcpy(result, src, sizeof(cts_messenger));
-
-               if (src->im_id)
-                       result->im_id = strdup(src->im_id);
-               if (src->svc_name)
-                       result->svc_name = strdup(src->svc_name);
-               if (src->svc_op)
-                       result->svc_op = strdup(src->svc_op);
-       }
-
-       return result;
-}
-
-static inline cts_group* cts_struct_dup_grouprel(const cts_group *src)
-{
-       cts_group *result = NULL;
-       if (src) {
-               result = calloc(1, sizeof(cts_group));
-               retvm_if(NULL == result, NULL, "calloc() Failed");
-
-               memcpy(result, src, sizeof(cts_group));
-
-               if (src->name)
-                       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;
-}
-
-static inline cts_extend* cts_struct_dup_extend(const cts_extend *src)
-{
-       cts_extend *result = NULL;
-       if (src) {
-               result = calloc(1, sizeof(cts_extend));
-               retvm_if(NULL == result, NULL, "calloc() Failed");
-
-               memcpy(result, src, sizeof(cts_extend));
-
-               if (src->data2)
-                       result->data2 = strdup(src->data2);
-               if (src->data3)
-                       result->data3 = strdup(src->data3);
-               if (src->data4)
-                       result->data4 = strdup(src->data4);
-               if (src->data5)
-                       result->data5 = strdup(src->data5);
-               if (src->data6)
-                       result->data6 = strdup(src->data6);
-               if (src->data7)
-                       result->data7 = strdup(src->data7);
-               if (src->data8)
-                       result->data8 = strdup(src->data8);
-               if (src->data9)
-                       result->data9 = strdup(src->data9);
-               if (src->data10)
-                       result->data10 = strdup(src->data10);
-       }
-
-       return result;
-}
-
-static inline cts_nickname* cts_struct_dup_nick(const cts_nickname *src)
-{
-       cts_nickname *result = NULL;
-       if (src) {
-               result = calloc(1, sizeof(cts_nickname));
-               retvm_if(NULL == result, NULL, "calloc() Failed");
-
-               memcpy(result, src, sizeof(cts_nickname));
-
-               if (src->nick)
-                       result->nick = strdup(src->nick);
-       }
-
-       return result;
-}
-
-static inline GSList* cts_struct_dup_list(int type, GSList *src)
-{
-       GSList *cur, *result = NULL;
-       if (src) {
-               result = g_slist_copy(src);
-
-               for (cur=result;cur;cur=cur->next) {
-                       switch (type) {
-                       case CTS_VALUE_NUMBER:
-                               cur->data = cts_struct_dup_number(cur->data);
-                               break;
-                       case CTS_VALUE_EMAIL:
-                               cur->data = cts_struct_dup_email(cur->data);
-                               break;
-                       case CTS_VALUE_WEB:
-                               cur->data = cts_struct_dup_web(cur->data);
-                               break;
-                       case CTS_VALUE_POSTAL:
-                               cur->data = cts_struct_dup_postal(cur->data);
-                               break;
-                       case CTS_VALUE_EVENT:
-                               cur->data = cts_struct_dup_event(cur->data);
-                               break;
-                       case CTS_VALUE_MESSENGER:
-                               cur->data = cts_struct_dup_messenger(cur->data);
-                               break;
-                       case CTS_VALUE_GROUP_RELATION:
-                               cur->data = cts_struct_dup_grouprel(cur->data);
-                               break;
-                       case CTS_VALUE_EXTEND:
-                               cur->data = cts_struct_dup_extend(cur->data);
-                               break;
-                       case CTS_VALUE_NICKNAME:
-                               cur->data = cts_struct_dup_nick(cur->data);
-                               break;
-                       default:
-                               ERR("invalid type(%d)", type);
-                               break;
-                       }
-               }
-       }
-
-       return result;
-}
-
-static inline cts_company* cts_struct_dup_company(const cts_company *src)
-{
-       cts_company *result = NULL;
-       if (src) {
-               result = calloc(1, sizeof(cts_company));
-               retvm_if(NULL == result, NULL, "calloc() Failed");
-
-               memcpy(result, src, sizeof(cts_company));
-
-               if (src->name)
-                       result->name = strdup(src->name);
-               if (src->department)
-                       result->department = strdup(src->department);
-               if (src->jot_title)
-                       result->jot_title = strdup(src->jot_title);
-               if (src->role)
-                       result->role = strdup(src->role);
-               if (src->assistant_name)
-                       result->assistant_name = strdup(src->assistant_name);
-       }
-
-       return result;
-}
-
-API CTSstruct* contacts_svc_struct_duplicate(const CTSstruct *contact)
-{
-       contact_t *src, *result = NULL;
-
-       retvm_if(NULL == contact, NULL, "contact is NULL");
-
-       src = (contact_t *)contact;
-       result = (contact_t *)contacts_svc_struct_new(CTS_STRUCT_CONTACT);
-       retvm_if(NULL == result, NULL, "contacts_svc_struct_new() Failed");
-
-       result->base = cts_struct_dup_base(src->base);
-       result->name = cts_struct_dup_name(src->name);
-       result->numbers = cts_struct_dup_list(CTS_VALUE_NUMBER, src->numbers);
-       result->emails = cts_struct_dup_list(CTS_VALUE_EMAIL, src->emails);
-       result->web_addrs = cts_struct_dup_list(CTS_VALUE_WEB, src->web_addrs);
-       result->postal_addrs = cts_struct_dup_list(CTS_VALUE_POSTAL, src->postal_addrs);
-       result->events = cts_struct_dup_list(CTS_VALUE_EVENT, src->events);
-       result->messengers = cts_struct_dup_list(CTS_VALUE_MESSENGER, src->messengers);
-       result->grouprelations = cts_struct_dup_list(CTS_VALUE_GROUP_RELATION, src->grouprelations);
-       result->company = cts_struct_dup_company(src->company);
-       result->extended_values = cts_struct_dup_list(CTS_VALUE_EXTEND, src->extended_values);
-       result->nicknames = cts_struct_dup_list(CTS_VALUE_NICKNAME, src->nicknames);
-
-       result->default_num = src->default_num;
-       result->default_email = src->default_email;
-
-       return (CTSstruct *)result;
-}
-
diff --git a/src/cts-struct-ext.h b/src/cts-struct-ext.h
deleted file mode 100755 (executable)
index 88c373c..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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_STRUCT_EXT_H__
-#define __CTS_STRUCT_EXT_H__
-
-//<!--
-
-/**
- * This function merges two contact. #s2 merges into #s1.
- * Free #s2 immediately, regardless of success.
- * #s2 must not be used after calling this function.
- * If single-value field(_VALUE suffix) is conflict, s2 value is ignored.
- * The case of multi-value field(_LIST suffix), s2 list will be append to s1 list.
- *
- *
- * @param[in] s1 The base contact
- * @param[in] s2 The contact which is added to #s1.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_struct_merge(CTSstruct *s1, CTSstruct *s2);
-
-/**
- * duplicate a contact struct.
- *
- * @param[in] contact a contact struct(#CTSstruct)
- * @return a pointer to a new duplicated contact struct on success, NULL on error
- */
-CTSstruct* contacts_svc_struct_duplicate(const CTSstruct *contact);
-
-//-->
-
-#endif //__CTS_STRUCT_EXT_H__
-
diff --git a/src/cts-struct.c b/src/cts-struct.c
deleted file mode 100755 (executable)
index 23b0103..0000000
+++ /dev/null
@@ -1,3010 +0,0 @@
-/*
- * 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 <unistd.h>
-#include <errno.h>
-
-#include "cts-internal.h"
-#include "cts-list.h"
-#include "cts-utils.h"
-
-static contact_list *contact_list_mempool=NULL;
-static plog_list *plog_list_mempool=NULL;
-static change_list *change_list_mempool=NULL;
-static numtype_list *numtype_list_mempool=NULL;
-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) {
-       case CTS_STRUCT_CONTACT:
-               ret_val = (CTSstruct*)calloc(1, sizeof(contact_t));
-               if (ret_val) ret_val->s_type = CTS_STRUCT_CONTACT;
-               return ret_val;
-       default:
-               ERR("your type is Not supported");
-               return NULL;
-       }
-}
-
-static void cts_number_free(gpointer data, gpointer user_data)
-{
-       if (NULL == data || !((cts_number*)data)->embedded)
-               return;
-
-       free(((cts_number*)data)->number);
-       free(((cts_number*)data)->added_type);
-       free(data);
-}
-static void cts_email_free(gpointer data, gpointer user_data)
-{
-       if (NULL == data || !((cts_email*)data)->embedded)
-               return;
-
-       free(((cts_email*)data)->email_addr);
-       free(data);
-}
-static void cts_group_free(gpointer data, gpointer user_data)
-{
-       cts_group* data0 = (cts_group*)data;
-
-       if (NULL == data || !data0->embedded)
-               return;
-
-       free(data0->name);
-       free(data0->ringtone_path);
-       free(data0->img_path);
-       free(data0->vcard_group);
-       free(data);
-}
-static void cts_event_free(gpointer data, gpointer user_data)
-{
-       if (NULL == data || !((cts_event*)data)->embedded)
-               return;
-
-       free(data);
-}
-static void cts_messenger_free(gpointer data, gpointer user_data)
-{
-       cts_messenger *data0 = (cts_messenger *)data;
-
-       if (NULL == data0 || !data0->embedded)
-               return;
-
-       free(data0->im_id);
-       free(data0->svc_name);
-       free(data0->svc_op);
-       free(data);
-}
-static void cts_postal_free(gpointer data, gpointer user_data)
-{
-       cts_postal *data0 = (cts_postal *)data;
-
-       if (NULL == data0 || !data0->embedded)
-               return;
-
-       free(data0->pobox);
-       free(data0->postalcode);
-       free(data0->region);
-       free(data0->locality);
-       free(data0->street);
-       free(data0->extended);
-       free(data0->country);
-       free(data);
-}
-static void cts_web_free(gpointer data, gpointer user_data)
-{
-       if (NULL == data || !((cts_web*)data)->embedded)
-               return;
-
-       free(((cts_web*)data)->url);
-       free(data);
-}
-static void cts_nickname_free(gpointer data, gpointer user_data)
-{
-       if (NULL == data || !((cts_nickname*)data)->embedded)
-               return;
-
-       free(((cts_nickname*)data)->nick);
-       free(data);
-}
-
-static void cts_extend_free(gpointer data, gpointer user_data)
-{
-       cts_extend *data0 = (cts_extend *)data;
-       if (NULL == data0 || !data0->embedded)
-               return;
-
-       free(data0->data2);
-       free(data0->data3);
-       free(data0->data4);
-       free(data0->data5);
-       free(data0->data6);
-       free(data0->data7);
-       free(data0->data8);
-       free(data0->data9);
-       free(data0->data10);
-       free(data);
-}
-
-static inline void cts_name_free(cts_name *name)
-{
-       if (!name->embedded)
-               return;
-
-       free(name->first);
-       free(name->last);
-       free(name->addition);
-       free(name->display);
-       free(name->prefix);
-       free(name->suffix);
-       free(name);
-}
-
-static inline void cts_company_free(cts_company *company)
-{
-       if (!company->embedded)
-               return;
-
-       free(company->name);
-       free(company->department);
-       free(company->jot_title);
-       free(company->role);
-       free(company->assistant_name);
-       free(company);
-}
-
-static inline void cts_contact_free(contact_t *contact)
-{
-       if (contact->base && contact->base->embedded) {
-               free(contact->base->uid);
-               free(contact->base->img_path);
-               free(contact->base->full_img_path);
-               free(contact->base->ringtone_path);
-               free(contact->base->note);
-
-               if (contact->base->vcard_img_path) {
-                       unlink(contact->base->vcard_img_path);
-                       free(contact->base->vcard_img_path);
-               }
-
-               free(contact->base);
-       }
-
-       if (contact->name)
-               cts_name_free(contact->name);
-
-       if (contact->company)
-               cts_company_free(contact->company);
-
-       if (contact->numbers) {
-               g_slist_foreach(contact->numbers, cts_number_free, NULL);
-               g_slist_free(contact->numbers);
-       }
-
-       if (contact->emails) {
-               g_slist_foreach(contact->emails, cts_email_free, NULL);
-               g_slist_free(contact->emails);
-       }
-
-       if (contact->grouprelations) {
-               g_slist_foreach(contact->grouprelations, cts_group_free, NULL);
-               g_slist_free(contact->grouprelations);
-       }
-
-       if (contact->events) {
-               g_slist_foreach(contact->events, cts_event_free, NULL);
-               g_slist_free(contact->events);
-       }
-
-       if (contact->messengers) {
-               g_slist_foreach(contact->messengers, cts_messenger_free, NULL);
-               g_slist_free(contact->messengers);
-       }
-
-       if (contact->postal_addrs) {
-               g_slist_foreach(contact->postal_addrs, cts_postal_free, NULL);
-               g_slist_free(contact->postal_addrs);
-       }
-
-       if (contact->web_addrs) {
-               g_slist_foreach(contact->web_addrs, cts_web_free, NULL);
-               g_slist_free(contact->web_addrs);
-       }
-
-       if (contact->nicknames) {
-               g_slist_foreach(contact->nicknames, cts_nickname_free, NULL);
-               g_slist_free(contact->nicknames);
-       }
-
-       if (contact->extended_values) {
-               g_slist_foreach(contact->extended_values, cts_extend_free, NULL);
-               g_slist_free(contact->extended_values);
-       }
-}
-
-API int contacts_svc_struct_free(CTSstruct* structure)
-{
-       retv_if(NULL == structure, CTS_ERR_ARG_NULL);
-
-       switch (structure->s_type) {
-       case CTS_STRUCT_CONTACT:
-               cts_contact_free((contact_t *)structure);
-               free(structure);
-               break;
-       default:
-               ERR("The structure type(%d) is Not valid", structure->s_type);
-               return CTS_ERR_ARG_INVALID;
-       }
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_struct_get_list(CTSstruct *contact,
-               cts_struct_field field, GSList** retlist)
-{
-       contact_t *record = (contact_t *)contact;
-
-       retv_if(NULL == contact, CTS_ERR_ARG_NULL);
-       retv_if(NULL == retlist, CTS_ERR_ARG_NULL);
-       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) {
-       case CTS_CF_NUMBER_LIST:
-               *retlist = record->numbers;
-               break;
-       case CTS_CF_EMAIL_LIST:
-               *retlist = record->emails;
-               break;
-       case CTS_CF_GROUPREL_LIST:
-               *retlist = record->grouprelations;
-               break;
-       case CTS_CF_EVENT_LIST:
-               *retlist = record->events;
-               break;
-       case CTS_CF_MESSENGER_LIST:
-               *retlist = record->messengers;
-               break;
-       case CTS_CF_POSTAL_ADDR_LIST:
-               *retlist = record->postal_addrs;
-               break;
-       case CTS_CF_WEB_ADDR_LIST:
-               *retlist = record->web_addrs;
-               break;
-       case CTS_CF_NICKNAME_LIST:
-               *retlist = record->nicknames;
-               break;
-       default:
-               ERR("The parameter(field) is invalid"
-                               "You MUST be (CTS_CF_VALUE_MAX < field < CTS_CF_FIELD_MAX).");
-               return CTS_ERR_ARG_INVALID;
-       }
-
-       if (NULL == *retlist) return CTS_ERR_NO_DATA;
-
-       return CTS_SUCCESS;
-}
-
-static cts_extend* cts_extend_slist_search(int type, GSList *list)
-{
-       cts_extend *tmp_extend;
-       GSList *tmp_gslist=list;
-       while (tmp_gslist) {
-               tmp_extend = tmp_gslist->data;
-               retvm_if(CTS_VALUE_EXTEND != tmp_extend->v_type, NULL,
-                               "List has other type");
-               if (tmp_extend->type == type) return tmp_extend;
-
-               tmp_gslist = tmp_gslist->next;
-       }
-       return NULL;
-}
-
-static inline int cts_contact_get_value(contact_t *contact,
-               cts_struct_field field, CTSvalue** retval)
-{
-
-       switch (field) {
-       case CTS_CF_NAME_VALUE:
-               *retval = (CTSvalue *)contact->name;
-               break;
-       case CTS_CF_BASE_INFO_VALUE:
-               *retval = (CTSvalue *)contact->base;
-               break;
-       case CTS_CF_COMPANY_VALUE:
-               *retval = (CTSvalue *)contact->company;
-               break;
-       default:
-               if ((int)CTS_DATA_EXTEND_START <= field) {
-                       *retval = (CTSvalue *)cts_extend_slist_search(field,
-                                       contact->extended_values);
-                       return CTS_SUCCESS;
-               }
-               ERR("The parameter(field:%d) is not interpreted", field);
-               return CTS_ERR_ARG_INVALID;
-       }
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_struct_get_value(CTSstruct *structure,
-               cts_struct_field field, CTSvalue **retval)
-{
-       int ret;
-
-       retv_if(NULL == structure, CTS_ERR_ARG_NULL);
-       retv_if(NULL == retval, CTS_ERR_ARG_NULL);
-
-       switch (structure->s_type) {
-       case CTS_STRUCT_CONTACT:
-               ret = cts_contact_get_value((contact_t *)structure, field, retval);
-               if (CTS_SUCCESS != ret)
-                       return ret;
-               break;
-       default:
-               ERR("The structure type(%d) is Not valid", structure->s_type);
-               return CTS_ERR_ARG_INVALID;
-       }
-
-       if (NULL == *retval) return CTS_ERR_NO_DATA;
-       return CTS_SUCCESS;
-}
-
-#define CTS_REMOVE_GSLIST_ITEM(type, loc) \
-       do { \
-               cts_##type##_free(tmp_##type, NULL); \
-               if (prev) { \
-                       prev->next = tmp_gslist->next; \
-                       g_slist_free_1(tmp_gslist); \
-                       tmp_gslist = prev->next; \
-               } \
-               else { \
-                       contact->loc = tmp_gslist->next; \
-                       g_slist_free_1(tmp_gslist); \
-                       tmp_gslist = contact->loc; \
-               } \
-       }while(false)
-
-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) {
-                       tmp_number = tmp_gslist->data;
-                       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) {
-                                       CTS_REMOVE_GSLIST_ITEM(number, numbers);
-                                       continue;
-                               }
-
-                               if (!tmp_number->embedded) {
-                                       tmp_number->embedded = true;
-                                       tmp_number->number = SAFE_STRDUP(tmp_number->number);
-                               }
-                       }
-                       prev = tmp_gslist;
-                       tmp_gslist = tmp_gslist->next;
-               }
-       }
-       else {
-               while (tmp_gslist) {
-                       tmp_number = tmp_gslist->data;
-                       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) {
-                                       tmp_number->embedded = true;
-                                       tmp_number->number = SAFE_STRDUP(tmp_number->number);
-                                       new_gslist = g_slist_append(new_gslist, tmp_number);
-                               }
-                       }
-                       tmp_gslist = tmp_gslist->next;
-               }
-               contact->numbers = g_slist_concat(contact->numbers, new_gslist);
-       }
-       return CTS_SUCCESS;
-}
-
-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) {
-                       tmp_email = tmp_gslist->data;
-                       if (tmp_email) {
-                               retvm_if(CTS_VALUE_EMAIL != tmp_email->v_type, CTS_ERR_ARG_INVALID,
-                                               "List has other type");
-
-                               if (!tmp_email->id && tmp_email->deleted) {
-                                       CTS_REMOVE_GSLIST_ITEM(email, emails);
-                                       continue;
-                               }
-
-                               if (!tmp_email->embedded) {
-                                       tmp_email->embedded = true;
-                                       tmp_email->email_addr = SAFE_STRDUP(tmp_email->email_addr);
-                               }
-                       }
-                       prev = tmp_gslist;
-                       tmp_gslist = tmp_gslist->next;
-               }
-       }
-       else {
-               while (tmp_gslist) {
-                       tmp_email = tmp_gslist->data;
-                       if (tmp_email) {
-                               retvm_if(CTS_VALUE_EMAIL != tmp_email->v_type, CTS_ERR_ARG_INVALID,
-                                               "List has other type");
-                               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);
-                               }
-                       }
-                       tmp_gslist = tmp_gslist->next;
-               }
-               contact->emails = g_slist_concat(contact->emails, new_gslist);
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_struct_store_grouprel_list(contact_t *contact, GSList* list)
-{
-       cts_group *tmp_group;
-
-       GSList *new_gslist=NULL, *tmp_gslist=list, *prev=NULL;
-       if (contact->grouprelations && tmp_gslist == contact->grouprelations) {
-               while (tmp_gslist) {
-                       tmp_group = tmp_gslist->data;
-                       if (tmp_group) {
-                               retvm_if(CTS_VALUE_GROUP_RELATION != tmp_group->v_type, CTS_ERR_ARG_INVALID,
-                                               "List has other type");
-
-                               if (!tmp_group->name && tmp_group->deleted) {
-                                       CTS_REMOVE_GSLIST_ITEM(group, grouprelations);
-                                       continue;
-                               }
-
-                               tmp_group->embedded = true;
-                       }
-                       prev = tmp_gslist;
-                       tmp_gslist = tmp_gslist->next;
-               }
-       }
-       else {
-               while (tmp_gslist) {
-                       tmp_group = tmp_gslist->data;
-                       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) {
-                                       tmp_group->embedded = true;
-                                       new_gslist = g_slist_append(new_gslist, tmp_group);
-                               }
-                       }
-                       tmp_gslist = tmp_gslist->next;
-               }
-               contact->grouprelations = g_slist_concat(contact->grouprelations, new_gslist);
-       }
-       return CTS_SUCCESS;
-}
-
-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) {
-                       tmp_event = tmp_gslist->data;
-                       if (tmp_event) {
-                               retvm_if(CTS_VALUE_EVENT != tmp_event->v_type, CTS_ERR_ARG_INVALID,
-                                               "List has other type");
-
-                               if (!tmp_event->id && tmp_event->deleted) {
-                                       CTS_REMOVE_GSLIST_ITEM(event, events);
-                                       continue;
-                               }
-
-                               tmp_event->embedded = true;
-                       }
-                       prev = tmp_gslist;
-                       tmp_gslist = tmp_gslist->next;
-               }
-       }
-       else {
-               while (tmp_gslist) {
-                       tmp_event = tmp_gslist->data;
-                       if (tmp_event) {
-                               retvm_if(CTS_VALUE_EVENT != tmp_event->v_type, CTS_ERR_ARG_INVALID,
-                                               "List has other type");
-                               if (!tmp_event->embedded) {
-                                       tmp_event->embedded = true;
-                                       new_gslist = g_slist_append(new_gslist, tmp_event);
-                               }
-                       }
-                       tmp_gslist = tmp_gslist->next;
-               }
-               contact->events = g_slist_concat(contact->events, new_gslist);
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_struct_store_messenger_list(contact_t *contact, GSList* list)
-{
-       cts_messenger *tmp_messenger;
-
-       GSList *new_gslist=NULL, *tmp_gslist=list, *prev=NULL;
-       if (contact->messengers && tmp_gslist == contact->messengers) {
-               while (tmp_gslist) {
-                       tmp_messenger = tmp_gslist->data;
-                       if (tmp_messenger) {
-                               retvm_if(CTS_VALUE_MESSENGER != tmp_messenger->v_type, CTS_ERR_ARG_INVALID,
-                                               "List has other type");
-
-                               if (!tmp_messenger->id && tmp_messenger->deleted) {
-                                       CTS_REMOVE_GSLIST_ITEM(messenger, messengers);
-                                       continue;
-                               }
-
-                               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);
-                                       tmp_messenger->svc_op = SAFE_STRDUP(tmp_messenger->svc_op);
-                               }
-                       }
-                       prev = tmp_gslist;
-                       tmp_gslist = tmp_gslist->next;
-               }
-       }
-       else {
-               while (tmp_gslist) {
-                       tmp_messenger = tmp_gslist->data;
-                       if (tmp_messenger) {
-                               retvm_if(CTS_VALUE_MESSENGER != tmp_messenger->v_type, CTS_ERR_ARG_INVALID,
-                                               "List has other type");
-                               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);
-                                       tmp_messenger->svc_op = SAFE_STRDUP(tmp_messenger->svc_op);
-                                       new_gslist = g_slist_append(new_gslist, tmp_messenger);
-                               }
-                       }
-                       tmp_gslist = tmp_gslist->next;
-               }
-               contact->messengers = g_slist_concat(contact->messengers, new_gslist);
-       }
-       return CTS_SUCCESS;
-}
-
-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) {
-                       tmp_postal = tmp_gslist->data;
-                       if (tmp_postal) {
-                               retvm_if(CTS_VALUE_POSTAL != tmp_postal->v_type, CTS_ERR_ARG_INVALID,
-                                               "List has other type");
-
-                               if (!tmp_postal->id && tmp_postal->deleted) {
-                                       CTS_REMOVE_GSLIST_ITEM(postal, postal_addrs);
-                                       continue;
-                               }
-
-                               if (!tmp_postal->embedded) {
-                                       tmp_postal->embedded = true;
-                                       tmp_postal->pobox = SAFE_STRDUP(tmp_postal->pobox);
-                                       tmp_postal->postalcode = SAFE_STRDUP(tmp_postal->postalcode);
-                                       tmp_postal->region = SAFE_STRDUP(tmp_postal->region);
-                                       tmp_postal->locality = SAFE_STRDUP(tmp_postal->locality);
-                                       tmp_postal->street = SAFE_STRDUP(tmp_postal->street);
-                                       tmp_postal->extended = SAFE_STRDUP(tmp_postal->extended);
-                                       tmp_postal->country = SAFE_STRDUP(tmp_postal->country);
-                               }
-                       }
-                       prev = tmp_gslist;
-                       tmp_gslist = tmp_gslist->next;
-               }
-       }
-       else {
-               //retvm_if(NULL != contact->postal_addrs, CTS_ERR_ARG_INVALID, "New list can be stored when struct has no list");
-               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,
-                                               "List has other type");
-                               if (!tmp_postal->embedded) {
-                                       tmp_postal->embedded = true;
-                                       tmp_postal->pobox = SAFE_STRDUP(tmp_postal->pobox);
-                                       tmp_postal->postalcode = SAFE_STRDUP(tmp_postal->postalcode);
-                                       tmp_postal->region = SAFE_STRDUP(tmp_postal->region);
-                                       tmp_postal->locality = SAFE_STRDUP(tmp_postal->locality);
-                                       tmp_postal->street = SAFE_STRDUP(tmp_postal->street);
-                                       tmp_postal->extended = SAFE_STRDUP(tmp_postal->extended);
-                                       tmp_postal->country = SAFE_STRDUP(tmp_postal->country);
-                                       new_gslist = g_slist_append(new_gslist, tmp_postal);
-                               }
-                       }
-                       tmp_gslist = tmp_gslist->next;
-               }
-               contact->postal_addrs = g_slist_concat(contact->postal_addrs, new_gslist);
-       }
-       return CTS_SUCCESS;
-}
-
-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) {
-                       tmp_web = tmp_gslist->data;
-                       if (tmp_web) {
-                               retvm_if(CTS_VALUE_WEB != tmp_web->v_type, CTS_ERR_ARG_INVALID,
-                                               "List has other type");
-
-                               if (!tmp_web->id && tmp_web->deleted) {
-                                       CTS_REMOVE_GSLIST_ITEM(web, web_addrs);
-                                       continue;
-                               }
-
-                               if (!tmp_web->embedded) {
-                                       tmp_web->embedded = true;
-                                       tmp_web->url = SAFE_STRDUP(tmp_web->url);
-                               }
-                       }
-                       prev = tmp_gslist;
-                       tmp_gslist = tmp_gslist->next;
-               }
-       }
-       else {
-               while (tmp_gslist) {
-                       tmp_web = tmp_gslist->data;
-                       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) {
-                                       tmp_web->embedded = true;
-                                       tmp_web->url = SAFE_STRDUP(tmp_web->url);
-                                       new_gslist = g_slist_append(new_gslist, tmp_web);
-                               }
-                       }
-                       tmp_gslist = tmp_gslist->next;
-               }
-               contact->web_addrs = g_slist_concat(contact->web_addrs, new_gslist);
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_struct_store_nickname_list(contact_t *contact, GSList* list)
-{
-       cts_nickname *tmp_nickname;
-
-       GSList *new_gslist=NULL, *tmp_gslist=list, *prev=NULL;
-       if (contact->nicknames && tmp_gslist == contact->nicknames) {
-               while (tmp_gslist) {
-                       tmp_nickname = tmp_gslist->data;
-                       if (tmp_nickname) {
-                               retvm_if(CTS_VALUE_NICKNAME != tmp_nickname->v_type, CTS_ERR_ARG_INVALID,
-                                               "List has other type");
-
-                               if (!tmp_nickname->id && tmp_nickname->deleted) {
-                                       CTS_REMOVE_GSLIST_ITEM(nickname, nicknames);
-                                       continue;
-                               }
-
-                               if (!tmp_nickname->embedded) {
-                                       tmp_nickname->embedded = true;
-                                       tmp_nickname->nick = SAFE_STRDUP(tmp_nickname->nick);
-                               }
-                       }
-                       prev = tmp_gslist;
-                       tmp_gslist = tmp_gslist->next;
-               }
-       }
-       else {
-               //retvm_if(NULL != contact->web_addrs, CTS_ERR_ARG_INVALID, "New list can be stored when struct has no list");
-               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) {
-                                       tmp_nickname->embedded = true;
-                                       tmp_nickname->nick = SAFE_STRDUP(tmp_nickname->nick);
-                                       new_gslist = g_slist_append(new_gslist, tmp_nickname);
-                               }
-                       }
-                       tmp_gslist = tmp_gslist->next;
-               }
-               contact->nicknames = g_slist_concat(contact->nicknames, new_gslist);
-       }
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_struct_store_list(CTSstruct *contact,
-               cts_struct_field field, GSList *list)
-{
-       int ret;
-
-       retv_if(NULL == contact, CTS_ERR_ARG_NULL);
-       retv_if(NULL == list, CTS_ERR_ARG_NULL);
-       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) {
-       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);
-               break;
-       case CTS_CF_EMAIL_LIST:
-               ret = cts_struct_store_email_list((contact_t *)contact, list);
-               retvm_if(CTS_SUCCESS != ret, ret, "cts_struct_store_email_list() Failed(%d)",ret);
-               break;
-       case CTS_CF_GROUPREL_LIST:
-               ret = cts_struct_store_grouprel_list((contact_t *)contact, list);
-               retvm_if(CTS_SUCCESS != ret, ret, "cts_struct_store_grouprel_list() Failed(%d)",ret);
-               break;
-       case CTS_CF_EVENT_LIST:
-               ret = cts_struct_store_event_list((contact_t *)contact, list);
-               retvm_if(CTS_SUCCESS != ret, ret, "cts_struct_store_event_list() Failed(%d)",ret);
-               break;
-       case CTS_CF_MESSENGER_LIST:
-               ret = cts_struct_store_messenger_list((contact_t *)contact, list);
-               retvm_if(CTS_SUCCESS != ret, ret, "cts_struct_store_messenger_list() Failed(%d)",ret);
-               break;
-       case CTS_CF_POSTAL_ADDR_LIST:
-               ret = cts_struct_store_postal_list((contact_t *)contact, list);
-               retvm_if(CTS_SUCCESS != ret, ret, "cts_struct_store_postal_list() Failed(%d)",ret);
-               break;
-       case CTS_CF_WEB_ADDR_LIST:
-               ret = cts_struct_store_web_list((contact_t *)contact, list);
-               retvm_if(CTS_SUCCESS != ret, ret, "cts_struct_store_web_list() Failed(%d)",ret);
-               break;
-       case CTS_CF_NICKNAME_LIST:
-               ret = cts_struct_store_nickname_list((contact_t *)contact, list);
-               retvm_if(CTS_SUCCESS != ret, ret, "cts_struct_store_nickname_list() Failed(%d)",ret);
-               break;
-       default:
-               ERR("The parameter(field) is invalid"
-                               "You MUST be (CTS_CF_VALUE_MAX < field < CTS_CF_FIELD_MAX).");
-               return CTS_ERR_ARG_INVALID;
-       }
-       return CTS_SUCCESS;
-}
-
-static inline void cts_contact_store_name(contact_t *contact, cts_name *value)
-{
-       if (contact->name) {
-               if (value->is_changed) {
-                       FREEandSTRDUP(contact->name->first, value->first);
-                       FREEandSTRDUP(contact->name->last, value->last);
-                       FREEandSTRDUP(contact->name->addition, value->addition);
-                       FREEandSTRDUP(contact->name->display, value->display);
-                       FREEandSTRDUP(contact->name->prefix, value->prefix);
-                       FREEandSTRDUP(contact->name->suffix, value->suffix);
-                       contact->name->is_changed = true;
-               }
-       }
-       else {
-               //contact->name = (cts_name *)contacts_svc_value_new(CTS_VALUE_NAME);
-               contact->name = value;
-               contact->name->embedded = true;
-               contact->name->first = SAFE_STRDUP(value->first);
-               contact->name->last = SAFE_STRDUP(value->last);
-               contact->name->addition = SAFE_STRDUP(value->addition);
-               contact->name->display = SAFE_STRDUP(value->display);
-               contact->name->prefix = SAFE_STRDUP(value->prefix);
-               contact->name->suffix = SAFE_STRDUP(value->suffix);
-       }
-}
-
-static inline void cts_contact_store_base(contact_t *contact, cts_ct_base *value)
-{
-       if (contact->base) {
-               if (value->uid_changed) {
-                       FREEandSTRDUP(contact->base->uid, value->uid);
-                       contact->base->uid_changed = true;
-               }
-               if (value->img_changed) {
-                       FREEandSTRDUP(contact->base->img_path, value->img_path);
-                       contact->base->img_changed = true;
-               }
-               if (value->full_img_changed) {
-                       FREEandSTRDUP(contact->base->full_img_path, value->full_img_path);
-                       contact->base->full_img_changed = true;
-               }
-               if (value->ringtone_changed) {
-                       FREEandSTRDUP(contact->base->ringtone_path, value->ringtone_path);
-                       contact->base->ringtone_changed = true;
-               }
-               if (value->note_changed) {
-                       FREEandSTRDUP(contact->base->note, value->note);
-                       contact->base->note_changed = true;
-               }
-       }
-       else {
-               contact->base = value;
-               contact->base->embedded = true;
-               contact->base->uid = SAFE_STRDUP(value->uid);
-               contact->base->img_path = SAFE_STRDUP(value->img_path);
-               contact->base->full_img_path = SAFE_STRDUP(value->full_img_path);
-               contact->base->ringtone_path = SAFE_STRDUP(value->ringtone_path);
-               contact->base->note = SAFE_STRDUP(value->note);
-       }
-}
-
-static inline void cts_contact_store_company(contact_t *contact, cts_company *value)
-{
-       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 {
-               //contact->company = (cts_company *)contacts_svc_value_new(CTS_VALUE_COMPANY);
-               contact->company = value;
-               contact->company->embedded = true;
-               contact->company->name = SAFE_STRDUP(value->name);
-               contact->company->department = SAFE_STRDUP(value->department);
-               contact->company->jot_title = SAFE_STRDUP(value->jot_title);
-               contact->company->role = SAFE_STRDUP(value->role);
-               contact->company->assistant_name = SAFE_STRDUP(value->assistant_name);
-       }
-}
-
-static inline int cts_contact_store_extend(contact_t *contact,
-               int type, cts_extend *value)
-{
-       cts_extend *stored_extend;
-
-       stored_extend = cts_extend_slist_search(type, contact->extended_values);
-       if (NULL == stored_extend) {
-               retvm_if(value->embedded, CTS_ERR_ARG_INVALID, "This Value is already stored");
-               value->embedded = true;
-               value->type = type;
-               contact->extended_values = g_slist_append(contact->extended_values, value);
-               value->data2 = SAFE_STRDUP(value->data2);
-               value->data3 = SAFE_STRDUP(value->data3);
-               value->data4 = SAFE_STRDUP(value->data4);
-               value->data5 = SAFE_STRDUP(value->data5);
-               value->data6 = SAFE_STRDUP(value->data6);
-               value->data7 = SAFE_STRDUP(value->data7);
-               value->data8 = SAFE_STRDUP(value->data8);
-               value->data9 = SAFE_STRDUP(value->data9);
-               value->data10 = SAFE_STRDUP(value->data10);
-       }
-       else {
-               retvm_if(stored_extend == value, CTS_SUCCESS, "This value is already stored");
-
-               FREEandSTRDUP(stored_extend->data2, value->data2);
-               FREEandSTRDUP(stored_extend->data3, value->data3);
-               FREEandSTRDUP(stored_extend->data4, value->data4);
-               FREEandSTRDUP(stored_extend->data5, value->data5);
-               FREEandSTRDUP(stored_extend->data6, value->data6);
-               FREEandSTRDUP(stored_extend->data7, value->data7);
-               FREEandSTRDUP(stored_extend->data8, value->data8);
-               FREEandSTRDUP(stored_extend->data9, value->data9);
-               FREEandSTRDUP(stored_extend->data10, value->data10);
-       }
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_struct_store_value(CTSstruct *contact,
-               cts_struct_field field, CTSvalue *value)
-{
-       contact_t *record = (contact_t *)contact;
-
-       retv_if(NULL == contact, CTS_ERR_ARG_NULL);
-       retv_if(NULL == value, CTS_ERR_ARG_NULL);
-       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);
-       CTS_DBG("contact type = %d, field = %d, value type = %d",
-                       contact->s_type, field, value->v_type);
-
-       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).");
-               if (record->name != (cts_name *)value)
-                       cts_contact_store_name(record, (cts_name *)value);
-               break;
-       case CTS_CF_BASE_INFO_VALUE:
-               retvm_if(CTS_VALUE_CONTACT_BASE_INFO != value->v_type, CTS_ERR_ARG_INVALID,
-                               "The value must be a CTS_VALUE_CONTACT_BASE_INFO for field(CTS_CF_IMAGE_PATH_STR).");
-               if (record->base != (cts_ct_base *)value)
-                       cts_contact_store_base(record, (cts_ct_base*)value);
-               break;
-       case CTS_CF_COMPANY_VALUE:
-               retvm_if(CTS_VALUE_COMPANY != value->v_type, CTS_ERR_ARG_INVALID,
-                               "The value must be a CTS_VALUE_COMPANY for field(CTS_CF_COMPANY_VALUE).");
-               if (record->company != (cts_company *)value)
-                       cts_contact_store_company(record, (cts_company*)value);
-               break;
-       default:
-               if (CTS_VALUE_EXTEND == value->v_type && (int)CTS_DATA_EXTEND_START <= field)
-                       return cts_contact_store_extend(record, field, (cts_extend*)value);
-               ERR("The parameter(field:%d) is invalid"
-                               "You MUST be (CTS_CF_NONE < field < CTS_CF_VALUE_MAX).", field);
-               return CTS_ERR_ARG_INVALID;
-       }
-
-       return CTS_SUCCESS;
-}
-
-API CTSvalue* contacts_svc_value_new(cts_value_type type)
-{
-       CTSvalue* ret_val;
-       switch ((int)type) {
-       case CTS_VALUE_BASIC:
-               ret_val = (CTSvalue*)calloc(1, sizeof(cts_basic));
-               break;
-       case CTS_VALUE_CONTACT_BASE_INFO:
-               ret_val = (CTSvalue*)calloc(1, sizeof(cts_ct_base));
-               break;
-       case CTS_VALUE_NAME:
-               ret_val = (CTSvalue*)calloc(1, sizeof(cts_name));
-               break;
-       case CTS_VALUE_EMAIL:
-               ret_val = (CTSvalue*)calloc(1, sizeof(cts_email));
-               break;
-       case CTS_VALUE_NUMBER:
-               ret_val = (CTSvalue*)calloc(1, sizeof(cts_number));
-               break;
-       case CTS_VALUE_WEB:
-               ret_val = (CTSvalue*)calloc(1, sizeof(cts_web));
-               break;
-       case CTS_VALUE_POSTAL:
-               ret_val = (CTSvalue*)calloc(1, sizeof(cts_postal));
-               break;
-       case CTS_VALUE_EVENT:
-               ret_val = (CTSvalue*)calloc(1, sizeof(cts_event));
-               break;
-       case CTS_VALUE_MESSENGER:
-               ret_val = (CTSvalue*)calloc(1, sizeof(cts_messenger));
-               if (ret_val) ret_val->v_type = CTS_VALUE_MESSENGER;
-               break;
-       case CTS_VALUE_NICKNAME:
-               ret_val = (CTSvalue*)calloc(1, sizeof(cts_nickname));
-               break;
-       case CTS_VALUE_GROUP_RELATION:
-       case CTS_VALUE_GROUP:
-               ret_val = (CTSvalue*)calloc(1, sizeof(cts_group));
-               break;
-       case CTS_VALUE_COMPANY:
-               ret_val = (CTSvalue*)calloc(1, sizeof(cts_company));
-               break;
-       case CTS_VALUE_PHONELOG:
-               ret_val = (CTSvalue*)calloc(1, sizeof(cts_plog));
-               break;
-       case CTS_VALUE_EXTEND:
-               ret_val = (CTSvalue*)calloc(1, sizeof(cts_extend));
-               break;
-       case CTS_VALUE_ADDRESSBOOK:
-               ret_val = (CTSvalue*)calloc(1, sizeof(cts_addrbook));
-               break;
-       case CTS_VALUE_LIST_CONTACT:
-               if (contact_list_mempool) {
-                       memset(contact_list_mempool, 0x00, sizeof(contact_list));
-                       ret_val = (CTSvalue*)contact_list_mempool;
-                       contact_list_mempool = NULL;
-               }
-               else
-                       ret_val = (CTSvalue*)calloc(1, sizeof(contact_list));
-               break;
-       case CTS_VALUE_LIST_PLOG:
-               if (plog_list_mempool) {
-                       memset(plog_list_mempool, 0x00, sizeof(plog_list));
-                       ret_val = (CTSvalue*)plog_list_mempool;
-                       plog_list_mempool = NULL;
-               }
-               else
-                       ret_val = (CTSvalue*)calloc(1, sizeof(plog_list));
-               break;
-       case CTS_VALUE_LIST_CUSTOM_NUM_TYPE:
-               if (numtype_list_mempool) {
-                       memset(numtype_list_mempool, 0x00, sizeof(numtype_list));
-                       ret_val = (CTSvalue*)numtype_list_mempool;
-                       numtype_list_mempool = NULL;
-               }
-               else
-                       ret_val = (CTSvalue*)calloc(1, sizeof(numtype_list));
-               break;
-       case CTS_VALUE_LIST_CHANGE:
-               if (change_list_mempool) {
-                       memset(change_list_mempool, 0x00, sizeof(change_list));
-                       ret_val = (CTSvalue*)change_list_mempool;
-                       change_list_mempool = NULL;
-               }
-               else
-                       ret_val = (CTSvalue*)calloc(1, sizeof(change_list));
-               break;
-       case CTS_VALUE_LIST_ADDRBOOK:
-               if (addrbook_list_mempool) {
-                       memset(addrbook_list_mempool, 0x00, sizeof(cts_addrbook));
-                       ret_val = (CTSvalue*)addrbook_list_mempool;
-                       addrbook_list_mempool = NULL;
-               }
-               else
-                       ret_val = (CTSvalue*)calloc(1, sizeof(cts_addrbook));
-               break;
-       case CTS_VALUE_LIST_GROUP:
-               if (group_list_mempool) {
-                       memset(group_list_mempool, 0x00, sizeof(cts_group));
-                       ret_val = (CTSvalue*)group_list_mempool;
-                       group_list_mempool = NULL;
-               }
-               else
-                       ret_val = (CTSvalue*)calloc(1, sizeof(cts_group));
-               break;
-       case CTS_VALUE_LIST_SHORTCUT:
-               if (favorite_list_mempool) {
-                       memset(favorite_list_mempool, 0x00, sizeof(shortcut_list));
-                       ret_val = (CTSvalue*)favorite_list_mempool;
-                       favorite_list_mempool = NULL;
-               }
-               else
-                       ret_val = (CTSvalue*)calloc(1, sizeof(shortcut_list));
-               break;
-       case CTS_VALUE_LIST_SDN:
-               if (sdn_list_mempool) {
-                       memset(sdn_list_mempool, 0x00, sizeof(sdn_list));
-                       ret_val = (CTSvalue*)sdn_list_mempool;
-                       sdn_list_mempool = NULL;
-               }
-               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;
-       }
-
-       if (ret_val)
-               ret_val->v_type = type;
-       else
-               ERR("calloc() Failed(%d)", errno);
-
-       return ret_val;
-}
-
-static inline void cts_internal_value_info_free(CTSvalue *value)
-{
-       plog_list *plog;
-       cts_plog *log;
-       numtype_list *numtype;
-       contact_list *contact;
-       change_list *change;
-       shortcut_list *favorite;
-       cts_group *group;
-       cts_addrbook *ab;
-       sdn_list *sdn;
-       osp_list *osp;
-
-       switch (value->v_type) {
-       case CTS_VALUE_LIST_CONTACT:
-       case CTS_VALUE_LIST_NUMBERINFO:
-       case CTS_VALUE_LIST_EMAILINFO:
-               contact = (contact_list *)value;
-               free(contact->img_path);
-               free(contact->first);
-               free(contact->last);
-               free(contact->display);
-               free(contact->connect);
-               free(contact->normalize);
-
-               if (!contact_list_mempool) {
-                       contact_list_mempool = contact;
-               }
-               else
-                       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);
-               free(plog->last);
-               free(plog->display);
-               free(plog->img_path);
-
-               if (!plog_list_mempool) {
-                       plog_list_mempool = plog;
-               }
-               else
-                       if (plog_list_mempool != plog)
-                               free(plog);
-               break;
-       case CTS_VALUE_LIST_CUSTOM_NUM_TYPE:
-               numtype = (numtype_list *)value;
-               free(numtype->name);
-               if (!numtype_list_mempool) {
-                       numtype_list_mempool = numtype;
-               }
-               else
-                       if (numtype_list_mempool != numtype)
-                               free(numtype);
-               break;
-       case CTS_VALUE_LIST_CHANGE:
-               change = (change_list *)value;
-               if (!change_list_mempool) {
-                       change_list_mempool = change;
-               }
-               else
-                       if (change_list_mempool != change)
-                               free(change);
-               break;
-       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;
-               }
-               else
-                       if (group_list_mempool != group)
-                               free(group);
-               break;
-       case CTS_VALUE_LIST_ADDRBOOK:
-               ab = (cts_addrbook *)value;
-               free(ab->name);
-
-               if (!addrbook_list_mempool) {
-                       addrbook_list_mempool = ab;
-               }
-               else
-                       if (addrbook_list_mempool != ab)
-                               free(ab);
-               break;
-       case CTS_VALUE_LIST_SHORTCUT:
-               favorite = (shortcut_list *)value;
-               free(favorite->first);
-               free(favorite->last);
-               free(favorite->display);
-               free(favorite->number);
-               free(favorite->img_path);
-
-               if (!favorite_list_mempool) {
-                       favorite_list_mempool = favorite;
-               }
-               else
-                       if (favorite_list_mempool != favorite)
-                               free(favorite);
-               break;
-       case CTS_VALUE_LIST_SDN:
-               sdn = (sdn_list *)value;
-               free(sdn->name);
-               free(sdn->number);
-
-               if (!sdn_list_mempool) {
-                       sdn_list_mempool = sdn;
-               }
-               else
-                       if (sdn_list_mempool != sdn)
-                               free(sdn);
-               break;
-       case CTS_VALUE_RDONLY_NAME:
-               cts_name_free((cts_name *)value);
-               break;
-       case CTS_VALUE_RDONLY_NUMBER:
-               cts_number_free(value, NULL);
-               break;
-       case CTS_VALUE_RDONLY_EMAIL:
-               cts_email_free(value, NULL);
-               break;
-       case CTS_VALUE_RDONLY_COMPANY:
-               cts_company_free((cts_company *)value);
-               break;
-       case CTS_VALUE_RDONLY_PLOG:
-               log = (cts_plog *)value;
-               free(log->number);
-               free(log->extra_data2);
-               free(log);
-               break;
-       default:
-               ERR("The type of value is unknown type(%d)", value->v_type);
-               return;
-       }
-}
-
-API int contacts_svc_value_free(CTSvalue *value)
-{
-       retv_if(NULL == value, CTS_ERR_ARG_NULL);
-
-       if (CTS_VALUE_LIST_CONTACT <= value->v_type)
-               cts_internal_value_info_free(value);
-       else {
-               switch (value->v_type) {
-               case CTS_VALUE_GROUP:
-                       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:
-                       if (value->embedded) {
-                               free(((cts_addrbook *)value)->name);
-                       }
-                       break;
-               default:
-                       if (value->embedded) {
-                               DBG("This is the value of struct. It is really freed with the struct.");
-                               return CTS_SUCCESS;
-                       }
-                       break;
-               }
-               free(value);
-       }
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_value_get_type(CTSvalue *value)
-{
-       retv_if(NULL == value, CTS_ERR_ARG_NULL);
-
-       return value->v_type;
-}
-
-static inline int cts_value_get_int_base(cts_ct_base *value, int field)
-{
-       int ret = 0;
-
-       switch (field) {
-       case CTS_BASE_VAL_ID_INT:
-               ret = value->id;
-               break;
-       case CTS_BASE_VAL_CHANGED_TIME_INT:
-               ret = value->changed_time;
-               break;
-       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;
-       }
-       return ret;
-}
-
-static inline int cts_value_get_int_plog_list(plog_list *value, int field)
-{
-       int ret = 0;
-
-       switch (field) {
-       case CTS_LIST_PLOG_ID_INT:
-               ret = value->id;
-               break;
-       case CTS_LIST_PLOG_RELATED_ID_INT:
-               ret = value->related_id;
-               break;
-       case CTS_LIST_PLOG_NUM_TYPE_INT:
-               ret = value->num_type;
-               break;
-       case CTS_LIST_PLOG_LOG_TIME_INT:
-               ret = value->log_time;
-               break;
-       case CTS_LIST_PLOG_LOG_TYPE_INT:
-               ret = value->log_type;
-               break;
-       case CTS_LIST_PLOG_DURATION_INT:
-       case CTS_LIST_PLOG_MSGID_INT:
-               ret = value->extra_data1;
-               break;
-       default:
-               ERR("The field(%d) is not supported in value(plog list)", field);
-               break;
-       }
-       return ret;
-}
-
-static inline int cts_value_get_int_plog(cts_plog *value, int field)
-{
-       int ret = 0;
-
-       switch (field) {
-       case CTS_PLOG_VAL_ID_INT:
-               ret = value->id;
-               break;
-       case CTS_PLOG_VAL_RELATED_ID_INT:
-               ret = value->related_id;
-               break;
-       case CTS_PLOG_VAL_LOG_TIME_INT:
-               ret = value->log_time;
-               break;
-       case CTS_PLOG_VAL_LOG_TYPE_INT:
-               ret = value->log_type;
-               break;
-       case CTS_PLOG_VAL_DURATION_INT:
-       case CTS_PLOG_VAL_MSGID_INT:
-               ret = value->extra_data1;
-               break;
-       default:
-               ERR("The field(%d) is not supported in value(plog)", field);
-               break;
-       }
-       return ret;
-}
-
-static inline int cts_value_get_int_change_list(change_list *value, int field)
-{
-       int ret = 0;
-
-       switch (field) {
-       case CTS_LIST_CHANGE_ID_INT:
-               ret = value->id;
-               break;
-       case CTS_LIST_CHANGE_TYPE_INT:
-               ret = value->changed_type;
-               break;
-       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;
-       }
-       return ret;
-}
-
-static inline int cts_value_get_int_shortcut_list(shortcut_list *value, int field)
-{
-       int ret = 0;
-
-       switch (field) {
-       case CTS_LIST_SHORTCUT_ID_INT:
-               ret = value->id;
-               break;
-       case CTS_LIST_SHORTCUT_CONTACT_ID_INT:
-               ret = value->contact_id;
-               break;
-       case CTS_LIST_SHORTCUT_NUMBER_TYPE_INT:
-               ret = value->num_type;
-               break;
-       case CTS_LIST_SHORTCUT_SPEEDDIAL_INT:
-               ret = value->speeddial;
-               break;
-       default:
-               ERR("The field(%d) is not supported in value(shorcut list)", field);
-               break;
-       }
-       return ret;
-}
-
-static inline int cts_value_get_int_addrbook(cts_addrbook *value, int field)
-{
-       int ret = 0;
-
-       switch (field) {
-       case CTS_ADDRESSBOOK_VAL_ID_INT:
-               ret = value->id;
-               break;
-       case CTS_ADDRESSBOOK_VAL_ACC_ID_INT:
-               ret = value->acc_id;
-               break;
-       case CTS_ADDRESSBOOK_VAL_ACC_TYPE_INT:
-               ret = value->acc_type;
-               break;
-       case CTS_ADDRESSBOOK_VAL_MODE_INT:
-               ret = value->mode;
-               break;
-       default:
-               ERR("The field(%d) is not supported in value(addressbook)", field);
-               break;
-       }
-       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) {
-       case CTS_VALUE_BASIC:
-               retvm_if(CTS_BASIC_VAL_INT != ((cts_basic*)value)->type, 0,
-                               "The type of Basic_value is not integer");
-               ret = ((cts_basic*)value)->val.i;
-               break;
-       case CTS_VALUE_CONTACT_BASE_INFO:
-               ret = cts_value_get_int_base((cts_ct_base *)value, field);
-               break;
-       case CTS_VALUE_EXTEND:
-               if (CTS_EXTEND_VAL_DATA1_INT == field)
-                       ret = ((cts_extend*)value)->data1;
-               else
-                       ERR("The field(%d) is not supported in value(Extend)", field);
-               break;
-       case CTS_VALUE_RDONLY_NUMBER:
-       case CTS_VALUE_NUMBER:
-               if (CTS_NUM_VAL_ID_INT == field)
-                       ret = ((cts_number*)value)->id;
-               else if (CTS_NUM_VAL_TYPE_INT == field)
-                       ret = ((cts_number*)value)->type;
-               else
-                       ERR("The field(%d) is not supported in value(Number)", field);
-               break;
-       case CTS_VALUE_RDONLY_EMAIL:
-       case CTS_VALUE_EMAIL:
-               if (CTS_EMAIL_VAL_ID_INT == field)
-                       ret = ((cts_email*)value)->id;
-               else if (CTS_EMAIL_VAL_TYPE_INT == field)
-                       ret = ((cts_email*)value)->type;
-               else
-                       ERR("The field(%d) is not supported in value(Email)", field);
-               break;
-       case CTS_VALUE_LIST_PLOG:
-               ret = cts_value_get_int_plog_list((plog_list *)value, field);
-               break;
-       case CTS_VALUE_RDONLY_PLOG:
-               ret = cts_value_get_int_plog((cts_plog *)value, field);
-               break;
-       case CTS_VALUE_LIST_CONTACT:
-       case CTS_VALUE_LIST_NUMS_EMAILS:
-               if (CTS_LIST_CONTACT_ID_INT == field)
-                       ret = ((contact_list *)value)->contact_id;
-               else if (CTS_LIST_CONTACT_ADDRESSBOOK_ID_INT == field)
-                       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;
-       case CTS_VALUE_ADDRESSBOOK:
-       case CTS_VALUE_LIST_ADDRBOOK:
-               ret = cts_value_get_int_addrbook((cts_addrbook *)value, 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
-               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)
-                       ret = ((numtype_list*)value)->id;
-               else
-                       ERR("Not supported field(%d)", field);
-               break;
-       case CTS_VALUE_LIST_GROUP:
-               if (CTS_LIST_GROUP_ID_INT == field)
-                       ret = ((cts_group *)value)->id;
-               else if (CTS_LIST_GROUP_ADDRESSBOOK_ID_INT == field)
-                       ret = ((cts_group *)value)->addrbook_id;
-               else
-                       ERR("Not supported field(%d)", field);
-               break;
-       case CTS_VALUE_LIST_CHANGE:
-               ret = cts_value_get_int_change_list((change_list *)value, field);
-               break;
-       case CTS_VALUE_LIST_SHORTCUT:
-               ret = cts_value_get_int_shortcut_list((shortcut_list *)value, field);
-               break;
-       case CTS_VALUE_MESSENGER:
-               if (CTS_MESSENGER_VAL_TYPE_INT == field)
-                       ret = ((cts_messenger*)value)->type;
-               else
-                       ERR("Not supported field(%d)", field);
-               break;
-       case CTS_VALUE_GROUP_RELATION:
-               if (CTS_GROUPREL_VAL_ID_INT == field)
-                       ret = ((cts_group*)value)->id;
-               else
-                       ERR("Not supported field(%d)", field);
-               break;
-       case CTS_VALUE_GROUP:
-               if (CTS_GROUP_VAL_ID_INT == field)
-                       ret = ((cts_group*)value)->id;
-               if (CTS_GROUP_VAL_ADDRESSBOOK_ID_INT == field)
-                       ret = ((cts_group*)value)->addrbook_id;
-               else
-                       ERR("Not supported field(%d)", field);
-               break;
-       case CTS_VALUE_WEB:
-               if (CTS_WEB_VAL_TYPE_INT == field)
-                       ret = ((cts_web*)value)->type;
-               else
-                       ERR("Not supported field(%d)", field);
-               break;
-       case CTS_VALUE_POSTAL:
-               if (CTS_POSTAL_VAL_TYPE_INT == field)
-                       ret = ((cts_postal*)value)->type;
-               else
-                       ERR("Not supported field(%d)", field);
-               break;
-       case CTS_VALUE_EVENT:
-               if (CTS_EVENT_VAL_TYPE_INT == field)
-                       ret = ((cts_event *)value)->type;
-               else if (CTS_EVENT_VAL_DATE_INT == field)
-                       ret = ((cts_event *)value)->date;
-               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:
-               /* company value doesn't have interger value */
-       case CTS_VALUE_NAME:
-               /* name value doesn't have interger value */
-       default:
-               ERR("The value has unsupported type(%d)", value->v_type);
-               break;
-       }
-       return ret;
-}
-
-double contacts_svc_value_get_dbl(CTSvalue *value, int field)
-{
-       retv_if(NULL == value, CTS_ERR_ARG_NULL);
-
-       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");
-               return ((cts_basic*)value)->val.d;
-       case CTS_VALUE_NAME:
-       case CTS_VALUE_EMAIL:
-       case CTS_VALUE_NUMBER:
-       case CTS_VALUE_WEB:
-       case CTS_VALUE_POSTAL:
-       case CTS_VALUE_EVENT:
-       case CTS_VALUE_MESSENGER:
-       case CTS_VALUE_GROUP_RELATION:
-       case CTS_VALUE_COMPANY:
-       default:
-               ERR("The value has unsupported type(%d)", value->v_type);
-               return CTS_ERR_ARG_INVALID;
-       }
-
-}
-
-API bool contacts_svc_value_get_bool(CTSvalue *value, int field)
-{
-       retv_if(NULL == value, false);
-
-       switch (value->v_type) {
-       case CTS_VALUE_CONTACT_BASE_INFO:
-               if (CTS_BASE_VAL_FAVORITE_BOOL == field) {
-                       return ((cts_ct_base*)value)->is_favorite;
-               }
-               else {
-                       ERR("The field(%d) is not supported in value(BASE_INFO)", field);
-                       return false;
-               }
-       case CTS_VALUE_RDONLY_NUMBER:
-       case CTS_VALUE_NUMBER:
-               if (CTS_NUM_VAL_DEFAULT_BOOL == field) {
-                       return ((cts_number*)value)->is_default;
-               }
-               else if (CTS_NUM_VAL_DELETE_BOOL == field) {
-                       return value->deleted;
-               }
-               else if (CTS_NUM_VAL_FAVORITE_BOOL == field) {
-                       return ((cts_number*)value)->is_favorite;
-               }
-               else {
-                       ERR("The field(%d) is not supported in value(Number)", field);
-                       return false;
-               }
-       case CTS_VALUE_RDONLY_EMAIL:
-       case CTS_VALUE_EMAIL:
-               if (CTS_EMAIL_VAL_DEFAULT_BOOL == field) {
-                       return ((cts_email*)value)->is_default;
-               }
-               else if (CTS_EMAIL_VAL_DELETE_BOOL == field) {
-                       return value->deleted;
-               }
-               else {
-                       ERR("The field(%d) is not supported in value(Email)", field);
-                       return false;
-               }
-       case CTS_VALUE_GROUP_RELATION:
-               if (CTS_GROUPREL_VAL_DELETE_BOOL == field) {
-                       return value->deleted;
-               }
-               else {
-                       ERR("The field(%d) is not supported in value(Group)", field);
-                       return false;
-               }
-       case CTS_VALUE_EVENT:
-               if (CTS_EVENT_VAL_DELETE_BOOL == field) {
-                       return value->deleted;
-               }
-               else {
-                       ERR("The field(%d) is not supported in value(Event)", field);
-                       return false;
-               }
-       case CTS_VALUE_MESSENGER:
-               if (CTS_MESSENGER_VAL_DELETE_BOOL == field) {
-                       return value->deleted;
-               }
-               else {
-                       ERR("The field(%d) is not supported in value(Messenger)", field);
-                       return false;
-               }
-       case CTS_VALUE_POSTAL:
-               if (CTS_POSTAL_VAL_DELETE_BOOL == field) {
-                       return value->deleted;
-               }
-               else if (CTS_POSTAL_VAL_DEFAULT_BOOL == field) {
-                       return ((cts_postal*)value)->is_default;;
-               }
-               else {
-                       ERR("The field(%d) is not supported in value(Postal)", field);
-                       return false;
-               }
-       case CTS_VALUE_WEB:
-               if (CTS_WEB_VAL_DELETE_BOOL == field) {
-                       return value->deleted;
-               }
-               else {
-                       ERR("The field(%d) is not supported in value(Web)", field);
-                       return false;
-               }
-       case CTS_VALUE_NICKNAME:
-               if (CTS_NICKNAME_VAL_DELETE_BOOL == field) {
-                       return value->deleted;
-               }
-               else {
-                       ERR("The field(%d) is not supported in value(Web)", field);
-                       return false;
-               }
-       case CTS_VALUE_EXTEND:
-               if (CTS_EXTEND_VAL_DELETE_BOOL == field) {
-                       return value->deleted;
-               }
-               else {
-                       ERR("The field(%d) is not supported in value(Extend)", field);
-                       return false;
-               }
-       case CTS_VALUE_BASIC:
-               retvm_if(CTS_BASIC_VAL_BOOL != ((cts_basic*)value)->type, false,
-                               "The type of value is not boolean");
-               return ((cts_basic*)value)->val.b;
-       case CTS_VALUE_PHONELOG:
-               /* phonelog value is write only */
-       case CTS_VALUE_LIST_CONTACT:
-               /* contact list value doesn't have boolean value */
-       case CTS_VALUE_LIST_PLOG:
-               /* plog list value doesn't have boolean value */
-       case CTS_VALUE_LIST_CUSTOM_NUM_TYPE:
-               /* custom number type list value doesn't have boolean value */
-       case CTS_VALUE_LIST_CHANGE:
-               /* Change list value doesn't have boolean value */
-       case CTS_VALUE_NAME:
-               /* name value doesn't have boolean value */
-       case CTS_VALUE_COMPANY:
-               /* company value doesn't have boolean value */
-       default:
-               ERR("The value has unsupported type(%d)", value->v_type);
-               return false;
-       }
-}
-
-static inline char* cts_value_get_str_name(int op_code,
-               cts_name *value, int field)
-{
-       char *ret_val;
-
-       switch (field) {
-       case CTS_NAME_VAL_FIRST_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->first);
-               break;
-       case CTS_NAME_VAL_LAST_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->last);
-               break;
-       case CTS_NAME_VAL_DISPLAY_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->display);
-               break;
-       case CTS_NAME_VAL_ADDITION_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->addition);
-               break;
-       case CTS_NAME_VAL_PREFIX_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->prefix);
-               break;
-       case CTS_NAME_VAL_SUFFIX_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->suffix);
-               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_extend(int op_code,
-               cts_extend *value, int field)
-{
-       char *ret_val;
-
-       switch (field) {
-       case CTS_EXTEND_VAL_DATA2_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->data2);
-               break;
-       case CTS_EXTEND_VAL_DATA3_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->data3);
-               break;
-       case CTS_EXTEND_VAL_DATA4_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->data4);
-               break;
-       case CTS_EXTEND_VAL_DATA5_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->data5);
-               break;
-       case CTS_EXTEND_VAL_DATA6_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->data6);
-               break;
-       case CTS_EXTEND_VAL_DATA7_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->data7);
-               break;
-       case CTS_EXTEND_VAL_DATA8_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->data8);
-               break;
-       case CTS_EXTEND_VAL_DATA9_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->data9);
-               break;
-       case CTS_EXTEND_VAL_DATA10_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->data10);
-               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_base(int op_code,
-               cts_ct_base *value, int field)
-{
-       char *ret_val;
-
-       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) {
-                       if (CTS_HANDLE_STR_STEAL == op_code)
-                               ret_val = strdup(value->vcard_img_path);
-                       else
-                               ret_val = value->vcard_img_path;
-               }
-               break;
-       case CTS_BASE_VAL_RINGTONE_PATH_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->ringtone_path);
-               break;
-       case CTS_BASE_VAL_NOTE_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->note);
-               break;
-       case CTS_BASE_VAL_UID_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->uid);
-               break;
-       case CTS_BASE_VAL_FULL_IMG_PATH_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->full_img_path);
-               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_contact_list(int op_code,
-               contact_list *value, int field)
-{
-       char *ret_val;
-       switch (field) {
-       case CTS_LIST_CONTACT_FIRST_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->first);
-               break;
-       case CTS_LIST_CONTACT_LAST_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->last);
-               break;
-       case CTS_LIST_CONTACT_DISPLAY_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->display);
-               break;
-       case CTS_LIST_CONTACT_IMG_PATH_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->img_path);
-               break;
-       case CTS_LIST_CONTACT_NUM_OR_EMAIL_STR:
-               if (CTS_VALUE_LIST_NUMS_EMAILS == value->v_type) {
-                       HANDLE_STEAL_STRING(op_code, ret_val, value->connect);
-               } else {
-                       ERR("The parameter(field:%d, value type = %d) is not interpreted",
-                               field, value->v_type);
-                       ret_val = NULL;
-               }
-               break;
-       case CTS_LIST_CONTACT_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_num_email_list(int op_code,
-               contact_list *value, int field)
-{
-       char *ret_val;
-       switch (field) {
-       case CTS_LIST_NUM_CONTACT_FIRST_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->first);
-               break;
-       case CTS_LIST_NUM_CONTACT_LAST_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->last);
-               break;
-       case CTS_LIST_NUM_CONTACT_DISPLAY_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->display);
-               break;
-       case CTS_LIST_NUM_CONTACT_IMG_PATH_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->img_path);
-               break;
-       case CTS_LIST_NUM_NUMBER_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->connect);
-               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_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) {
-       case CTS_LIST_SHORTCUT_FIRST_NAME_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->first);
-               break;
-       case CTS_LIST_SHORTCUT_LAST_NAME_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->last);
-               break;
-       case CTS_LIST_SHORTCUT_DISPLAY_NAME_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->display);
-               break;
-       case CTS_LIST_SHORTCUT_IMG_PATH_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->img_path);
-               break;
-       case CTS_LIST_SHORTCUT_NUMBER_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->number);
-               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_plog_list(int op_code,
-               plog_list *value, int field)
-{
-       char *ret_val;
-       switch (field) {
-       case CTS_LIST_PLOG_FIRST_NAME_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->first);
-               break;
-       case CTS_LIST_PLOG_LAST_NAME_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->last);
-               break;
-       case CTS_LIST_PLOG_DISPLAY_NAME_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->display);
-               break;
-       case CTS_LIST_PLOG_NUMBER_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->number);
-               break;
-       case CTS_LIST_PLOG_IMG_PATH_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->img_path);
-               break;
-       case CTS_LIST_PLOG_SHORTMSG_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->extra_data2);
-               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_postal(int op_code,
-               cts_postal *value, int field)
-{
-       char *ret_val;
-       switch (field) {
-       case CTS_POSTAL_VAL_POBOX_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->pobox);
-               break;
-       case CTS_POSTAL_VAL_POSTALCODE_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->postalcode);
-               break;
-       case CTS_POSTAL_VAL_REGION_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->region);
-               break;
-       case CTS_POSTAL_VAL_LOCALITY_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->locality);
-               break;
-       case CTS_POSTAL_VAL_STREET_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->street);
-               break;
-       case CTS_POSTAL_VAL_EXTENDED_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->extended);
-               break;
-       case CTS_POSTAL_VAL_COUNTRY_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->country);
-               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_company(int op_code,
-               cts_company *value, int field)
-{
-       char *ret_val;
-       switch (field) {
-       case CTS_COMPANY_VAL_NAME_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->name);
-               break;
-       case CTS_COMPANY_VAL_DEPARTMENT_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->department);
-               break;
-       case CTS_COMPANY_VAL_JOB_TITLE_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->jot_title);
-               break;
-       case CTS_COMPANY_VAL_ROLE_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->role);
-               break;
-       case CTS_COMPANY_VAL_ASSISTANT_NAME_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->assistant_name);
-               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_im(int op_code,
-               cts_messenger *value, int field)
-{
-       char *ret_val;
-       switch (field) {
-       case CTS_MESSENGER_VAL_IM_ID_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->im_id);
-               break;
-       case CTS_MESSENGER_VAL_SERVICE_NAME_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->svc_name);
-               break;
-       case CTS_MESSENGER_VAL_SERVICE_OP_STR:
-               HANDLE_STEAL_STRING(op_code, ret_val, value->svc_op);
-               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_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) {
-       case CTS_VALUE_BASIC:
-               retvm_if(CTS_BASIC_VAL_STR != ((cts_basic *)value)->type, NULL,
-                               "The type of value is not string");
-               HANDLE_STEAL_STRING(op_code, ret_val, ((cts_basic *)value)->val.s);
-               break;
-       case CTS_VALUE_CONTACT_BASE_INFO:
-               ret_val = cts_value_get_str_base(op_code, (cts_ct_base *)value, field);
-               break;
-       case CTS_VALUE_POSTAL:
-               ret_val = cts_value_get_str_postal(op_code, (cts_postal *)value, field);
-               break;
-       case CTS_VALUE_COMPANY:
-       case CTS_VALUE_RDONLY_COMPANY:
-               ret_val = cts_value_get_str_company(op_code, (cts_company *)value, field);
-               break;
-       case CTS_VALUE_NAME:
-       case CTS_VALUE_RDONLY_NAME:
-               ret_val = cts_value_get_str_name(op_code, (cts_name *)value, field);
-               break;
-       case CTS_VALUE_EXTEND:
-               ret_val = cts_value_get_str_extend(op_code, (cts_extend *)value, field);
-               break;
-       case CTS_VALUE_LIST_CONTACT:
-       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);
-               break;
-       case CTS_VALUE_LIST_SHORTCUT:
-               ret_val = cts_value_get_str_favorite_list(op_code, (shortcut_list *)value, field);
-               break;
-       case CTS_VALUE_LIST_PLOG:
-               ret_val = cts_value_get_str_plog_list(op_code, (plog_list *)value, field);
-               break;
-       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_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);
-               } else {
-                       ERR("Not supported field");
-                       return NULL;
-               }
-               break;
-       case CTS_VALUE_NUMBER:
-       case CTS_VALUE_RDONLY_NUMBER:
-               retvm_if(CTS_NUM_VAL_NUMBER_STR != field, NULL,
-                               "This field(%d) is not supported in value(Number)", field);
-               HANDLE_STEAL_STRING(op_code, ret_val, ((cts_number *)value)->number);
-               break;
-       case CTS_VALUE_EMAIL:
-       case CTS_VALUE_RDONLY_EMAIL:
-               retvm_if(CTS_EMAIL_VAL_ADDR_STR != field, NULL,
-                               "This field(%d) is not supported in value(Email)", field);
-               HANDLE_STEAL_STRING(op_code, ret_val, ((cts_email *)value)->email_addr);
-               break;
-       case CTS_VALUE_ADDRESSBOOK:
-       case CTS_VALUE_LIST_ADDRBOOK:
-               retvm_if(CTS_ADDRESSBOOK_VAL_NAME_STR != field, NULL,
-                               "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_WEB:
-               if (CTS_WEB_VAL_ADDR_STR == field) {
-                       HANDLE_STEAL_STRING(op_code, ret_val, ((cts_web *)value)->url);
-               }
-               else {
-                       ERR("Not supported field(%d)", field);
-                       ret_val = NULL;
-               }
-               break;
-       case CTS_VALUE_NICKNAME:
-               if (CTS_NICKNAME_VAL_NAME_STR == field) {
-                       HANDLE_STEAL_STRING(op_code, ret_val, ((cts_nickname *)value)->nick);
-               }
-               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);
-               } else {
-                       ERR("Not supported field(%d)", field);
-                       ret_val = NULL;
-               }
-               break;
-       case CTS_VALUE_LIST_SDN:
-               if (CTS_LIST_SDN_NAME_STR == field) {
-                       HANDLE_STEAL_STRING(op_code, ret_val, ((sdn_list *)value)->name);
-               }
-               else if (CTS_LIST_SDN_NUMBER_STR == field) {
-                       HANDLE_STEAL_STRING(op_code, ret_val, ((sdn_list *)value)->number);
-               }
-               else {
-                       ERR("Not supported field(%d)", field);
-                       ret_val = NULL;
-               }
-               break;
-       case CTS_VALUE_PHONELOG:
-               /* phonelog value is write only */
-       case CTS_VALUE_LIST_CHANGE:
-               /* Change list value doesn't have string value */
-       case CTS_VALUE_EVENT:
-               /* evet value doesn't have string value */
-       default:
-               ERR("The value has unsupported type(%d)", value->v_type);
-               ret_val = NULL;
-               break;
-       }
-       return ret_val;
-}
-
-API const char* contacts_svc_value_get_str(CTSvalue *value, int field)
-{
-       return cts_value_handle_str(CTS_HANDLE_STR_GET, value, field);
-}
-
-API char* contacts_svc_value_steal_str(CTSvalue *value, int field)
-{
-       return cts_value_handle_str(CTS_HANDLE_STR_STEAL, value, field);
-}
-
-static inline int cts_value_set_int_plog(cts_plog *value, int field, int intval)
-{
-       switch (field) {
-       case CTS_PLOG_VAL_LOG_TIME_INT:
-               value->log_time = intval;
-               break;
-       case CTS_PLOG_VAL_LOG_TYPE_INT:
-               value->log_type = intval;
-               break;
-       case CTS_PLOG_VAL_DURATION_INT:
-       case CTS_PLOG_VAL_MSGID_INT:
-               value->extra_data1 = intval;
-               break;
-       case CTS_PLOG_VAL_RELATED_ID_INT:
-               value->related_id = intval;
-               break;
-       default:
-               ERR("The field(%d) is not supported in value(plog)", field);
-               return CTS_ERR_ARG_INVALID;
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_value_set_int_addrbook(cts_addrbook *value,
-               int field, int intval)
-{
-       switch (field) {
-       case CTS_ADDRESSBOOK_VAL_ACC_ID_INT:
-               value->acc_id = intval;
-               break;
-       case CTS_ADDRESSBOOK_VAL_ACC_TYPE_INT:
-               value->acc_type = intval;
-               break;
-       case CTS_ADDRESSBOOK_VAL_MODE_INT:
-               value->mode = intval;
-               break;
-       default:
-               ERR("The field(%d) is not supported in value(addressbook)", field);
-               return CTS_ERR_ARG_INVALID;
-       }
-       return CTS_SUCCESS;
-}
-
-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) {
-       case CTS_VALUE_BASIC:
-               ((cts_basic*)value)->type = CTS_BASIC_VAL_INT;
-               ((cts_basic*)value)->val.i = intval;
-               break;
-       case CTS_VALUE_EXTEND:
-               retvm_if(CTS_EXTEND_VAL_DATA1_INT != field, CTS_ERR_ARG_INVALID,
-                               "Not supported field");
-               ((cts_extend *)value)->data1 = intval;
-               break;
-       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:
-               retvm_if(CTS_GROUPREL_VAL_ID_INT != field, CTS_ERR_ARG_INVALID,
-                               "Not supported field");
-               retvm_if(value->embedded, CTS_ERR_ARG_INVALID,
-                               "The field is only used for creating");
-               ((cts_group *)value)->id = intval;
-               break;
-       case CTS_VALUE_GROUP:
-               retvm_if(CTS_GROUP_VAL_ADDRESSBOOK_ID_INT != field, CTS_ERR_ARG_INVALID,
-                               "Not supported field");
-               retvm_if(!value->embedded, CTS_ERR_ARG_INVALID,
-                               "The field is only used for updating");
-               ((cts_group *)value)->addrbook_id = intval;
-               break;
-       case CTS_VALUE_MESSENGER:
-               retvm_if(CTS_MESSENGER_VAL_TYPE_INT != field, CTS_ERR_ARG_INVALID,
-                               "Not supported field");
-               ((cts_messenger *)value)->type = intval;
-               break;
-       case CTS_VALUE_WEB:
-               retvm_if(CTS_WEB_VAL_TYPE_INT != field, CTS_ERR_ARG_INVALID,
-                               "Not supported field");
-               ((cts_web *)value)->type = intval;
-               break;
-       case CTS_VALUE_EVENT:
-               if (CTS_EVENT_VAL_TYPE_INT == field)
-                       ((cts_event *)value)->type = intval;
-               else if (CTS_EVENT_VAL_DATE_INT == field)
-                       ((cts_event *)value)->date = intval;
-               else {
-                       ERR("Not supported field");
-                       return CTS_ERR_ARG_INVALID;
-               }
-               break;
-       case CTS_VALUE_POSTAL:
-               retvm_if(CTS_POSTAL_VAL_TYPE_INT != field, CTS_ERR_ARG_INVALID,
-                               "Not supported field");
-               ((cts_postal *)value)->type = intval;
-               break;
-       case CTS_VALUE_ADDRESSBOOK:
-               return cts_value_set_int_addrbook((cts_addrbook *)value, field, intval);
-       case CTS_VALUE_COMPANY:
-               /* company value doesn't have integer value */
-       case CTS_VALUE_NAME:
-               /* name value doesn't have integer value */
-       case CTS_VALUE_CONTACT_BASE_INFO:
-               /* base_info value doesn't have integer value for set */
-       default:
-               ERR("The value has unsupported type(%d)", value->v_type);
-               return CTS_ERR_ARG_INVALID;
-       }
-
-       return CTS_SUCCESS;
-}
-
-int contacts_svc_value_set_dbl(CTSvalue *value, int field, double dblval)
-{
-       retv_if(NULL == value, CTS_ERR_ARG_NULL);
-
-       switch (value->v_type) {
-       case CTS_VALUE_BASIC:
-               ((cts_basic*)value)->type = CTS_BASIC_VAL_DBL;
-               ((cts_basic*)value)->val.d = dblval;
-               break;
-       case CTS_VALUE_EMAIL:
-       case CTS_VALUE_NUMBER:
-       case CTS_VALUE_WEB:
-       case CTS_VALUE_POSTAL:
-       case CTS_VALUE_EVENT:
-       case CTS_VALUE_MESSENGER:
-       case CTS_VALUE_GROUP_RELATION:
-       case CTS_VALUE_COMPANY:
-       case CTS_VALUE_NAME:
-       case CTS_VALUE_CONTACT_BASE_INFO:
-       default:
-               ERR("The value has unsupported type(%d)", value->v_type);
-               return CTS_ERR_ARG_INVALID;
-       }
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_value_set_bool(CTSvalue *value,
-               int field, bool boolval)
-{
-       retv_if(NULL == value, CTS_ERR_ARG_NULL);
-
-       switch (value->v_type) {
-       case CTS_VALUE_CONTACT_BASE_INFO:
-               if (CTS_BASE_VAL_FAVORITE_BOOL == field)
-                       ((cts_ct_base*)value)->is_favorite = boolval;
-               else {
-                       ERR("The field(%d) is not supported in value(BASE_INFO)", field);
-                       return CTS_ERR_ARG_INVALID;
-               }
-               break;
-       case CTS_VALUE_NUMBER:
-               if (CTS_NUM_VAL_DEFAULT_BOOL == field)
-                       ((cts_number *)value)->is_default = boolval;
-               else if (CTS_NUM_VAL_FAVORITE_BOOL == field)
-                       ((cts_number *)value)->is_favorite = boolval;
-               else if (CTS_NUM_VAL_DELETE_BOOL == field) {
-                       retvm_if(false == value->embedded, CTS_ERR_ARG_INVALID,
-                                       "The field is only used for updating");
-                       value->deleted = boolval;
-               }
-               else {
-                       ERR("Not supported field");
-                       return CTS_ERR_ARG_INVALID;
-               }
-               break;
-       case CTS_VALUE_EMAIL:
-               if (CTS_EMAIL_VAL_DEFAULT_BOOL == field)
-                       ((cts_email *)value)->is_default = boolval;
-               else if (CTS_EMAIL_VAL_DELETE_BOOL == field) {
-                       retvm_if(false == value->embedded, CTS_ERR_ARG_INVALID,
-                                       "The field is only used for updating");
-                       value->deleted = boolval;
-               }
-               else {
-                       ERR("Not supported field");
-                       return CTS_ERR_ARG_INVALID;
-               }
-               break;
-       case CTS_VALUE_POSTAL:
-               if (CTS_POSTAL_VAL_DEFAULT_BOOL == field)
-                       ((cts_postal *)value)->is_default = boolval;
-               else if (CTS_POSTAL_VAL_DELETE_BOOL == field) {
-                       retvm_if(false == value->embedded, CTS_ERR_ARG_INVALID,
-                                       "The field is only used for updating");
-                       value->deleted = boolval;
-               }
-               else {
-                       ERR("Not supported field");
-                       return CTS_ERR_ARG_INVALID;
-               }
-               break;
-       case CTS_VALUE_GROUP_RELATION:
-               retvm_if(CTS_GROUPREL_VAL_DELETE_BOOL != field, CTS_ERR_ARG_INVALID,
-                               "Not supported field");
-               retvm_if(false == value->embedded, CTS_ERR_ARG_INVALID,
-                               "The field is only used for updating");
-               value->deleted = boolval;
-               break;
-       case CTS_VALUE_EVENT:
-               retvm_if(CTS_EVENT_VAL_DELETE_BOOL != field, CTS_ERR_ARG_INVALID,
-                               "Not supported field");
-               retvm_if(false == value->embedded, CTS_ERR_ARG_INVALID,
-                               "The field is only used for updating");
-               value->deleted = boolval;
-               break;
-       case CTS_VALUE_MESSENGER:
-               retvm_if(CTS_MESSENGER_VAL_DELETE_BOOL != field, CTS_ERR_ARG_INVALID,
-                               "Not supported field");
-               retvm_if(false == value->embedded, CTS_ERR_ARG_INVALID,
-                               "The field is only used for updating");
-               value->deleted = boolval;
-               break;
-       case CTS_VALUE_WEB:
-               retvm_if(CTS_WEB_VAL_DELETE_BOOL != field, CTS_ERR_ARG_INVALID,
-                               "Not supported field");
-               retvm_if(false == value->embedded, CTS_ERR_ARG_INVALID,
-                               "The field is only used for updating");
-               value->deleted = boolval;
-               break;
-       case CTS_VALUE_NICKNAME:
-               retvm_if(CTS_NICKNAME_VAL_DELETE_BOOL != field, CTS_ERR_ARG_INVALID,
-                               "Not supported field");
-               retvm_if(false == value->embedded, CTS_ERR_ARG_INVALID,
-                               "The field is only used for updating");
-               value->deleted = boolval;
-               break;
-       case CTS_VALUE_EXTEND:
-               retvm_if(CTS_EXTEND_VAL_DELETE_BOOL != field, CTS_ERR_ARG_INVALID,
-                               "Not supported field");
-               retvm_if(false == value->embedded, CTS_ERR_ARG_INVALID,
-                               "The field is only used for updating");
-               value->deleted = boolval;
-               break;
-       case CTS_VALUE_BASIC:
-               ((cts_basic*)value)->type = CTS_BASIC_VAL_BOOL;
-               ((cts_basic*)value)->val.b = boolval;
-               break;
-       case CTS_VALUE_COMPANY:
-               /* company value doesn't have boolean value */
-       case CTS_VALUE_NAME:
-               /* name value doesn't have boolean value */
-       default:
-               ERR("The value has unsupported type(%d)", value->v_type);
-               return CTS_ERR_ARG_INVALID;
-       }
-
-       return CTS_SUCCESS;
-}
-
-static inline int cts_value_set_str_base(cts_ct_base *base, int field, char *strval)
-{
-       switch (field) {
-       case CTS_BASE_VAL_IMG_PATH_STR:
-               if (base->embedded)
-                       FREEandSTRDUP(base->img_path, strval);
-               else
-                       base->img_path = strval;
-               base->img_changed = true;
-               break;
-       case CTS_BASE_VAL_RINGTONE_PATH_STR:
-               if (base->embedded)
-                       FREEandSTRDUP(base->ringtone_path, strval);
-               else
-                       base->ringtone_path = strval;
-               base->ringtone_changed = true;
-               break;
-       case CTS_BASE_VAL_NOTE_STR:
-               if (base->embedded)
-                       FREEandSTRDUP(base->note, strval);
-               else
-                       base->note = strval;
-               base->note_changed = true;
-               break;
-       case CTS_BASE_VAL_UID_STR:
-               if (base->embedded)
-                       FREEandSTRDUP(base->uid, strval);
-               else
-                       base->uid = strval;
-               base->uid_changed = true;
-               break;
-       case CTS_BASE_VAL_FULL_IMG_PATH_STR:
-               if (base->embedded)
-                       FREEandSTRDUP(base->full_img_path, strval);
-               else
-                       base->full_img_path = strval;
-               base->full_img_changed = true;
-               break;
-       default:
-               ERR("Not supported field(%d)", field);
-               return CTS_ERR_ARG_INVALID;
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_value_set_str_name(cts_name *name, int field, char *strval)
-{
-       switch (field) {
-       case CTS_NAME_VAL_FIRST_STR:
-               if (name->embedded) {
-                       FREEandSTRDUP(name->first, strval);
-               }
-               else
-                       name->first = strval;
-               break;
-       case CTS_NAME_VAL_LAST_STR:
-               if (name->embedded) {
-                       FREEandSTRDUP(name->last, strval);
-               }
-               else
-                       name->last = strval;
-               break;
-       case CTS_NAME_VAL_ADDITION_STR:
-               if (name->embedded) {
-                       FREEandSTRDUP(name->addition, strval);
-               }
-               else
-                       name->addition = strval;
-               break;
-       case CTS_NAME_VAL_DISPLAY_STR:
-               if (name->embedded) {
-                       FREEandSTRDUP(name->display, strval);
-               }
-               else
-                       name->display = strval;
-               break;
-       case CTS_NAME_VAL_PREFIX_STR:
-               if (name->embedded) {
-                       FREEandSTRDUP(name->prefix, strval);
-               }
-               else
-                       name->prefix = strval;
-               break;
-       case CTS_NAME_VAL_SUFFIX_STR:
-               if (name->embedded) {
-                       FREEandSTRDUP(name->suffix, strval);
-               }
-               else
-                       name->suffix = strval;
-               break;
-       default:
-               ERR("Not supported field(%d)", field);
-               return CTS_ERR_ARG_INVALID;
-       }
-       name->is_changed = true;
-       return CTS_SUCCESS;
-}
-
-static inline int cts_value_set_str_postal(cts_postal *postal, int field, char *strval)
-{
-       switch (field) {
-       case CTS_POSTAL_VAL_POBOX_STR:
-               if (postal->embedded) {
-                       FREEandSTRDUP(postal->pobox, strval);
-               }
-               else
-                       postal->pobox = strval;
-               break;
-       case CTS_POSTAL_VAL_POSTALCODE_STR:
-               if (postal->embedded) {
-                       FREEandSTRDUP(postal->postalcode, strval);
-               }
-               else
-                       postal->postalcode = strval;
-               break;
-       case CTS_POSTAL_VAL_REGION_STR:
-               if (postal->embedded) {
-                       FREEandSTRDUP(postal->region, strval);
-               }
-               else
-                       postal->region = strval;
-               break;
-       case CTS_POSTAL_VAL_LOCALITY_STR:
-               if (postal->embedded) {
-                       FREEandSTRDUP(postal->locality, strval);
-               }
-               else
-                       postal->locality = strval;
-               break;
-       case CTS_POSTAL_VAL_STREET_STR:
-               if (postal->embedded) {
-                       FREEandSTRDUP(postal->street, strval);
-               }
-               else
-                       postal->street = strval;
-               break;
-       case CTS_POSTAL_VAL_EXTENDED_STR:
-               if (postal->embedded) {
-                       FREEandSTRDUP(postal->extended, strval);
-               }
-               else
-                       postal->extended = strval;
-               break;
-       case CTS_POSTAL_VAL_COUNTRY_STR:
-               if (postal->embedded) {
-                       FREEandSTRDUP(postal->country, strval);
-               }
-               else
-                       postal->country = strval;
-               break;
-       default:
-               ERR("Not supported field(%d)", field);
-               return CTS_ERR_ARG_INVALID;
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_value_set_str_company(
-               cts_company *com, int field, char *strval)
-{
-       switch (field) {
-       case CTS_COMPANY_VAL_NAME_STR:
-               if (com->embedded) {
-                       FREEandSTRDUP(com->name, strval);
-               }
-               else
-                       com->name = strval;
-               break;
-       case CTS_COMPANY_VAL_DEPARTMENT_STR:
-               if (com->embedded) {
-                       FREEandSTRDUP(com->department, strval);
-               }
-               else
-                       com->department = strval;
-               break;
-       case CTS_COMPANY_VAL_JOB_TITLE_STR:
-               if (com->embedded) {
-                       FREEandSTRDUP(com->jot_title, strval);
-               }
-               else
-                       com->jot_title = strval;
-               break;
-       case CTS_COMPANY_VAL_ROLE_STR:
-               if (com->embedded) {
-                       FREEandSTRDUP(com->role, strval);
-               }
-               else
-                       com->role = strval;
-               break;
-       case CTS_COMPANY_VAL_ASSISTANT_NAME_STR:
-               if (com->embedded) {
-                       FREEandSTRDUP(com->assistant_name, strval);
-               }
-               else
-                       com->assistant_name = strval;
-               break;
-       default:
-               ERR("Not supported field(%d)", field);
-               return CTS_ERR_ARG_INVALID;
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_value_set_str_group(
-               cts_group *group, int field, char *strval)
-{
-       switch (field) {
-       case CTS_GROUP_VAL_NAME_STR:
-               if (group->embedded) {
-                       FREEandSTRDUP(group->name, strval);
-               }
-               else
-                       group->name = strval;
-               break;
-       case CTS_GROUP_VAL_RINGTONE_STR:
-               if (group->embedded) {
-                       FREEandSTRDUP(group->ringtone_path, strval);
-               }
-               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(%d)", field);
-               return CTS_ERR_ARG_INVALID;
-       }
-       return CTS_SUCCESS;
-}
-
-static inline int cts_value_set_str_extend(cts_extend *extend, int field, char *strval)
-{
-       switch (field) {
-       case CTS_EXTEND_VAL_DATA2_STR:
-               if (extend->embedded) {
-                       FREEandSTRDUP(extend->data2, strval);
-               }
-               else
-                       extend->data2 = strval;
-               break;
-       case CTS_EXTEND_VAL_DATA3_STR:
-               if (extend->embedded) {
-                       FREEandSTRDUP(extend->data3, strval);
-               }
-               else
-                       extend->data3 = strval;
-               break;
-       case CTS_EXTEND_VAL_DATA4_STR:
-               if (extend->embedded) {
-                       FREEandSTRDUP(extend->data4, strval);
-               }
-               else
-                       extend->data4 = strval;
-               break;
-       case CTS_EXTEND_VAL_DATA5_STR:
-               if (extend->embedded) {
-                       FREEandSTRDUP(extend->data5, strval);
-               }
-               else
-                       extend->data5 = strval;
-               break;
-       case CTS_EXTEND_VAL_DATA6_STR:
-               if (extend->embedded) {
-                       FREEandSTRDUP(extend->data6, strval);
-               }
-               else
-                       extend->data6 = strval;
-               break;
-       case CTS_EXTEND_VAL_DATA7_STR:
-               if (extend->embedded) {
-                       FREEandSTRDUP(extend->data7, strval);
-               }
-               else
-                       extend->data7 = strval;
-               break;
-       case CTS_EXTEND_VAL_DATA8_STR:
-               if (extend->embedded) {
-                       FREEandSTRDUP(extend->data8, strval);
-               }
-               else
-                       extend->data8 = strval;
-               break;
-       case CTS_EXTEND_VAL_DATA9_STR:
-               if (extend->embedded) {
-                       FREEandSTRDUP(extend->data9, strval);
-               }
-               else
-                       extend->data9 = strval;
-               break;
-
-       case CTS_EXTEND_VAL_DATA10_STR:
-               if (extend->embedded) {
-                       FREEandSTRDUP(extend->data10, strval);
-               }
-               else
-                       extend->data10 = strval;
-               break;
-       default:
-               ERR("Not supported field(%d)", field);
-               return CTS_ERR_ARG_INVALID;
-       }
-       return CTS_SUCCESS;
-}
-
-
-static inline int cts_value_set_str_im(cts_messenger *im, int field, char *strval)
-{
-       switch (field) {
-       case CTS_MESSENGER_VAL_IM_ID_STR:
-               if (im->embedded)
-                       FREEandSTRDUP(im->im_id, strval);
-               else
-                       im->im_id = strval;
-               break;
-       case CTS_MESSENGER_VAL_SERVICE_NAME_STR:
-               if (im->embedded)
-                       FREEandSTRDUP(im->svc_name, strval);
-               else
-                       im->svc_name = strval;
-               break;
-       case CTS_MESSENGER_VAL_SERVICE_OP_STR:
-               if (im->embedded)
-                       FREEandSTRDUP(im->svc_op, strval);
-               else
-                       im->svc_op = strval;
-               break;
-       default:
-               ERR("Not supported field(%d)", field);
-               return CTS_ERR_ARG_INVALID;
-       }
-       return CTS_SUCCESS;
-}
-
-
-API int contacts_svc_value_set_str(CTSvalue *value, int field, const char *strval)
-{
-       char *str;
-
-       retv_if(NULL == value, CTS_ERR_ARG_NULL);
-
-       if (strval && *strval)
-               str = (char *)strval;
-       else
-               str = NULL;
-
-       switch (value->v_type) {
-       case CTS_VALUE_BASIC:
-               ((cts_basic*)value)->type = CTS_BASIC_VAL_STR;
-               if (value->embedded)
-                       FREEandSTRDUP(((cts_basic*)value)->val.s, str);
-               else
-                       ((cts_basic*)value)->val.s = str;
-               break;
-       case CTS_VALUE_CONTACT_BASE_INFO:
-               return cts_value_set_str_base((cts_ct_base *)value, field, str);
-       case CTS_VALUE_NAME:
-               return cts_value_set_str_name((cts_name *)value, field, str);
-       case CTS_VALUE_POSTAL:
-               return cts_value_set_str_postal((cts_postal *)value, field, str);
-       case CTS_VALUE_COMPANY:
-               return cts_value_set_str_company((cts_company *)value, field, str);
-       case CTS_VALUE_GROUP:
-               return cts_value_set_str_group((cts_group *)value, field, str);
-       case CTS_VALUE_EXTEND:
-               return cts_value_set_str_extend((cts_extend *)value, field, str);
-       case CTS_VALUE_MESSENGER:
-               return cts_value_set_str_im((cts_messenger *)value, field, str);
-       case CTS_VALUE_NUMBER:
-               retvm_if(CTS_NUM_VAL_NUMBER_STR != field, CTS_ERR_ARG_INVALID,
-                               "Not supported field");
-               if (value->embedded)
-                       FREEandSTRDUP(((cts_number*)value)->number, str);
-               else
-                       ((cts_number *)value)->number = str;
-               break;
-       case CTS_VALUE_EMAIL:
-               retvm_if(CTS_EMAIL_VAL_ADDR_STR != field, CTS_ERR_ARG_INVALID, "Not supported field");
-               if (value->embedded)
-                       FREEandSTRDUP(((cts_email*)value)->email_addr, str);
-               else
-                       ((cts_email *)value)->email_addr = str;
-               break;
-       case CTS_VALUE_GROUP_RELATION:
-               retvm_if(CTS_GROUPREL_VAL_NAME_STR != field, CTS_ERR_ARG_INVALID,
-                               "Not supported field(%d) for CTS_VALUE_GROUP_RELATION", field);
-               retvm_if(value->embedded, CTS_ERR_ARG_INVALID,
-                               "CTS_GROUPREL_VAL_NAME_STR is readonly");
-               ((cts_group *)value)->name = str;
-               break;
-       case CTS_VALUE_PHONELOG:  /* phonelog value never be embedded*/
-               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 {
-                       ERR("Not supported field");
-                       return CTS_ERR_ARG_INVALID;
-               }
-               break;
-       case CTS_VALUE_WEB:
-               retvm_if(CTS_WEB_VAL_ADDR_STR != field, CTS_ERR_ARG_INVALID, "Not supported field");
-               if (value->embedded)
-                       FREEandSTRDUP(((cts_web *)value)->url, str);
-               else
-                       ((cts_web *)value)->url = str;
-               break;
-       case CTS_VALUE_NICKNAME:
-               retvm_if(CTS_NICKNAME_VAL_NAME_STR != field, CTS_ERR_ARG_INVALID, "Not supported field");
-               if (value->embedded)
-                       FREEandSTRDUP(((cts_nickname *)value)->nick, str);
-               else
-                       ((cts_nickname *)value)->nick = str;
-               break;
-       case CTS_VALUE_ADDRESSBOOK:
-               retvm_if(CTS_ADDRESSBOOK_VAL_NAME_STR != field, CTS_ERR_ARG_INVALID,
-                               "Not supported field");
-               if (value->embedded)
-                       FREEandSTRDUP(((cts_addrbook *)value)->name, str);
-               else
-                       ((cts_addrbook *)value)->name = str;
-               break;
-       case CTS_VALUE_EVENT:
-               /* evet value doesn't have string value */
-       default:
-               ERR("The value has unsupported type(%d)", value->v_type);
-               return CTS_ERR_ARG_INVALID;
-       }
-
-       return CTS_SUCCESS;
-}
diff --git a/src/cts-struct.h b/src/cts-struct.h
deleted file mode 100755 (executable)
index 1bba9bc..0000000
+++ /dev/null
@@ -1,861 +0,0 @@
-/*
- * 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_STRUCT_H__
-#define __CTS_STRUCT_H__
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <glib.h>
-#include <string.h>
-
-#define CTS_NUMBER_MAX_LEN 512
-
-#define SMART_STRDUP(src) (src && *src)?strdup(src):NULL
-#define SAFE_STRDUP(src) (src)?strdup(src):NULL
-#define FREEandSTRDUP(dest, src) \
-       do{ \
-               free(dest);\
-               if (src) dest = strdup(src);\
-               else dest = NULL; \
-       }while (0)
-
-enum {
-       CTS_HANDLE_STR_GET,
-       CTS_HANDLE_STR_STEAL,
-};
-
-#define HANDLE_STEAL_STRING(op_code, dest, src) \
-       do{ \
-               dest=src; \
-               if (CTS_HANDLE_STR_STEAL == op_code) src=NULL; \
-       }while (0)
-
-#define CTS_DATA_FIELD_NAME (1<<0)
-#define CTS_DATA_FIELD_POSTAL (1<<1)
-#define CTS_DATA_FIELD_MESSENGER (1<<2)
-#define CTS_DATA_FIELD_WEB (1<<3)
-#define CTS_DATA_FIELD_EVENT (1<<4)
-#define CTS_DATA_FIELD_COMPANY (1<<5)
-#define CTS_DATA_FIELD_NICKNAME (1<<6)
-#define CTS_DATA_FIELD_NUMBER (1<<7)
-#define CTS_DATA_FIELD_EMAIL (1<<8)
-#define CTS_DATA_FIELD_EXTEND_ALL (1<<9)
-#define CTS_DATA_FIELD_ALL ((1<<9)|(1<<8)|(1<<7)|(1<<6)|(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0))
-
-enum {
-       CTS_DATA_NAME = 1,
-       CTS_DATA_POSTAL = 2,
-       CTS_DATA_MESSENGER = 3,
-       CTS_DATA_WEB = 4,
-       CTS_DATA_EVENT = 5,
-       CTS_DATA_COMPANY = 6,
-       CTS_DATA_NICKNAME = 7,
-       CTS_DATA_NUMBER = 8,
-       CTS_DATA_EMAIL = 9,
-       CTS_DATA_EXTEND_START = 100
-};
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       bool deleted;
-       int type;
-       union {
-               int i;
-               bool b;
-               double d;
-               char *s;
-       }val;
-}cts_basic; //CTS_BASIC_VAL_
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       bool deleted;
-       bool uid_changed;
-       bool img_changed;
-       bool full_img_changed;
-       bool ringtone_changed;
-       bool note_changed;
-       bool is_favorite;
-       int id;
-       int person_id;
-       int changed_time;
-       int addrbook_id;
-       char *uid;
-       char *img_path;
-       char *full_img_path;
-       char *ringtone_path;
-       char *note;
-       char *vcard_img_path;
-}cts_ct_base; //CTS_BASE_VAL_
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       bool deleted;
-       bool is_changed;
-       int id;
-       int lang_type;
-       char *first;
-       char *last;
-       char *addition;
-       char *display;
-       char *prefix;
-       char *suffix;
-}cts_name; //CTS_NAME_VAL_
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       bool deleted;
-       bool is_default;
-       bool is_favorite;
-       int id;
-       int type;
-       char *number;
-       char *added_type;
-}cts_number; //CTS_NUM_VAL_
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       bool deleted;
-       bool is_default;
-       int id;
-       int type;
-       char *email_addr;
-}cts_email; //CTS_EMAIL_VAL_
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       bool deleted;
-       int id;
-       int type;
-       char *url;
-}cts_web; //CTS_WEB_VAL_
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       bool deleted;
-       bool is_default;
-       int id;
-       int type;
-       char *pobox;
-       char *postalcode;
-       char *region;
-       char *locality;
-       char *street;
-       char *extended;
-       char *country;
-}cts_postal; //CTS_POSTAL_VAL_
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       bool deleted;
-       int id;
-       int type;
-       int date;
-}cts_event;//CTS_EVENT_VAL_
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       bool deleted;
-       int id;
-       int type;
-       char *im_id;
-       char *svc_name;
-       char *svc_op;
-}cts_messenger;//CTS_MESSENGER_VAL_
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       bool deleted;
-       int id;
-       char *nick;
-}cts_nickname; //CTS_NICKNAME_VAL_
-
-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 *img_path;
-}cts_group; //CTS_GROUP_VAL_ or CTS_GROUPREL_VAL_
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       bool deleted;
-       int id;
-       int acc_id;
-       int acc_type;
-       int mode;
-       char *name;
-}cts_addrbook; //CTS_ADDRESSBOOK_VAL_
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       bool deleted; /* not used */
-       int id;
-       char *name;
-       char *department;
-       char *jot_title;
-       char *role;
-       char *assistant_name;
-}cts_company;//CTS_COMPANY_VAL_
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       bool deleted;
-       int id;
-       char *number;
-       int related_id; /* person id */
-       int log_time;
-       int log_type;
-       int extra_data1; /* duration, message_id */
-       char *extra_data2; /*short message*/
-}cts_plog;//PHONELOGVALUE
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       bool deleted;
-       int id;
-       int type;
-       int data1;
-       char *data2;
-       char *data3;
-       char *data4;
-       char *data5;
-       char *data6;
-       char *data7;
-       char *data8;
-       char *data9;
-       char *data10;
-}cts_extend;//EXTENDVALUE
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       int id;
-       int num_type;
-       char *first;
-       char *last;
-       char *display;
-       char *number;
-       char *img_path;
-       int log_time;
-       int log_type;
-       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 person_id;
-       int contact_id;
-       int addrbook_id;
-       char *img_path;
-       char *first;
-       char *last;
-       char *display;
-       char *connect;
-       char *normalize;
-}contact_list;//CTS_LIST_CONTACT_
-
-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
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       int changed_type:8;
-       int id;
-       int changed_ver;
-       int addressbook_id;
-}change_list;//CTS_LIST_CHANGE_
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       int id;
-       int account_type;
-       char *name;
-}addrbook_list;//CTS_LIST_ADDRESSBOOK_
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       int id;
-       char *name;
-}numtype_list;//CUSTOMNUMTYPELIST
-
-typedef struct {
-       int v_type:16;
-       bool embedded;
-       int id;
-       int person_id;
-       int contact_id;
-       char *first;
-       char *last;
-       char *display;
-       char *number;
-       char *img_path;
-       int num_type;
-       int speeddial;
-}shortcut_list;//CTS_LIST_FAVORITE_
-
-typedef struct {
-       int s_type;
-       int is_restricted;
-       cts_ct_base *base;
-       cts_name *name;
-       GSList *numbers;
-       GSList *emails;
-       GSList *grouprelations;
-       GSList *events;
-       GSList *messengers;
-       GSList *postal_addrs;
-       GSList *web_addrs;
-       GSList *nicknames;
-       cts_company *company;
-       int default_num;
-       int default_email;
-       GSList *extended_values;
-}contact_t; //cts_struct_field
-
-enum{
-       CTS_VALUE_BASIC = 100, /**< Deprecated */
-       CTS_VALUE_LIST_CONTACT = 101,
-       CTS_VALUE_LIST_ADDRBOOK, // ADDRESSBOOKLIST order must be same to ADDRESSBOOKVALUE order.
-       CTS_VALUE_LIST_PLOG,
-       CTS_VALUE_LIST_CUSTOM_NUM_TYPE,
-       CTS_VALUE_LIST_CHANGE,
-       CTS_VALUE_LIST_GROUP,
-       CTS_VALUE_LIST_NUMBERINFO, // NUMBERLIST order must be same to EMAILLIST order.
-       CTS_VALUE_LIST_EMAILINFO, // EMAILLIST order must be same to NUMBERLIST order.
-       CTS_VALUE_LIST_NUMS_EMAILS,
-       CTS_VALUE_LIST_SDN,
-       CTS_VALUE_RDONLY_NAME,
-       CTS_VALUE_RDONLY_NUMBER,
-       CTS_VALUE_RDONLY_EMAIL,
-       CTS_VALUE_RDONLY_COMPANY,
-       CTS_VALUE_LIST_SHORTCUT,
-       CTS_VALUE_RDONLY_PLOG,
-       CTS_VALUE_LIST_OSP,
-};
-
-//basic
-enum {
-       CTS_BASIC_VAL_INT,
-       CTS_BASIC_VAL_DBL,
-       CTS_BASIC_VAL_BOOL,
-       CTS_BASIC_VAL_STR
-};
-
-#ifndef __CONTACTS_SVC_H__
-
-struct cts_struct{
-       int s_type;
-};
-
-struct cts_value{
-       int v_type:16;
-       bool embedded;
-       bool deleted;
-};
-
-//<!--
-
-/**
- * CTSstruct is an opaque type, it must be used via accessor functions.
- * Conceptually, each Struct is a set of values and list of values.
- *
- * To remove a value from a list of values, set the VAL_DELETE
- * field in the value and store the list.
- *
- * @see contacts_svc_struct_new(), contacts_svc_struct_free()
- * @see contacts_svc_struct_get_value(), contacts_svc_struct_get_list(),
- * @see contacts_svc_struct_store_value(), contacts_svc_struct_store_list()
- */
-typedef struct cts_struct CTSstruct;
-
-/**
- * CTSvalue is an opaque type, it must be
- * used via accessor functions. Conceptually, each value is
- * a tuple of fields with a fixed type per field, with each field
- * accessed inside the value via a fixed index number (for example,
- * #NAMEVALUE). Supported types are int (value range as in C int), string
- * and boolean (C++ bool). The right access methods must be used depending
- * on the field type.
- *
- * @see contacts_svc_value_new(), contacts_svc_value_free()
- * @see contacts_svc_value_set_int(), contacts_svc_value_set_bool(), contacts_svc_value_set_str()
- * @see contacts_svc_value_get_int(), contacts_svc_value_get_bool(), contacts_svc_value_get_str()
- */
-typedef struct cts_value CTSvalue;
-
-
-//////////////////// Value ////////////////////
-/**
- * Use for contacts_svc_value_new()
- *
- * Unless noted otherwise, these values are storded in a contact
- * Struct. Some of those values may occur more than once per contact
- * Struct. Those values are stored in lists, see #cts_struct_field.
- */
-typedef enum
-{
-       CTS_VALUE_CONTACT_BASE_INFO,/**< #BASEVALUE */
-       CTS_VALUE_NAME,/**< #NAMEVALUE */
-       CTS_VALUE_NUMBER,/**< #NUMBERVALUE */
-       CTS_VALUE_EMAIL,/**< #EMAILVALUE */
-       CTS_VALUE_WEB,/**< #WEBVALUE */
-       CTS_VALUE_POSTAL,/**< #POSTALVALUE */
-       CTS_VALUE_EVENT,/**< #EVENTVALUE */
-       CTS_VALUE_MESSENGER,/**< #MESSENGERVALUE */
-       CTS_VALUE_GROUP_RELATION,/**< #GROUPRELATIONVALUE */
-       CTS_VALUE_COMPANY,/**< #COMPANYVALUE */
-       CTS_VALUE_PHONELOG,/**< #PHONELOGVALUE, not part of a contact, see contacts_svc_insert_phonelog() and friends */
-       CTS_VALUE_GROUP,/**< #GROUPVALUE, not part of a contact, see contacts_svc_insert_group() */
-       CTS_VALUE_EXTEND,/**< #EXTENDVALUE(@ref CONTACTS_SVC_EXTEND) */
-       CTS_VALUE_NICKNAME,/**< #NICKNAMEVALUE */
-       CTS_VALUE_ADDRESSBOOK /**< #ADDRESSBOOKVALUE, not part of a contact, see contacts_svc_insert_addressbook() */
-}cts_value_type;
-
-/**
- * base information
- */
-enum BASEVALUE {
-       CTS_BASE_VAL_ID_INT,/**< A contact index number. read only */
-       CTS_BASE_VAL_CHANGED_TIME_INT,/**< read only, The time since the Epoch (00:00:00 UTC, January 1, 1970), measured in seconds.
-                                                                                         It is based on system. If system time is invalid, this value is invalid too.*/
-       CTS_BASE_VAL_IMG_PATH_STR, /**< A thumbnail image. Should include extension at path */
-       CTS_BASE_VAL_RINGTONE_PATH_STR, /**< .*/
-       CTS_BASE_VAL_NOTE_STR, /**< .*/
-       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_PERSON_ID_INT /**< read only */
-};
-
-/**
- * name
- */
-enum NAMEVALUE {
-       CTS_NAME_VAL_FIRST_STR,/**< for example, John */
-       CTS_NAME_VAL_LAST_STR,/**< for example, Doe */
-       CTS_NAME_VAL_ADDITION_STR,/**< also known as "middle name(s)" */
-       CTS_NAME_VAL_SUFFIX_STR,/**< for example, Jr. for "Junior" */
-       CTS_NAME_VAL_PREFIX_STR,/**< for example, Mr. for "Mister" */
-       CTS_NAME_VAL_DISPLAY_STR,/**< see #CONTACTS_SVC_NAME */
-};
-
-/**
- * A phone number
- */
-enum NUMBERVALUE {
-       CTS_NUM_VAL_ID_INT,/**< read only, for use in contacts_svc_set_favorite(CTS_FAVOR_NUMBER) */
-       CTS_NUM_VAL_TYPE_INT,/**< you can use #NUMBERTYPE or contacts_svc_find_custom_type().*/
-       CTS_NUM_VAL_DEFAULT_BOOL,/**< */
-       CTS_NUM_VAL_FAVORITE_BOOL, /**< read only. Set with contacts_svc_set_favorite(CTS_FAVOR_NUMBER). It can assign for handling struct. But the changes are ignored */
-       CTS_NUM_VAL_DELETE_BOOL,/**< request to delete in the list of #CTSstruct. */
-       CTS_NUM_VAL_NUMBER_STR,/**< .*/
-};
-
-/**
- * email
- */
-enum EMAILVALUE {
-       CTS_EMAIL_VAL_ID_INT,/**< read only */
-       CTS_EMAIL_VAL_TYPE_INT,/**< #EMAILTYPE.*/
-       CTS_EMAIL_VAL_DEFAULT_BOOL,/**< */
-       CTS_EMAIL_VAL_DELETE_BOOL,/**< request to delete in the list of #CTSstruct. */
-       CTS_EMAIL_VAL_ADDR_STR,/**< .*/
-};
-
-/**
- * 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 = 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 */
-};
-
-/**
- * event, for example birthday
- */
-enum EVENTVALUE {
-       CTS_EVENT_VAL_TYPE_INT,/**< #EVENTTYPE*/
-       CTS_EVENT_VAL_DELETE_BOOL,/**< request to delete in the list of #CTSstruct. */
-       CTS_EVENT_VAL_DATE_INT,/**< The date(YYYYMMDD). ex) 20100107 : year = 2010, month = 01, day = 07 */
-};
-
-/**
- * web address
- */
-enum WEBVALUE {
-       CTS_WEB_VAL_TYPE_INT,/**< #WEBTYPE */
-       CTS_WEB_VAL_DELETE_BOOL,/**< request to delete in the list of #CTSstruct. */
-       CTS_WEB_VAL_ADDR_STR,/**< .*/
-};
-
-/**
- * postal address
- */
-enum POSTALVALUE {
-       CTS_POSTAL_VAL_TYPE_INT,/**< #ADDRESSTYPE*/
-       CTS_POSTAL_VAL_DELETE_BOOL,/**< request to delete in the list of #CTSstruct. */
-       CTS_POSTAL_VAL_POBOX_STR,/**< .*/
-       CTS_POSTAL_VAL_POSTALCODE_STR,/**< .*/
-       CTS_POSTAL_VAL_REGION_STR,/**< e.g., state or province */
-       CTS_POSTAL_VAL_LOCALITY_STR,/**< e.g., city */
-       CTS_POSTAL_VAL_STREET_STR,/**< .*/
-       CTS_POSTAL_VAL_EXTENDED_STR,/**< .*/
-       CTS_POSTAL_VAL_COUNTRY_STR,/**< .*/
-       CTS_POSTAL_VAL_DEFAULT_BOOL,/**< */
-};
-
-/**
- * messenger
- */
-enum MESSENGERVALUE {
-       CTS_MESSENGER_VAL_TYPE_INT,/**< #cts_im_type */
-       CTS_MESSENGER_VAL_DELETE_BOOL,/**< request to delete in the list of #CTSstruct. */
-       CTS_MESSENGER_VAL_IM_ID_STR,/**< .*/
-       CTS_MESSENGER_VAL_SERVICE_NAME_STR,/**< The name of unknown service. So, this is valid in CTS_IM_TYPE_NONE. */
-       CTS_MESSENGER_VAL_SERVICE_OP_STR,/**< The service operation related to launch unknown application. So, this is valid in CTS_IM_TYPE_NONE. */
-};
-
-/**
- * company
- */
-enum COMPANYVALUE {
-       CTS_COMPANY_VAL_NAME_STR,/**< .*/
-       CTS_COMPANY_VAL_DEPARTMENT_STR,/**< .*/
-       CTS_COMPANY_VAL_JOB_TITLE_STR,/**< .*/
-       CTS_COMPANY_VAL_ASSISTANT_NAME_STR,/**< .*/
-       CTS_COMPANY_VAL_ROLE_STR,/**< .*/
-};
-
-/**
- * nickname
- */
-enum NICKNAMEVALUE {
-       CTS_NICKNAME_VAL_DELETE_BOOL,/**< request to delete in the list of #CTSstruct. */
-       CTS_NICKNAME_VAL_NAME_STR,/**< .*/
-};
-
-/**
- * phone log
- */
-enum PHONELOGVALUE {
-       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,/**<  message short message or email subject */
-       CTS_PLOG_VAL_MSGID_INT,/**< message id or email id */
-       CTS_PLOG_VAL_RELATED_ID_INT,/**< contact id */
-};
-
-/** deprecated */
-#define CTS_PLOG_VAL_NUMBER_STR CTS_PLOG_VAL_ADDRESS_STR
-
-/**
- * addressbook
- */
-enum ADDRESSBOOKVALUE
-{
-       CTS_ADDRESSBOOK_VAL_ID_INT, /**< read only */
-       CTS_ADDRESSBOOK_VAL_NAME_STR, /**< . */
-       CTS_ADDRESSBOOK_VAL_ACC_ID_INT, /**< The related account id */
-       CTS_ADDRESSBOOK_VAL_ACC_TYPE_INT, /**< #ADDRESSBOOKTYPE */
-       CTS_ADDRESSBOOK_VAL_MODE_INT, /**< #ADDRESSBOOKPERMISSION
-                                                                                         It is only data. nothing to do in contacts-service */
-};
-
-/**
- * extended value
- * @ref CONTACTS_SVC_EXTEND
- *
- * See #CTS_TYPE_CLASS_EXTEND_DATA, contacts_svc_find_custom_type().
- */
-enum EXTENDVALUE {
-       CTS_EXTEND_VAL_DELETE_BOOL,/**< request to delete in the list of #CTSstruct. */
-       CTS_EXTEND_VAL_DATA1_INT,/**< . */
-       CTS_EXTEND_VAL_DATA2_STR,/**< . */
-       CTS_EXTEND_VAL_DATA3_STR,/**< . */
-       CTS_EXTEND_VAL_DATA4_STR,/**< . */
-       CTS_EXTEND_VAL_DATA5_STR,/**< . */
-       CTS_EXTEND_VAL_DATA6_STR,/**< . */
-       CTS_EXTEND_VAL_DATA7_STR,/**< . */
-       CTS_EXTEND_VAL_DATA8_STR,/**< . */
-       CTS_EXTEND_VAL_DATA9_STR,/**< . */
-       CTS_EXTEND_VAL_DATA10_STR,/**< . */
-};
-
-
-//////////////////// Struct ////////////////////
-/**
- * Use for contacts_svc_struct_new()
- */
-typedef enum {
-       CTS_STRUCT_CONTACT = 0, /**< CTS_STRUCT_CONTACT */
-}cts_struct_type;
-
-/**
- * Contacts service struct fields
- * CF means Contact Field. Some of these
- * fields may only have one value (_VALUE suffix),
- * others have a list of values (_LIST suffix).
- */
-typedef enum
-{
-       CTS_CF_NONE,/**< CTS_CF_NONE */
-       CTS_CF_BASE_INFO_VALUE,/**< #BASEVALUE */
-       CTS_CF_NAME_VALUE,/**< #NAMEVALUE */
-       CTS_CF_COMPANY_VALUE,/**< #COMPANYVALUE */
-       CTS_CF_VALUE_MAX,/**< CTS_CF_VALUE_MAX */
-       CTS_CF_NUMBER_LIST,/**< List of #NUMBERVALUE */
-       CTS_CF_EMAIL_LIST,/**< List of #EMAILVALUE */
-       CTS_CF_GROUPREL_LIST,/**< List of #GROUPVALUE */
-       CTS_CF_EVENT_LIST,/**< List of #EVENTVALUE */
-       CTS_CF_MESSENGER_LIST,/**< List of #MESSENGERVALUE */
-       CTS_CF_POSTAL_ADDR_LIST,/**< List of #POSTALVALUE */
-       CTS_CF_WEB_ADDR_LIST,/**< List of #WEBVALUE */
-       CTS_CF_NICKNAME_LIST,/**< List of #NICKNAMEVALUE */
-       CTS_CF_FIELD_MAX,/**< CTS_CF_FIELD_MAX */
-}cts_struct_field;
-
-/**
- * Allocate, initialize and return a new contacts service struct.
- *
- * @param[in] type The type of contacts service struct
- * @return The pointer of New contacts service struct, NULL on error
- * @see contacts_svc_struct_free()
- */
-CTSstruct* contacts_svc_struct_new(cts_struct_type type);
-
-/**
- * A destructor for contacts service struct.
- *
- * @param[in] structure A contacts service struct
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @see contacts_svc_struct_new()
- */
-int contacts_svc_struct_free(CTSstruct* structure);
-
-/**
- * This function gets the contacts service value of a single-value field(_VALUE suffix) in the contacts service struct.
- * Must not be used with fields which contain a list(_LIST suffix).
- *
- * @param[in] structure A contacts service struct
- * @param[in] field The index of the contacts service value in contacts service struct.
- * @param[out] retval the contacts service value requested with field(should not be freed)
- * @return     #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_struct_get_value(CTSstruct *structure, cts_struct_field field, CTSvalue** retval);
-
-/**
- * This function sets the contacts service value of a single-value field(_VALUE suffix) in the contacts service struct.
- * \n For efficiency, Ownership of the contacts service value is transferred to the contacts service struct.
- * (Although values be free by contacts_svc_value_free, it is ignored automatically)
- * But string values of contacts service value are copied, and thus ownership of the original string
- * remains with the original creator of it.
- *
- * @param[in] structure A contacts service struct
- * @param[in] field The index of the contacts service value in contacts service struct.
- * @param[in] value the contacts service value to be set
- * @return     #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_struct_store_value(CTSstruct *structure, cts_struct_field field, CTSvalue* value);
-
-/**
- * This function gets the pointer to a glib singly-linked list holding all values of multi-value field(_LIST suffix) in the contacts service struct.
- * Must not be used with single-value fields.
- *
- * @param[in] structure A contacts service struct
- * @param[in] field The index of the glib singly-linked list in contacts service struct.
- * @param[out] retlist the glib singly-linked list requested with field(should not be freed or removed)
- * @return     #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_struct_get_list(CTSstruct *structure, cts_struct_field field, GSList** retlist);
-
-/**
- * This function sets the glib singly-linked list to the contacts service struct.
- * \n The list is copied.(list is needed to free)
- * But values(#CTSvalue) of the list are moved to the contacts service struct for efficiency.
- * (Although values be free by contacts_svc_value_free, it is ignored automatically)
- *
- * @param[in] structure A contacts service struct
- * @param[in] field The index of the glib singly-linked list in contacts service struct.
- * @param[in] list the glib singly-linked list to be set
- * @return     #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_struct_store_list(CTSstruct *structure, cts_struct_field field, GSList* list);
-
-/**
- * Allocate, initialize and return a new contacts service value.
- * @param[in] type The type of contacts service value
- * @return The pointer of New contacts service value, NULL on error
- * @see contacts_svc_value_free()
- */
-CTSvalue* contacts_svc_value_new(cts_value_type type);
-
-/**
- * A destructor for contacts service value.
- * If it is in struct, this function will ignore to free and return #CTS_ERR_ARG_INVALID.
- * @param[in] value A contacts service value
- * @return     #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @see contacts_svc_value_new()
- */
-int contacts_svc_value_free(CTSvalue* value);
-
-/**
- * This function sets integer field in the contacts service value.
- * May only be used with fields of type integer (_INT suffix in enum).
- *
- * @param[in] value The contacts service value
- * @param[in] field The index of the integer field in the contacts service value.
- * @param[in] intval The integer value to be set.
- * @return     #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_value_set_int(CTSvalue* value, int field, int intval);
-
-/**
- * This function sets boolean field in the contacts service value.
- * May only be used with fields of type boolean (_BOOL suffix in enum).
- *
- * @param[in] value The contacts service value
- * @param[in] field The index of the boolean field in the contacts service value.
- * @param[in] boolval The boolean value to be set.
- * @return     #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_value_set_bool(CTSvalue* value, int field, bool boolval);
-
-/**
- * This function sets string field in the contacts service value.(call by reference)
- * May only be used with fields of type string (_STR suffix in enum).
- * \n If it is in struct, free old string and copy strval to struct.(call by value)
- * \n empty string is handled as NULL and thus will result in NULL being stored
- *
- * @param[in] value The contacts service value
- * @param[in] field The index of the string field in the contacts service value.
- * @param[in] strval The string value to be set.
- * @return     #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_value_set_str(CTSvalue* value, int field, const char *strval);
-
-/**
- * This function gets the type of the contacts service value.
- * @param[in] value The contacts service value
- * @return Value Type(#cts_value_type) on success, Negative value(#cts_error) on error
- */
-int contacts_svc_value_get_type(CTSvalue* value);
-
-/**
- * This function gets the pointer to a string field of the contacts service value.
- * May only be used with fields of type string (_STR suffix in enum).
- *
- * @param[in] value The contacts service value
- * @param[in] field The index of the string field in the contacts service value.
- * @return string value(should not be freed, never empty), or NULL if no value is obtained
- */
-const char* contacts_svc_value_get_str(CTSvalue *value, int field);
-
-/**
- * This function gets boolean value of a field in the contacts service value.
- * May only be used with fields of type boolean (_BOOL suffix in enum).
- *
- * @param[in] value The contacts service value
- * @param[in] field The index of the boolean field in the contacts service value.
- * @return boolean value, or false if no value is obtained
- */
-bool contacts_svc_value_get_bool(CTSvalue* value, int field);
-
-/**
- * This function gets Integer value of the contacts service value.
- * May only be used with fields of type integer (_INT suffix in enum).
- * @param[in] value The contacts service value
- * @param[in] field The index of the integer field in the contacts service value.
- * @return Integer value, or 0 if no value is obtained
- */
-int contacts_svc_value_get_int(CTSvalue* value, int field);
-
-//-->
-#endif //__CONTACTS_SVC_H__
-
-#endif //__CTS_STRUCT_H__
-
diff --git a/src/cts-types.c b/src/cts-types.c
deleted file mode 100755 (executable)
index 0cab02f..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * 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-sqlite.h"
-#include "cts-schema.h"
-#include "cts-utils.h"
-#include "cts-types.h"
-
-API char* contacts_svc_get_custom_type(cts_custom_type_class type_class,
-               int index)
-{
-       int ret;
-       char *ret_val = NULL;
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MIN_LEN] = {0};
-
-       CTS_START_TIME_CHECK;
-
-       if (CTS_TYPE_CLASS_EXTEND_DATA == type_class) index -= CTS_DATA_EXTEND_START;
-       else if (CTS_TYPE_CLASS_NUM == type_class) index ^= CTS_NUM_TYPE_CUSTOM;
-
-       snprintf(query, sizeof(query),
-                       "SELECT name FROM %s WHERE id = %d",
-                       CTS_TABLE_CUSTOM_TYPES, index);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, NULL, "cts_query_prepare() Failed");
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_TRUE == ret)
-               ret_val = cts_stmt_get_text(stmt, 0);
-       cts_stmt_finalize(stmt);
-
-       ret_val = SAFE_STRDUP(ret_val);
-
-       CTS_END_TIME_CHECK();
-       return ret_val;
-}
-
-API int contacts_svc_insert_custom_type(cts_custom_type_class type_class,
-               char *type_name)
-{
-       int ret;
-       cts_stmt stmt = NULL;
-       char query[CTS_SQL_MIN_LEN] = {0};
-
-       retv_if(NULL == type_name, CTS_ERR_ARG_NULL);
-
-       snprintf(query, sizeof(query),
-                       "INSERT INTO %s(class, name) VALUES(%d, ?)",
-                       CTS_TABLE_CUSTOM_TYPES, type_class);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       cts_stmt_bind_text(stmt, 1, type_name);
-
-       ret = cts_stmt_step(stmt);
-       if (CTS_SUCCESS != ret)
-       {
-               ERR("cts_stmt_step() Failed(%d)", ret);
-               cts_stmt_finalize(stmt);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-       ret = cts_db_get_last_insert_id();
-       cts_stmt_finalize(stmt);
-
-       int trans_ret = contacts_svc_end_trans(true);
-       retvm_if(trans_ret < CTS_SUCCESS, trans_ret,
-                       "contacts_svc_end_trans(true) Failed(%d)", trans_ret);
-
-       if (CTS_TYPE_CLASS_EXTEND_DATA == type_class) ret += CTS_DATA_EXTEND_START;
-       else if (CTS_TYPE_CLASS_NUM == type_class) ret |= CTS_NUM_TYPE_CUSTOM;
-       return ret;
-}
-
-API int contacts_svc_delete_custom_type(cts_custom_type_class type_class,
-               int index)
-{
-       int ret;
-       char  query[CTS_SQL_MIN_LEN] = {0};
-
-       retvm_if(CTS_TYPE_CLASS_NUM == type_class && index <= CTS_NUM_TYPE_ASSISTANT,
-                       CTS_ERR_ARG_INVALID,
-                       "This custom number type(System Number Type) is diable to delete");
-
-       if (CTS_TYPE_CLASS_EXTEND_DATA == type_class) index -= CTS_DATA_EXTEND_START;
-       else if (CTS_TYPE_CLASS_NUM == type_class) index ^= CTS_NUM_TYPE_CUSTOM;
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       snprintf(query, sizeof(query), "DELETE FROM %s WHERE class = %d AND id = %d",
-                       CTS_TABLE_CUSTOM_TYPES, type_class, index);
-
-       ret = cts_query_exec(query);
-       if (CTS_SUCCESS != ret)
-       {
-               ERR("cts_query_exec() Failed(%d)", ret);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-
-       ret = contacts_svc_end_trans(true);
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-API int contacts_svc_find_custom_type(cts_custom_type_class type_class,
-               char *type_name)
-{
-       int ret;
-       char query[CTS_SQL_MAX_LEN] = {0};
-
-       retv_if(NULL == type_name, CTS_ERR_ARG_NULL);
-
-       CTS_START_TIME_CHECK;
-
-       snprintf(query, sizeof(query),
-                       "SELECT id FROM %s WHERE class = %d AND name = '%s'",
-                       CTS_TABLE_CUSTOM_TYPES, type_class, type_name);
-       ret = cts_query_get_first_int_result(query);
-       retvm_if(ret < CTS_SUCCESS, ret, "cts_query_get_first_int_result() Failed(%d)", ret);
-
-       if (CTS_TYPE_CLASS_EXTEND_DATA == type_class) ret += CTS_DATA_EXTEND_START;
-       else if (CTS_TYPE_CLASS_NUM == type_class) ret |= CTS_NUM_TYPE_CUSTOM;
-
-       CTS_END_TIME_CHECK();
-       return ret;
-}
-
diff --git a/src/cts-types.h b/src/cts-types.h
deleted file mode 100755 (executable)
index daba106..0000000
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * 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_TYPES_H__
-#define __CTS_TYPES_H__
-
-//<!--
-/**
- * @defgroup   CONTACTS_SVC_TYPES Types
- * @ingroup    CONTACTS_SVC
- * @addtogroup CONTACTS_SVC_TYPES
- * @{
- *
- * It is Types of Number, E-mail, Web address, Address, Event, Phone Log, etc.
- * And this interface provides methods to handle custom types.
- *
- */
-
-/**
- * The Number can be made with a set of values by specifying one or more values.
- * \n Example : CTS_NUM_TYPE_HOME|CTS_NUM_TYPE_VOICE
- * \n Exceptionally, CTS_NUM_TYPE_CUSTOM is exclusive.
- * CTS_NUM_TYPE_CUSTOM should be handled earlier.
- */
-enum NUMBERTYPE{
-       CTS_NUM_TYPE_NONE = 0,
-       CTS_NUM_TYPE_HOME = 1<<0,/**< a telephone number associated with a residence */
-       CTS_NUM_TYPE_WORK = 1<<1,/**< a telephone number associated with a place of work */
-       CTS_NUM_TYPE_VOICE = 1<<2,/**< a voice telephone number */
-       CTS_NUM_TYPE_FAX = 1<<3,/**< a facsimile telephone number */
-       CTS_NUM_TYPE_MSG = 1<<4,/**< the telephone number has voice messaging support */
-       CTS_NUM_TYPE_CELL = 1<<5,/**< a cellular telephone number */
-       CTS_NUM_TYPE_PAGER = 1<<6,/**< a paging device telephone number */
-       CTS_NUM_TYPE_BBS = 1<<7,/**< a bulletin board system telephone number */
-       CTS_NUM_TYPE_MODEM = 1<<8,/**< a MODEM connected telephone number */
-       CTS_NUM_TYPE_CAR = 1<<9,/**< a car-phone telephone number */
-       CTS_NUM_TYPE_ISDN = 1<<10,/**< an ISDN service telephone number */
-       CTS_NUM_TYPE_VIDEO = 1<<11,/**< a video conferencing telephone number */
-       CTS_NUM_TYPE_PCS = 1<<12,/**< a personal communication services telephone number */
-
-       CTS_NUM_TYPE_ASSISTANT = 1<<30,/**< a additional type for assistant */
-       CTS_NUM_TYPE_CUSTOM = 1<<31,/**< Custom number type */
-};
-
-enum EMAILTYPE{
-       CTS_EMAIL_TYPE_NONE = 0,/**< Other */
-       CTS_EMAIL_TYPE_HOME = 1<<0,/**< . */
-       CTS_EMAIL_TYPE_WORK = 1<<1,/**< . */
-};
-
-enum ADDRESSTYPE{
-       CTS_ADDR_TYPE_NONE = 0,/**< . */
-       CTS_ADDR_TYPE_HOME = 1<<0,/**< a delivery address for a residence */
-       CTS_ADDR_TYPE_WORK = 1<<1,/**< a delivery address for a place of work */
-       CTS_ADDR_TYPE_DOM = 1<<2,/**< a domestic delivery address */
-       CTS_ADDR_TYPE_INTL = 1<<3,/**< an international delivery address */
-       CTS_ADDR_TYPE_POSTAL = 1<<4,/**< a postal delivery address */
-       CTS_ADDR_TYPE_PARCEL = 1<<5,/**< a parcel delivery address */
-};
-
-enum WEBTYPE{
-       CTS_WEB_TYPE_NONE,/**< Other */
-       CTS_WEB_TYPE_HOME,/**< . */
-       CTS_WEB_TYPE_WORK,/**< . */
-};
-
-enum PLOGTYPE{
-       CTS_PLOG_TYPE_NONE,
-       CTS_PLOG_TYPE_VOICE_INCOMMING = 1,/**< . */
-       CTS_PLOG_TYPE_VOICE_OUTGOING = 2,/**< . */
-       CTS_PLOG_TYPE_VIDEO_INCOMMING = 3,/**< . */
-       CTS_PLOG_TYPE_VIDEO_OUTGOING = 4,/**< . */
-       CTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN = 5,/**< Not confirmed missed call */
-       CTS_PLOG_TYPE_VOICE_INCOMMING_SEEN = 6,/**< Confirmed missed call */
-       CTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN = 7,/**< Not confirmed missed video call */
-       CTS_PLOG_TYPE_VIDEO_INCOMMING_SEEN = 8,/**< Confirmed missed video call */
-       CTS_PLOG_TYPE_VOICE_REJECT = 9,/**< . */
-       CTS_PLOG_TYPE_VIDEO_REJECT = 10,/**< . */
-       CTS_PLOG_TYPE_VOICE_BLOCKED = 11,/**< . */
-       CTS_PLOG_TYPE_VIDEO_BLOCKED = 12,/**< . */
-
-       CTS_PLOG_TYPE_MMS_INCOMMING = 101,/**< . */
-       CTS_PLOG_TYPE_MMS_OUTGOING = 102,/**< . */
-       CTS_PLOG_TYPE_SMS_INCOMMING = 103,/**< . */
-       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
-};
-
-enum EVENTTYPE{
-       CTS_EVENT_TYPE_BIRTH,/**< . */
-       CTS_EVENT_TYPE_ANNIVERSARY/**< . */
-};
-
-enum ADDRESSBOOKTYPE{
-       CTS_ADDRESSBOOK_TYPE_INTERNAL, /**< . */
-       CTS_ADDRESSBOOK_TYPE_EXCHANGE, /**< . */
-       CTS_ADDRESSBOOK_TYPE_GOOGLE, /**< . */
-       CTS_ADDRESSBOOK_TYPE_YAHOO, /**< . */
-       CTS_ADDRESSBOOK_TYPE_FACEBOOK, /**< . */
-       CTS_ADDRESSBOOK_TYPE_OTHER, /**< . */
-};
-
-/**
- * Use for contacts_svc_insert_custom_type(),
- * contacts_svc_delete_custom_type(), contacts_svc_find_custom_type().
- */
-typedef enum {
-       CTS_TYPE_CLASS_EXTEND_DATA=0,/**< Extend Data type(@ref CONTACTS_SVC_EXTEND) */
-       CTS_TYPE_CLASS_NUM=1,/**< Custom Number type */
-}cts_custom_type_class;
-
-/**
- * This function inserts a User defined type into database.
- * This api assigns a index of the group automatically.
- * \n The returned index is unique & non-reusable.
- *
- * @param[in] type_class #cts_custom_type_class
- * @param[in] type_name Name of Custom Type
- * @return the index of the inserted custom type on success, Negative value(#cts_error) on error
- */
-int contacts_svc_insert_custom_type(cts_custom_type_class type_class, char *type_name);
-
-/**
- * This function deletes a user defined type in database.
- *
- * @param[in] type_class #cts_custom_type_class
- * @param[in] index The index of User defined type to delete in database.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_delete_custom_type(cts_custom_type_class type_class, int index);
-
-
-/**
- * This function gets name of custom type.
- * Obtained string should be free using by free().
- * @param[in] type_class #cts_custom_type_class
- * @param[in] index The index of User defined type.
- * @return The gotten information, or NULL if no value is obtained or error
- */
-char* contacts_svc_get_custom_type(cts_custom_type_class type_class, int index);
-
-/**
- * This function gets index of user defined type of #name.
- *
- * @param[in] type_class #cts_custom_type_class
- * @param[in] type_name The name of type for searching
- * @return index of found Custom type on success, Negative value(#cts_error) on error
- */
-int contacts_svc_find_custom_type(cts_custom_type_class type_class, char *type_name);
-
-/*
- * @}
- */
-
-/**
- * @defgroup   CONTACTS_SVC_EXTEND Using the Extend Data for Contact
- * @ingroup    CONTACTS_SVC
- * @addtogroup CONTACTS_SVC_EXTEND
- * @{
- *
- * This is description of usages of extend data related with a contact.
- *
- * @section extend_sec1 Properties
- * - The extend data is contacts service value(#CTSvalue).
- * - The extend data only exist for contact struct(#CTSstruct).
- * - The type of extend data is defined
- * by contacts_svc_insert_custom_type() with #CTS_TYPE_CLASS_EXTEND_DATA.
- * - The extend data is stored to contact by contacts_svc_struct_store_value().
- * - Extend data can be stored only one at each type in contacts.
- * - The index of custom type is used as the field parameter of contacts_svc_struct_store_value().
- * - The composition of the extend data(#EXTENDVALUE)
- *   -# #CTS_EXTEND_VAL_DATA1_INT
- *   -# #CTS_EXTEND_VAL_DATA2_STR
- *   -# #CTS_EXTEND_VAL_DATA3_STR
- *   -# #CTS_EXTEND_VAL_DATA4_STR
- *   -# #CTS_EXTEND_VAL_DATA5_STR
- *   -# #CTS_EXTEND_VAL_DATA6_STR
- *   -# #CTS_EXTEND_VAL_DATA7_STR
- *   -# #CTS_EXTEND_VAL_DATA8_STR
- *   -# #CTS_EXTEND_VAL_DATA9_STR
- *   -# #CTS_EXTEND_VAL_DATA10_STR
- *
- * @section extend_sec2 Usages
- * - Notice
- * \n The extend data has values of fixed type.
- * \n Therefore if you want to save values of the other types, convert to string.
- * \n This mechanism is a supplementary mechanism. Do not abuse.
- * - example
- * @code
- #include <stdio.h>
- #include <glib.h>
- #include <contacts-svc.h>
-
- static void print_extend_contact(CTSstruct *contact)
- {
-    int ret;
-    CTSvalue *value;
-    GSList *get_list, *cursor;
-    value = NULL;
-    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));
-
-    value = NULL;
-    ret = contacts_svc_find_custom_type(CTS_TYPE_CLASS_EXTEND_DATA, "YomiName");
-    ret = contacts_svc_struct_get_value(contact, ret, &value);
-    if(CTS_SUCCESS == ret) {
-       printf("extend1 data2 : %s\n", contacts_svc_value_get_str(value, CTS_EXTEND_VAL_DATA2_STR));
-       printf("extend1 data3 : %s\n", contacts_svc_value_get_str(value, CTS_EXTEND_VAL_DATA3_STR));
-       printf("extend1 data4 : %s\n", contacts_svc_value_get_str(value, CTS_EXTEND_VAL_DATA4_STR));
-    }
-    value = NULL;
-    ret = contacts_svc_find_custom_type(CTS_TYPE_CLASS_EXTEND_DATA, "Family");
-    ret = contacts_svc_struct_get_value(contact, ret, &value);
-    if(CTS_SUCCESS == ret) {
-       printf("extend2 data2 : %s\n", contacts_svc_value_get_str(value, CTS_EXTEND_VAL_DATA2_STR));
-       printf("extend2 data3 : %s\n", contacts_svc_value_get_str(value, CTS_EXTEND_VAL_DATA3_STR));
-       printf("extend2 data4 : %s\n", contacts_svc_value_get_str(value, CTS_EXTEND_VAL_DATA4_STR));
-    }
-    get_list = NULL;
-    contacts_svc_struct_get_list(contact, 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));
-       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));
-    }
- }
-
- void extend_data_test(void)
- {
-    int ret, index;
-    CTSstruct *contact;
-    CTSvalue *name, *number1, *extend_value;
-    GSList *numbers=NULL;
-
-    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, "People");
-       contacts_svc_value_set_str(name, CTS_NAME_VAL_LAST_STR, "Japan");
-    }
-    contacts_svc_struct_store_value(contact, CTS_CF_NAME_VALUE, name);
-    contacts_svc_value_free(name);
-
-    number1 = contacts_svc_value_new(CTS_VALUE_NUMBER);
-    if(number1) {
-       contacts_svc_value_set_str(number1, CTS_NUM_VAL_NUMBER_STR, "0333333333");
-       contacts_svc_value_set_int(number1, CTS_NUM_VAL_TYPE_INT, CTS_NUM_TYPE_MOBILE);
-       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);
-
-    extend_value = contacts_svc_value_new(CTS_VALUE_EXTEND);
-    if(extend_value) {
-       contacts_svc_value_set_str(extend_value, CTS_EXTEND_VAL_DATA2_STR, "YomiFirstName");
-       contacts_svc_value_set_str(extend_value, CTS_EXTEND_VAL_DATA3_STR, "YomiLastName");
-       contacts_svc_value_set_str(extend_value, CTS_EXTEND_VAL_DATA4_STR, "YomiCompanyName");
-    }
-    ret = contacts_svc_find_custom_type(CTS_TYPE_CLASS_EXTEND_DATA, "YomiName");
-    if(CTS_ERR_DB_RECORD_NOT_FOUND == ret)
-       ret = contacts_svc_insert_custom_type(CTS_TYPE_CLASS_EXTEND_DATA, "YomiName");
-    contacts_svc_struct_store_value(contact, ret, extend_value);
-    contacts_svc_value_free(extend_value);
-
-    extend_value = contacts_svc_value_new(CTS_VALUE_EXTEND);
-    if(extend_value) {
-       contacts_svc_value_set_str(extend_value, CTS_EXTEND_VAL_DATA2_STR, "Children1");
-       contacts_svc_value_set_str(extend_value, CTS_EXTEND_VAL_DATA3_STR, "Children2");
-       contacts_svc_value_set_str(extend_value, CTS_EXTEND_VAL_DATA4_STR, "Children3");
-    }
-    ret = contacts_svc_find_custom_type(CTS_TYPE_CLASS_EXTEND_DATA, "Family");
-    if(CTS_ERR_DB_RECORD_NOT_FOUND == ret)
-       ret = contacts_svc_insert_custom_type(CTS_TYPE_CLASS_EXTEND_DATA, "Family");
-    contacts_svc_struct_store_value(contact, ret, extend_value);
-    contacts_svc_value_free(extend_value);
-
-    index = contacts_svc_insert_contact(0, contact);
-    contacts_svc_struct_free(contact);
-    contact = NULL;
-
-    ret = contacts_svc_get_contact(index, &contact);
-    if(ret < 0)
-    {
-       printf("No found record\n");
-       return;
-    }
-    print_extend_contact(contact);
-
-    //update test
-
-    extend_value = NULL;
-    ret = contacts_svc_find_custom_type(CTS_TYPE_CLASS_EXTEND_DATA, "Family");
-    ret = contacts_svc_struct_get_value(contact, ret, &extend_value);
-    if(CTS_SUCCESS == ret)
-       contacts_svc_value_set_str(extend_value, CTS_EXTEND_VAL_DATA2_STR, "Children4");
-    contacts_svc_struct_store_value(contact, ret, extend_value);
-
-    contacts_svc_update_contact(contact);
-    contacts_svc_struct_free(contact);
-    contact = NULL;
-
-    ret = contacts_svc_get_contact(index, &contact);
-    if(ret < 0)
-    {
-       printf("No found record\n");
-       return;
-    }
-    print_extend_contact(contact);
-    contacts_svc_struct_free(contact);
- }
-
- int main()
- {
-    contacts_svc_connect();
-
-    extend_data_test();
-
-    contacts_svc_disconnect();
-
-    return 0;
- }
-
- * @endcode
- *
- * @}
- */
-
-//-->
-
-#endif //__CTS_TYPES_H__
-
diff --git a/src/cts-utils.c b/src/cts-utils.c
deleted file mode 100755 (executable)
index 4d252ef..0000000
+++ /dev/null
@@ -1,1088 +0,0 @@
-/*
- * 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 <sys/time.h>
-#include <sys/stat.h>
-#include <vconf.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <dirent.h>
-
-#include "cts-internal.h"
-#include "cts-schema.h"
-#include "cts-sqlite.h"
-#include "cts-socket.h"
-#include "cts-normalize.h"
-#include "cts-inotify.h"
-#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;
-static const char *CTS_NOTI_PLOG_CHANGED="/opt/data/contacts-svc/.CONTACTS_SVC_PLOG_CHANGED";
-static const char *CTS_NOTI_FAVORITE_CHANGED="/opt/data/contacts-svc/.CONTACTS_SVC_FAVOR_CHANGED";
-static const char *CTS_NOTI_SPEEDDIAL_CHANGED="/opt/data/contacts-svc/.CONTACTS_SVC_SPEED_CHANGED";
-static const char *CTS_NOTI_ADDRBOOK_CHANGED="/opt/data/contacts-svc/.CONTACTS_SVC_AB_CHANGED";
-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=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;
-static bool version_up=false;
-
-static bool contact_change=false;
-static bool plog_change=false;
-static bool missed_change=false;
-static bool favor_change=false;
-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;
-static int default_lang = -1;
-
-static void cts_vconf_callback(keynode_t *key, void *data)
-{
-       //if(!strcmp(vconf_keynode_get_name(key), CTS_VCONF_SORTING_ORDER));
-       if (CTS_ORDER_OF_SORTING == (int)data)
-               name_sorting_order = vconf_keynode_get_int(key);
-       else if (CTS_ORDER_OF_DISPLAY == (int)data)
-               name_display_order = vconf_keynode_get_int(key);
-       else if (CTS_ORDER_OF_DISPLAY + 1 == (int)data)
-               default_lang = vconf_keynode_get_int(key);
-}
-
-int cts_get_default_language(void)
-{
-       if (default_lang < 0) {
-               int ret;
-               ret = vconf_get_int(CTS_VCONF_DEFAULT_LANGUAGE, &default_lang);
-               warn_if(ret < 0, "vconf_get_int() Failed(%d)", ret);
-       }
-       return default_lang;
-}
-
-void cts_set_contact_noti(void)
-{
-       contact_change = true;
-}
-void cts_set_plog_noti(void)
-{
-       plog_change = true;
-}
-void cts_set_missed_call_noti(void)
-{
-       missed_change = true;
-}
-void cts_set_favor_noti(void)
-{
-       favor_change = true;
-}
-void cts_set_speed_noti(void)
-{
-       speed_change = true;
-}
-void cts_set_addrbook_noti(void)
-{
-       addrbook_change = true;
-}
-void cts_set_group_noti(void)
-{
-       group_change = true;
-}
-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)
-{
-       int fd = open(CTS_NOTI_CONTACT_CHANGED, O_TRUNC | O_RDWR);
-       if (0 <= fd) {
-               close(fd);
-               contact_change = false;
-       }
-}
-
-static inline void cts_noti_publish_plog_change(void)
-{
-       int fd = open(CTS_NOTI_PLOG_CHANGED, O_TRUNC | O_RDWR);
-       if (0 <= fd) {
-               close(fd);
-               plog_change = false;
-       }
-}
-
-static inline void cts_noti_publish_missed_call_change(void)
-{
-       int fd = open(CTS_NOTI_MISSED_CALL_CHANGED, O_TRUNC | O_RDWR);
-       if (0 <= fd) {
-               close(fd);
-               missed_change = false;
-       }
-}
-
-static inline void cts_noti_publish_favor_change(void)
-{
-       int fd = open(CTS_NOTI_FAVORITE_CHANGED, O_TRUNC | O_RDWR);
-       if (0 <= fd) {
-               close(fd);
-               favor_change = false;
-       }
-}
-
-static inline void cts_noti_publish_speed_change(void)
-{
-       int fd = open(CTS_NOTI_SPEEDDIAL_CHANGED, O_TRUNC | O_RDWR);
-       if (0 <= fd) {
-               close(fd);
-               speed_change = false;
-       }
-}
-
-static inline void cts_noti_publish_addrbook_change(void)
-{
-       int fd = open(CTS_NOTI_ADDRBOOK_CHANGED, O_TRUNC | O_RDWR);
-       if (0 <= fd) {
-               close(fd);
-               addrbook_change = false;
-       }
-}
-
-static inline void cts_noti_publish_group_change(void)
-{
-       int fd = open(CTS_NOTI_GROUP_CHANGED, O_TRUNC | O_RDWR);
-       if (0 <= fd) {
-               close(fd);
-               group_change = false;
-       }
-}
-
-static inline void cts_noti_publish_group_rel_change(void)
-{
-       int fd = open(CTS_NOTI_GROUP_RELATION_CHANGED, O_TRUNC | O_RDWR);
-       if (0 <= fd) {
-               close(fd);
-               group_rel_change = false;
-       }
-}
-
-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)
-{
-       int ret = -1, progress;
-
-       cts_mutex_lock(CTS_MUTEX_TRANSACTION);
-       if (transaction_count <= 0)
-       {
-               ret = cts_query_exec("BEGIN IMMEDIATE TRANSACTION"); //taken 600ms
-               progress = 100000;
-               while (CTS_ERR_DB_LOCK == ret && progress<CTS_COMMIT_TRY_MAX) {
-                       usleep(progress);
-                       ret = cts_query_exec("BEGIN IMMEDIATE TRANSACTION");
-                       progress *= 2;
-               }
-               if(CTS_SUCCESS != ret) {
-                       ERR("cts_query_exec() Failed(%d)", ret);
-                       cts_mutex_unlock(CTS_MUTEX_TRANSACTION);
-                       return ret;
-               }
-
-               transaction_count = 0;
-
-               const char *query = "SELECT ver FROM "CTS_TABLE_VERSION;
-               transaction_ver = cts_query_get_first_int_result(query);
-               version_up = false;
-       }
-       transaction_count++;
-       INFO("transaction_count : %d", transaction_count);
-       cts_mutex_unlock(CTS_MUTEX_TRANSACTION);
-
-       return CTS_SUCCESS;
-}
-
-static inline void cts_cancel_changes(void)
-{
-       contact_change = false;
-       plog_change = false;
-       missed_change = false;
-       favor_change = false;
-       speed_change = false;
-       addrbook_change = false;
-       group_change = false;
-       group_rel_change = false;
-       link_change = false;
-}
-
-API int contacts_svc_end_trans(bool is_success)
-{
-       int ret = -1, progress;
-       char query[CTS_SQL_MIN_LEN];
-
-       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);
-               cts_mutex_unlock(CTS_MUTEX_TRANSACTION);
-               return CTS_SUCCESS;
-       }
-
-       if (false == is_success) {
-               cts_cancel_changes();
-               ret = cts_query_exec("ROLLBACK TRANSACTION");
-               cts_mutex_unlock(CTS_MUTEX_TRANSACTION);
-               return CTS_SUCCESS;
-       }
-
-       if (version_up) {
-               transaction_ver++;
-               snprintf(query, sizeof(query), "UPDATE %s SET ver = %d",
-                               CTS_TABLE_VERSION, transaction_ver);
-               ret = cts_query_exec(query);
-               warn_if(CTS_SUCCESS != ret, "cts_query_exec(version up) Failed(%d)", ret);
-       }
-
-       progress = 400000;
-       ret = cts_query_exec("COMMIT TRANSACTION");
-       while (CTS_ERR_DB_LOCK == ret && progress<CTS_COMMIT_TRY_MAX) {
-               usleep(progress);
-               ret = cts_query_exec("COMMIT TRANSACTION");
-               progress *= 2;
-       }
-       if (CTS_SUCCESS != ret) {
-               int tmp_ret;
-               ERR("cts_query_exec() Failed(%d)", ret);
-               cts_cancel_changes();
-               tmp_ret = cts_query_exec("ROLLBACK TRANSACTION");
-               warn_if(CTS_SUCCESS != tmp_ret, "cts_query_exec(ROLLBACK) Failed(%d)", tmp_ret);
-               cts_mutex_unlock(CTS_MUTEX_TRANSACTION);
-               return ret;
-       }
-       cts_mutex_unlock(CTS_MUTEX_TRANSACTION);
-
-       if (contact_change) cts_noti_publish_contact_change();
-       if (plog_change) cts_noti_publish_plog_change();
-       if (missed_change) cts_noti_publish_missed_call_change();
-       if (favor_change) cts_noti_publish_favor_change();
-       if (speed_change) cts_noti_publish_speed_change();
-       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;
-}
-
-int cts_get_next_ver(void)
-{
-       const char *query;
-
-       if (0 < transaction_count) {
-               version_up = true;
-               return transaction_ver + 1;
-       }
-
-       query = "SELECT ver FROM "CTS_TABLE_VERSION;
-       return (1+cts_query_get_first_int_result(query));
-}
-
-void cts_deregister_noti(void)
-{
-       int ret;
-
-       cts_inotify_close();
-
-       ret = vconf_ignore_key_changed(CTS_VCONF_SORTING_ORDER, cts_vconf_callback);
-       retm_if(ret<0,"vconf_ignore_key_changed(%s) Failed(%d)",CTS_VCONF_SORTING_ORDER,ret);
-       ret = vconf_ignore_key_changed(CTS_VCONF_DISPLAY_ORDER, cts_vconf_callback);
-       retm_if(ret<0,"vconf_ignore_key_changed(%s) Failed(%d)",CTS_VCONF_DISPLAY_ORDER,ret);
-       ret = vconf_ignore_key_changed(CTS_VCONF_DEFAULT_LANGUAGE, cts_vconf_callback);
-       retm_if(ret<0,"vconf_ignore_key_changed(%s) Failed(%d)",CTS_VCONF_DEFAULT_LANGUAGE,ret);
-}
-
-static inline int cts_conf_init_name_info(void)
-{
-       int ret;
-
-       ret = vconf_get_int(CTS_VCONF_SORTING_ORDER, &name_sorting_order);
-       if (ret < 0) {
-               ERR("vconf_get_int() Failed(%d)", ret);
-               name_sorting_order = CTS_ORDER_NAME_FIRSTLAST;
-       }
-
-       ret = vconf_get_int(CTS_VCONF_DISPLAY_ORDER, &name_display_order);
-       if (ret < 0) {
-               ERR("vconf_get_int() Failed(%d)", ret);
-               name_display_order = CTS_ORDER_NAME_FIRSTLAST;
-       }
-
-       ret = vconf_get_int(CTS_VCONF_DEFAULT_LANGUAGE, &default_lang);
-       warn_if(ret < 0, "vconf_get_int() Failed(%d)", ret);
-
-       ret = vconf_notify_key_changed(CTS_VCONF_SORTING_ORDER,
-                       cts_vconf_callback, (void *)CTS_ORDER_OF_SORTING);
-       retvm_if(ret<0, CTS_ERR_VCONF_FAILED, "vconf_notify_key_changed() Failed(%d)", ret);
-       ret = vconf_notify_key_changed(CTS_VCONF_DISPLAY_ORDER,
-                       cts_vconf_callback, (void *)CTS_ORDER_OF_DISPLAY);
-       retvm_if(ret<0, CTS_ERR_VCONF_FAILED, "vconf_notify_key_changed() Failed(%d)", ret);
-       ret = vconf_notify_key_changed(CTS_VCONF_DEFAULT_LANGUAGE,
-                       cts_vconf_callback, (void *)CTS_ORDER_OF_DISPLAY+1);
-       retvm_if(ret<0, CTS_ERR_VCONF_FAILED, "vconf_notify_key_changed() Failed(%d)", ret);
-
-       return CTS_SUCCESS;
-}
-
-void cts_register_noti(void)
-{
-       int ret;
-
-       ret = cts_inotify_init();
-       retm_if(CTS_SUCCESS != ret, "cts_inotify_init() Failed(%d)", ret);
-
-       ret = cts_conf_init_name_info();
-       retm_if(CTS_SUCCESS != ret, "cts_conf_init_name_info() Failed(%d)", ret);
-}
-
-API int contacts_svc_set_order(cts_order_op op_code, cts_order_type order)
-{
-       int ret;
-       const char *op;
-
-       retvm_if(CTS_ORDER_NAME_FIRSTLAST != order && CTS_ORDER_NAME_LASTFIRST != order,
-                       CTS_ERR_ARG_INVALID, "The parameter(order:%d) is Invalid", order);
-
-       if (CTS_ORDER_OF_SORTING == op_code)
-               op = CTS_VCONF_SORTING_ORDER;
-       else
-               op = CTS_VCONF_DISPLAY_ORDER;
-
-       ret = vconf_set_int(op, order);
-       retvm_if(ret<0, CTS_ERR_VCONF_FAILED, "vconf_set_int(%s) Failed(%d)", op, ret);
-
-       if (CTS_ORDER_OF_SORTING == op_code)
-               name_sorting_order = order;
-       else
-               name_display_order = order;
-
-       return CTS_SUCCESS;
-}
-
-API cts_order_type contacts_svc_get_order(cts_order_op op_code)
-{
-       int ret;
-
-       if (CTS_ORDER_OF_SORTING == op_code) {
-               if (name_sorting_order < 0) {
-                       ret = vconf_get_int(CTS_VCONF_SORTING_ORDER, &name_sorting_order);
-                       retvm_if(ret<0, CTS_ERR_VCONF_FAILED, "vconf_get_int() Failed(%d)", ret);
-               }
-
-               return name_sorting_order;
-       }
-       else{
-               if (name_display_order < 0) {
-                       ret = vconf_get_int(CTS_VCONF_DISPLAY_ORDER, &name_display_order);
-                       retvm_if(ret<0, CTS_ERR_VCONF_FAILED, "vconf_get_int() Failed(%d)", ret);
-               }
-
-               return name_display_order;
-       }
-}
-
-static inline const char* cts_noti_get_file_path(int type)
-{
-       const char *noti;
-       switch (type)
-       {
-       case CTS_SUBSCRIBE_CONTACT_CHANGE:
-               noti = CTS_NOTI_CONTACT_CHANGED;
-               break;
-       case CTS_SUBSCRIBE_PLOG_CHANGE:
-               noti = CTS_NOTI_PLOG_CHANGED;
-               break;
-       case CTS_SUBSCRIBE_MISSED_CALL_CHANGE:
-               noti = CTS_NOTI_MISSED_CALL_CHANGED;
-               break;
-       case CTS_SUBSCRIBE_FAVORITE_CHANGE:
-               noti = CTS_NOTI_FAVORITE_CHANGED;
-               break;
-       case CTS_SUBSCRIBE_GROUP_CHANGE:
-               noti = CTS_NOTI_GROUP_CHANGED;
-               break;
-       case CTS_SUBSCRIBE_SPEEDDIAL_CHANGE:
-               noti = CTS_NOTI_SPEEDDIAL_CHANGED;
-               break;
-       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;
-       }
-
-       return noti;
-}
-
-API int contacts_svc_subscribe_change(cts_subscribe_type noti_type,
-               void (*cb)(void *), void *user_data)
-{
-       int ret;
-       const char *noti;
-
-       noti = cts_noti_get_file_path(noti_type);
-       retvm_if(NULL == noti, CTS_ERR_ARG_INVALID,
-                       "cts_noti_get_file_path(%d) Failed", noti_type);
-
-       ret = cts_inotify_subscribe(noti, cb, user_data);
-       retvm_if(CTS_SUCCESS != ret, ret,
-                       "cts_inotify_subscribe(%d) Failed(%d)", noti_type, ret);
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_unsubscribe_change(cts_subscribe_type noti_type,
-               void (*cb)(void *))
-{
-       int ret;
-       const char *noti;
-
-       noti = cts_noti_get_file_path(noti_type);
-       retvm_if(NULL == noti, CTS_ERR_ARG_INVALID,
-                       "cts_noti_get_file_path(%d) Failed", noti_type);
-
-       ret = cts_inotify_unsubscribe(noti, cb);
-       retvm_if(CTS_SUCCESS != ret, ret,
-                       "cts_inotify_unsubscribe(%d) Failed(%d)", noti_type, ret);
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_unsubscribe_change_with_data(cts_subscribe_type noti_type,
-               void (*cb)(void *), void *user_data)
-{
-       int ret;
-       const char *noti;
-
-       noti = cts_noti_get_file_path(noti_type);
-       retvm_if(NULL == noti, CTS_ERR_ARG_INVALID,
-                       "cts_noti_get_file_path(%d) Failed", noti_type);
-
-       ret = cts_inotify_unsubscribe_with_data(noti, cb, user_data);
-       retvm_if(CTS_SUCCESS != ret, ret,
-                       "cts_inotify_unsubscribe_with_data(%d) Failed(%d)", noti_type, ret);
-
-       return CTS_SUCCESS;
-}
-
-int cts_exist_file(char *path)
-{
-       int fd = open(path, O_RDONLY);
-       // errno == ENOENT
-       retvm_if(fd < 0, CTS_ERR_FAIL, "Open(%s) Failed(%d)", path, errno);
-       close(fd);
-       return CTS_SUCCESS;
-}
-
-#define CTS_COPY_SIZE_MAX 4096
-API int contacts_svc_get_image(cts_img_t img_type, int index, char **img_path)
-{
-       int ret;
-       cts_stmt stmt;
-       char *img;
-       char query[CTS_SQL_MIN_LEN] = {0};
-
-       retvm_if(CTS_IMG_FULL != img_type && CTS_IMG_NORMAL != img_type,
-                       CTS_ERR_ARG_INVALID,
-                       "You have to use CTS_IMG_FULL or CTS_IMG_NORMAL for img_type");
-       retvm_if(NULL == img_path, CTS_ERR_ARG_INVALID, "img_path is NULL");
-
-       snprintf(query, sizeof(query),
-                               "SELECT image%d FROM %s WHERE contact_id = %d",
-                               img_type, CTS_TABLE_CONTACTS, index);
-
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       *img_path = NULL;
-       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;
-       }
-
-       img = cts_stmt_get_text(stmt, 0);
-       if (img) {
-               char tmp_path[CTS_IMG_PATH_SIZE_MAX];
-               snprintf(tmp_path, sizeof(tmp_path), "%s/%s", CTS_IMAGE_LOCATION, img);
-               ret = cts_exist_file(tmp_path);
-               retvm_if(ret, ret, "cts_exist_file(%s) Failed(%d)", tmp_path, ret);
-               *img_path = strdup(tmp_path);
-               if (NULL == *img_path) {
-                       ERR("strdup() Failed");
-                       cts_stmt_finalize(stmt);
-                       return CTS_ERR_OUT_OF_MEMORY;
-               }
-       }
-       cts_stmt_finalize(stmt);
-       return CTS_SUCCESS;
-}
-
-int cts_contact_delete_image_file(int img_type, int index)
-{
-       int ret;
-       cts_stmt stmt;
-       char *tmp_path;
-       char query[CTS_SQL_MIN_LEN];
-       snprintf(query, sizeof(query),
-                       "SELECT image%d FROM %s WHERE contact_id = %d",
-                       img_type, CTS_TABLE_CONTACTS, index);
-
-       stmt = cts_query_prepare(query);
-       if (NULL == stmt) {
-               ERR("cts_query_prepare() Failed");
-               return CTS_ERR_DB_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;
-       }
-
-       tmp_path = cts_stmt_get_text(stmt, 0);
-       if (tmp_path) {
-               char full_path[CTS_IMG_PATH_SIZE_MAX];
-               snprintf(full_path, sizeof(full_path), "%s/%s", CTS_IMAGE_LOCATION, tmp_path);
-               ret = unlink(full_path);
-               warn_if (ret < 0, "unlink(%s) Failed(%d)", full_path, errno);
-       }
-       cts_stmt_finalize(stmt);
-       return CTS_SUCCESS;
-}
-
-static int cts_copy_file(const char *src, const char *dest)
-{
-       int ret;
-       int size;
-       int src_fd, dest_fd;
-       char buf[CTS_COPY_SIZE_MAX];
-
-       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);
-               close(src_fd);
-               return CTS_ERR_FAIL;
-       }
-
-       while ((size = read(src_fd, buf, CTS_COPY_SIZE_MAX)) > 0) {
-               ret = write(dest_fd, buf, size);
-               if (ret <= 0) {
-                       if (EINTR == errno)
-                               continue;
-                       else {
-                               ERR("write() Failed(%d)", errno);
-                               if (ENOSPC == errno)
-                                       ret = CTS_ERR_NO_SPACE;
-                               else
-                                       ret = CTS_ERR_IO_ERR;
-                               close(src_fd);
-                               close(dest_fd);
-                               unlink(dest);
-                               return ret;
-                       }
-               }
-       }
-
-       fchown(dest_fd, getuid(), CTS_SECURITY_FILE_GROUP);
-       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_contact_update_image_file(int img_type, int index, char *src_img, char *dest_name, int dest_size)
-{
-       int ret;
-
-       ret = cts_contact_delete_image_file(img_type, index);
-       retvm_if(CTS_SUCCESS != ret && CTS_ERR_DB_RECORD_NOT_FOUND != ret,
-               ret, "cts_contact_delete_image_file() Failed(%d)", ret);
-
-       if (src_img) {
-               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;
-       char query[CTS_SQL_MIN_LEN];
-
-       snprintf(query, sizeof(query),
-                       "UPDATE %s SET changed_ver=%d, changed_time=%d WHERE contact_id=%d",
-                       CTS_TABLE_CONTACTS, cts_get_next_ver(), (int)time(NULL), contact_id);
-
-       ret = cts_query_exec(query);
-       retvm_if(CTS_SUCCESS != ret, ret, "cts_query_exec() Failed(%d)", ret);
-
-       cts_set_contact_noti();
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_save_image(cts_img_t img_type, int index, char *src_img)
-{
-       int ret;
-       char query[CTS_SQL_MIN_LEN];
-       char dest_img[CTS_SQL_MIN_LEN];
-       cts_stmt stmt;
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       dest_img[0] = '\0';
-       ret = cts_contact_update_image_file(img_type, index, src_img, dest_img, sizeof(dest_img));
-       if (CTS_SUCCESS != ret) {
-               ERR("cts_contact_update_image_file() Failed(%d)", ret);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-
-       snprintf(query, sizeof(query),
-                       "UPDATE %s SET changed_ver=%d, changed_time=%d, image%d=? WHERE contact_id=%d",
-                       CTS_TABLE_CONTACTS, cts_get_next_ver(), (int)time(NULL), img_type, index);
-       stmt = cts_query_prepare(query);
-       if (NULL == stmt) {
-               ERR("cts_query_prepare() Failed");
-               contacts_svc_end_trans(false);
-               return CTS_ERR_DB_FAILED;
-       }
-
-       if(*dest_img)
-               cts_stmt_bind_text(stmt, 1, dest_img);
-       ret = cts_stmt_step(stmt);
-       warn_if(CTS_SUCCESS != ret, "cts_stmt_step() Failed(%d)", ret);
-       cts_stmt_finalize(stmt);
-
-       cts_set_contact_noti();
-
-       ret = contacts_svc_end_trans(true);
-       retvm_if(ret < CTS_SUCCESS, ret, "contacts_svc_end_trans() Failed(%d)", ret);
-
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_count_with_int(cts_count_int_op op_code, int search_value)
-{
-       int ret;
-       cts_stmt stmt;
-       char query[CTS_SQL_MIN_LEN] = {0};
-
-       switch ((int)op_code) {
-       case CTS_GET_COUNT_CONTACTS_IN_ADDRESSBOOK:
-               snprintf(query, sizeof(query),
-                               "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(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(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;
-       }
-       stmt = cts_query_prepare(query);
-       retvm_if(NULL == stmt, CTS_ERR_DB_FAILED, "cts_query_prepare() Failed");
-
-       cts_stmt_bind_int(stmt, 1, search_value);
-       ret = cts_stmt_get_first_int_result(stmt);
-       if (CTS_ERR_DB_RECORD_NOT_FOUND == ret) return 0;
-       else return ret;
-}
-
-API int contacts_svc_count(cts_count_op op_code)
-{
-       int ret;
-       char query[CTS_SQL_MIN_LEN] = {0};
-
-       switch ((int)op_code)
-       {
-       case CTS_GET_ALL_CONTACT:
-               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",
-                               CTS_TABLE_SIM_SERVICES);
-               break;
-       case CTS_GET_ALL_PHONELOG:
-               snprintf(query, sizeof(query), "SELECT COUNT(*) FROM %s",
-                               CTS_TABLE_PHONELOGS);
-               break;
-       case CTS_GET_UNSEEN_MISSED_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_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;
-       }
-
-       ret = cts_query_get_first_int_result(query);
-       if (CTS_ERR_DB_RECORD_NOT_FOUND == ret) return 0;
-       else return ret;
-}
-
-int cts_convert_nicknames2textlist(GSList *src, char *dest, int dest_size)
-{
-       int len;
-       GSList *nick_repeat = src;
-       cts_nickname *nick_data;
-
-       retvm_if(dest_size <= 0 || NULL == dest, CTS_ERR_ARG_INVALID,
-                       "The parameter is Invalid. dest = %p, dest_size = %d", dest, dest_size);
-
-       len = 0;
-       dest[0] = '\0';
-       while (nick_repeat) {
-               if (NULL != (nick_data = (cts_nickname *)nick_repeat->data) && nick_data->nick) {
-                       if (!nick_data->deleted)
-                               len += snprintf(dest+len, dest_size-len, "%s,", nick_data->nick);
-               }
-               nick_repeat = nick_repeat->next;
-       }
-
-       len = strlen(dest);
-       if (len)
-               dest[len - 1] = '\0';
-       else
-               return CTS_ERR_NO_DATA;
-       return CTS_SUCCESS;
-}
-
-GSList* cts_convert_textlist2nicknames(char *text_list)
-{
-       char temp[CTS_SQL_MAX_LEN], *text_start, *text_end;
-       GSList *ret_list = NULL;
-       cts_nickname *result;
-
-       snprintf(temp, sizeof(temp), "%s", text_list);
-
-       text_start = temp;
-       while (text_start)
-       {
-               text_end = strchr(text_start, ',');
-               if (text_end)
-                       *text_end = '\0';
-
-               result = (cts_nickname *)contacts_svc_value_new(CTS_VALUE_NICKNAME);
-               if (result)
-               {
-                       result->embedded = true;
-                       result->nick = strdup(text_start);
-               }
-
-               ret_list = g_slist_append(ret_list, result);
-
-               if (text_end) {
-                       *text_end = ',';
-                       text_start = text_end+1;
-               }
-               else
-                       text_start = NULL;
-       }
-       return ret_list;
-}
-
-API int contacts_svc_import_sim(void)
-{
-       int ret;
-
-       cts_mutex_lock(CTS_MUTEX_SOCKET_FD);
-       ret = cts_request_sim_import();
-       cts_mutex_unlock(CTS_MUTEX_SOCKET_FD);
-
-       return ret;
-}
-
-API int contacts_svc_export_sim(int index)
-{
-       int 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 person_id = %d",
-                       CTS_TABLE_PERSONS, person_id);
-
-       ret = cts_query_exec(query);
-       retvm_if(CTS_SUCCESS != ret, ret, "cts_query_exec() Failed(%d)", ret);
-
-       return CTS_SUCCESS;
-}
-
-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 person_id = %d",
-                       CTS_TABLE_PERSONS, person_id);
-
-       ret = contacts_svc_begin_trans();
-       retvm_if(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret);
-
-       ret = cts_query_exec(query);
-       if (CTS_SUCCESS != ret)
-       {
-               ERR("cts_query_exec() Failed(%d)", ret);
-               contacts_svc_end_trans(false);
-               return ret;
-       }
-
-       ret = contacts_svc_end_trans(true);
-       if (ret < CTS_SUCCESS)
-               return ret;
-       else
-               return CTS_SUCCESS;
-}
-
-#ifdef CTS_TIMECHECK
-double cts_set_start_time(void)
-{
-       struct timeval tv;
-       double curtime;
-
-       gettimeofday(&tv, NULL);
-       curtime = tv.tv_sec * 1000 + (double)tv.tv_usec/1000;
-       return curtime;
-}
-
-double cts_exec_time(double start)
-{
-       double end = cts_set_start_time();
-       return (end - start - correction);
-}
-
-int cts_init_time(void)
-{
-       double temp_t;
-       temp_t = cts_set_start_time();
-       correction = cts_exec_time(temp_t);
-
-       return 0;
-}
-#endif
-
diff --git a/src/cts-utils.h b/src/cts-utils.h
deleted file mode 100755 (executable)
index d83a14c..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * 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_UTILS_H__
-#define __CTS_UTILS_H__
-
-#include <stdbool.h>
-
-#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"
-
-void cts_deregister_noti(void);
-void cts_register_noti(void);
-int cts_get_default_language(void);
-void cts_set_contact_noti(void);
-void cts_set_plog_noti(void);
-void cts_set_missed_call_noti(void);
-void cts_set_favor_noti(void);
-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_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__
-//<!--
-/**
- * This function starts database transaction
- * If you want to handle a transaction, use it.
- *
- * @par Multiple inserting case
- * case1 has only one DB commit. Therefore it is faster than case 2.
- * And if 5th inserted contact is failed,
- * case 1 insert nothing but case 2 insert 1,2,3 and 4th contacts.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @code
- * //case 1
- * contacts_svc_begin_trans();
- * for(i = 0; i< 20; i++) {
- *    if(CTS_SUCCESS != "insert api") {
- *       contacts_svc_end_trans(false);
- *       return -1;
- *    }
- * }
- * ret = contacts_svc_end_trans(true);
- * if(ret < CTS_SUCCESS){
- *  printf("all work were rollbacked");
- *   return;
- * }
- *
- * //case 2
- * for(i = 0; i< 20; i++) {
- *    if(CTS_SUCCESS != "insert api") {
- *       return -1;
- *    }
- * }
- * @endcode
- */
-int contacts_svc_begin_trans(void);
-
-/**
- * This function finishes database transaction of contacts service
- * If you want to handle a transaction, use it.
- * If returned value is error, the transaction was rollbacked.
- * When transaction is success, it returns the last contacts version.
- *
- * @param[in] is_success true : commit, false : rollback
- * @return #CTS_SUCCESS or the last contact version(when success) on success,
- *         Negative value(#cts_error) on error
- */
-int contacts_svc_end_trans(bool is_success);
-
-/**
- * A kind of order in contacts service of contacts service
- * @see contacts_svc_get_order()
- */
-typedef enum{
-       CTS_ORDER_NAME_FIRSTLAST = 0, /**<First Name first */
-       CTS_ORDER_NAME_LASTFIRST = 1 /**<Last Name first */
-}cts_order_type;
-
-/**
- * Use for contacts_svc_get_order().
- */
-typedef enum{
-       CTS_ORDER_OF_SORTING, /**< Sorting Order */
-       CTS_ORDER_OF_DISPLAY /**< Display Order */
-}cts_order_op;
-
-/**
- * This function gets the display or sorting order(Firstname first or LastName first)
- *
- * @param[in] op_code #cts_order_op
- * @return #CTS_ORDER_NAME_FIRSTLAST or #CTS_ORDER_NAME_LASTFIRST on success,
- *           \n Negative value(#cts_error) on error
- */
-cts_order_type contacts_svc_get_order(cts_order_op op_code);
-
-/**
- * This function sets the display or sorting order(Firstname first or LastName first)
- *
- * @param[in] op_code #cts_order_op
- * @param[in] order order type(#cts_order_type)
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_set_order(cts_order_op op_code, cts_order_type order);
-
-/**
- * Use for contacts_svc_subscribe_change(), contacts_svc_unsubscribe_change()
- */
-typedef enum{
-       CTS_SUBSCRIBE_CONTACT_CHANGE,
-       CTS_SUBSCRIBE_PLOG_CHANGE,
-       CTS_SUBSCRIBE_FAVORITE_CHANGE,
-       CTS_SUBSCRIBE_GROUP_CHANGE,
-       CTS_SUBSCRIBE_SPEEDDIAL_CHANGE,
-       CTS_SUBSCRIBE_ADDRESSBOOK_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;
-
-/**
- * This function watchs contacts service changes.
- * The notification is sent once per a transaction.
- * This is handled by default context of g_main_loop.
- *
- * @param[in] noti_type A kind of Notification
- * @param[in] cb callback function pointer
- * @param[in] user_data data which is passed to callback function
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- * @par example
- * @code
-#include <stdio.h>
-#include <glib.h>
-#include <contacts-svc.h>
-
-void test_callback(void *data)
-{
-   printf("Contact data of contacts service is changed\n");
-}
-
-int main()
-{
-   GMainLoop *loop;
-
-   contacts_svc_subscribe_change(CTS_SUBSCRIBE_CONTACT_CHANGE, test_callback, NULL);
-
-   loop = g_main_loop_new(NULL, FALSE);
-   g_main_loop_run(loop);
-
-   contacts_svc_unsubscribe_change(CTS_SUBSCRIBE_CONTACT_CHANGE, test_callback);
-   g_main_loop_unref(loop);
-
-   return 0;
-}
- * @endcode
- */
-int contacts_svc_subscribe_change(cts_subscribe_type noti_type,
-               void (*cb)(void *), void *user_data);
-
-/**
- * This function stops to watch contacts service changes.
- * @param[in] noti_type A kind of Notification(#cts_subscribe_type)
- * @param[in] cb callback function which is added by contacts_svc_subscribe_change()
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_unsubscribe_change(cts_subscribe_type noti_type,
-               void (*cb)(void *));
-
-/**
- * This function delete a callback function which is specified with user_data.
- * @param[in] noti_type A kind of Notification(#cts_subscribe_type)
- * @param[in] cb The callback function which is added by contacts_svc_subscribe_change()
- * @param[in] user_data The user_data which is added by contacts_svc_subscribe_change()
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_unsubscribe_change_with_data(cts_subscribe_type noti_type,
-               void (*cb)(void *), void *user_data);
-
-/**
- * Use for contacts_svc_count()
- */
-typedef enum
-{
-       CTS_GET_ALL_CONTACT, /**< The count of contacts in the all addressbook */
-       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.
- *
- * @param[in] op_code #cts_count_op
- * @return The count number on success, Negative value(#cts_error) on error
- */
-int contacts_svc_count(cts_count_op op_code);
-
-/**
- * Use for contacts_svc_count_with_int()
- */
-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.
- * \n #search_value is related with op_code. The Word after preposition is a property of search_value.
- *
- * @param[in] op_code #cts_count_int_op
- * @param[in] search_value interger value(almost a related index) for searching
- * @return The count number on success, Negative value(#cts_error) on error
- */
-int contacts_svc_count_with_int(cts_count_int_op op_code, int search_value);
-
-/**
- * Use for contacts_svc_save_image()
- */
-typedef enum
-{
-       CTS_IMG_NORMAL, /**< . */
-       CTS_IMG_FULL, /**< . */
-} cts_img_t;
-
-/**
- * This function saves image to contacts service domain.
- *
- * @param[in] img_type #cts_img_t
- * @param[in] index index of contact
- * @param[in] src_img The image path to copy(Should include extension at path)
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_save_image(cts_img_t img_type, int index, char *src_img);
-
-/**
- * This function gets image from contacts service domain.
- * Usually, You can get the #CTS_IMG_NORMAL in Contacts Struct(#CTSstruct).
- *
- * @param[in] img_type #cts_img_t
- * @param[in] index index of contact
- * @param[in] img_path The pointer of getting image path(should be freed by using free())
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_get_image(cts_img_t img_type, int index, char **img_path);
-
-/**
- * This function imports sim phonebook.
- *
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-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] 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 person_id);
-
-//-->
-#endif //#ifndef __CONTACTS_SVC_H__
-
-#endif //__CTS_UTILS_H__
-
diff --git a/src/cts-vcard-file.c b/src/cts-vcard-file.c
deleted file mode 100755 (executable)
index 516b974..0000000
+++ /dev/null
@@ -1,1790 +0,0 @@
-/*
- * 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 <ctype.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-#include <iconv.h>
-
-#include "cts-internal.h"
-#include "cts-types.h"
-#include "cts-utils.h"
-#include "cts-normalize.h"
-#include "cts-vcard.h"
-#include "cts-vcard-file.h"
-
-static int cts_tmp_photo_id;
-
-enum {
-       CTS_VCARD_VER_NONE,
-       CTS_VCARD_VER_2_1,
-       CTS_VCARD_VER_3_0,
-       CTS_VCARD_VER_4_0,
-};
-
-enum {
-       CTS_VCARD_VALUE_NONE,
-       CTS_VCARD_VALUE_FN,
-       CTS_VCARD_VALUE_N,
-       CTS_VCARD_VALUE_NICKNAME,
-       CTS_VCARD_VALUE_PHOTO,
-       CTS_VCARD_VALUE_BDAY,
-       CTS_VCARD_VALUE_ADR,
-       CTS_VCARD_VALUE_LABEL,
-       CTS_VCARD_VALUE_TEL,
-       CTS_VCARD_VALUE_EMAIL,
-       CTS_VCARD_VALUE_TITLE,
-       CTS_VCARD_VALUE_ROLE,
-       CTS_VCARD_VALUE_ORG,
-       CTS_VCARD_VALUE_NOTE,
-       CTS_VCARD_VALUE_REV,
-       CTS_VCARD_VALUE_UID,
-       CTS_VCARD_VALUE_URL,
-       CTS_VCARD_VALUE_X_ANNIVERSARY,
-       CTS_VCARD_VALUE_X_SLP_GROUP,
-       CTS_VCARD_VALUE_END,
-       CTS_VCARD_VALUE_MAX
-};
-
-static const char *content_name[CTS_VCARD_VALUE_MAX];
-
-static inline char* cts_vcard_remove_empty_line(char *src)
-{
-       while (*src) {
-               if ('\n' != *src && '\r' != *src)
-                       break;
-               src++;
-       }
-       return src;
-}
-
-static char* cts_vcard_check_word(char *src, const char *word)
-{
-       bool start = false;
-
-       retvm_if(NULL == src, NULL, "The src is NULL.");
-
-       src = cts_vcard_remove_empty_line(src);
-
-       while (*src) {
-               switch (*src) {
-               case ' ':
-               case ':':
-               case ';':
-                       src++;
-                       break;
-               default:
-                       start = true;
-                       break;
-               }
-               if (start) break;
-       }
-
-       while (*src == *word) {
-               src++;
-               word++;
-
-               if ('\0' == *src || '\0' == *word)
-                       break;
-       }
-
-       if ('\0' == *word)
-               return src;
-       else
-               return NULL;
-}
-
-static int cts_vcard_check_content_type(char **vcard)
-{
-       int i;
-       char *new_start;
-
-       for (i=CTS_VCARD_VALUE_NONE+1;i<CTS_VCARD_VALUE_MAX;i++) {
-               new_start = cts_vcard_check_word(*vcard, content_name[i]);
-               if (new_start && (':' == *new_start || ';' == *new_start))
-                       break;
-       }
-
-       if (CTS_VCARD_VALUE_MAX == i)
-               return CTS_VCARD_VALUE_NONE;
-       else {
-               *vcard = new_start;
-               return i;
-       }
-}
-
-static inline int cts_vcard_check_quoted(char *src, int max, int *quoted)
-{
-       int ret;
-       if (CTS_TRUE == *quoted)
-               return CTS_TRUE;
-
-       while (*src && max) {
-               if ('Q' == *src) {
-                       ret = strncmp(src, "QUOTED-PRINTABLE", sizeof("QUOTED-PRINTABLE") - 1);
-                       if (!ret) {
-                               *quoted = CTS_TRUE;
-                               return CTS_TRUE;
-                       }
-               }else if (':' == *src) {
-                       break;
-               }
-               src++;
-               max--;
-       }
-       return CTS_FALSE;
-}
-
-static inline int cts_vcard_hex_to_dec(char hex)
-{
-       switch (hex) {
-       case '0' ... '9':
-               return hex - '0';
-       case 'a' ... 'f':
-               return hex - 'a' + 10;
-       case 'A' ... 'F':
-               return hex - 'A' + 10;
-       default:
-               return -1;
-       }
-}
-static inline int cts_vcard_decode_quoted_val(char *val)
-{
-       char *src, *dest;
-       int pre;
-
-       src = strchr(val, ':');
-       if (NULL == src)
-               src = val;
-
-       dest = src;
-       while (*src) {
-               if ('=' == *src) {
-                       pre = cts_vcard_hex_to_dec(*(src+1));
-                       if (0 <= pre) {
-                               *dest = (char)((pre << 4) + cts_vcard_hex_to_dec(*(src+2)));
-                               dest++;
-                               src += 2;
-                       } else {
-                               if ('\r' == *(src+1) && '\n' == *(src+2))
-                                       src += 2;
-                       }
-               } else {
-                       *dest = *src;
-                       dest++;
-               }
-               src++;
-       }
-
-       *dest = '\0';
-       return dest - val;
-}
-
-static inline char* cts_vcard_translate_charset(char *src, int len)
-{
-       int ret;
-       char *val = src;
-
-       while (*val) {
-               if ('C' == *val) {
-                       ret = strncmp(val, "CHARSET", sizeof("CHARSET") - 1);
-                       if (!ret) {
-                               val += sizeof("CHARSET");
-                               break;
-                       }
-               }else if (':' == *val) {
-                       return NULL;
-               }
-               val++;
-       }
-
-       if (*val) {
-               int src_len, dest_len, i = 0;
-               iconv_t ic;
-               char enc[32], *dest;
-
-               while (';' != *val && ':' != *val) {
-                       enc[i++] = *val++;
-               }
-               enc[i] = '\0';
-               if (0 == strcasecmp("UTF-8", enc))
-                       return NULL;
-
-               while (':' != *val)
-                       val++;
-
-               ic = iconv_open("UTF-8", enc);
-               retvm_if(ic == (iconv_t)-1, NULL, "iconv_open(%s) Failed", enc);
-
-               src_len = len - (val - src);
-               dest_len = 2048;
-               dest = malloc(dest_len);
-
-               while (true) {
-                       char *in = val;
-                       char *out = dest;
-                       size_t in_byte = src_len;
-                       size_t out_byte = dest_len;
-
-                       ret = iconv(ic, &in, &in_byte, &out, &out_byte);
-
-                       if (-1 == ret) {
-                               if (E2BIG == errno) {
-                                       dest_len *= 2;
-                                       dest = realloc(dest, dest_len);
-                                       continue;
-                               } else {
-                                       if (dest) {
-                                               free(dest);
-                                               dest = NULL;
-                                       }
-                                       ERR("iconv is Failed(errno = %d)", errno);
-                                       break;
-                               }
-                       }
-                       dest[dest_len-out_byte] = '\0';
-                       break;
-               }
-               iconv_close(ic);
-               return dest;
-       }
-
-       return NULL;
-}
-
-
-static inline int cts_vcard_remove_folding(char *folded_src)
-{
-       char *result = folded_src;
-
-       retv_if(NULL == folded_src, CTS_ERR_ARG_NULL);
-
-       while (*folded_src) {
-               if ('\r' == *folded_src && '\n' == *(folded_src+1) && ' ' == *(folded_src+2))
-                       folded_src += 3;
-               else if ('\n' == *folded_src && ' ' == *(folded_src+1))
-                       folded_src += 2;
-
-               if ('\0' == *folded_src)
-                       break;
-
-               *result = *folded_src;
-               result++;
-               folded_src++;
-       }
-       *result = '\0';
-       return CTS_SUCCESS;
-}
-
-static char* cts_vcard_get_val(int ver, char *src, char **dest)
-{
-       int len, quoted;
-       bool start = false;
-       char *cursor;
-
-       retvm_if(NULL == src, NULL, "The src is NULL.");
-       retvm_if(NULL == dest, NULL, "The dest is NULL.");
-
-       while (*src) {
-               switch (*src) {
-               case '\n':
-                       return NULL;
-               case '\r':
-               case ' ':
-               case ':':
-                       src++;
-                       break;
-               default:
-                       start = true;
-                       break;
-               }
-               if (start) break;
-       }
-
-       quoted = CTS_FALSE;
-       cursor = src;
-       len = 0;
-       if(CTS_VCARD_VER_2_1 == ver) {
-               while (*cursor) {
-                       if ('=' == *cursor && cts_vcard_check_quoted(src, cursor - src, &quoted)) {
-                               if ('\r' == *(cursor+1) && '\n' == *(cursor+2))
-                                       cursor += 2;
-                       } else {
-                               if ('\r' == *cursor && '\n' == *(cursor+1) && ' ' != *(cursor+2))
-                                       break;
-                               if ('\n' == *cursor && ' ' != *(cursor+1))
-                                       break;
-                       }
-
-                       cursor++;
-               }
-       } else {
-               while (*cursor) {
-                       if ('\r' == *cursor && '\n' == *(cursor+1) && ' ' != *(cursor+2))
-                               break;
-
-                       if ('\n' == *cursor && ' ' != *(cursor+1))
-                               break;
-
-                       cursor++;
-               }
-       }
-
-       if (src == cursor) {
-               *dest = NULL;
-               return NULL;
-       }
-       else {
-               int len = 0;
-               char temp = *cursor;
-               char *new_dest;
-
-               *cursor = '\0';
-               *dest = strdup(src);
-               if(CTS_VCARD_VER_2_1 != ver)
-                       cts_vcard_remove_folding(*dest);
-
-               if (cts_vcard_check_quoted(*dest, -1, &quoted))
-                       len = cts_vcard_decode_quoted_val(*dest);
-               if (0 == len)
-                       len = strlen(*dest);
-               new_dest = cts_vcard_translate_charset(*dest, len);
-               if (new_dest) {
-                       free(*dest);
-                       *dest = new_dest;
-               }
-               *cursor = temp;
-               return (cursor + 1);
-       }
-}
-
-static inline int cts_vcard_check_version(const char *src)
-{
-       bool start = false;
-       const char *ver3 = "3.0";
-
-       while (*src) {
-               switch (*src) {
-               case '\n':
-               case '\r':
-                       return CTS_VCARD_VER_2_1;
-               case ' ':
-                       src++;
-                       break;
-               default:
-                       start = true;
-                       break;
-               }
-               if (start) break;
-       }
-
-       if (0 == strcmp(src, ver3))
-               return CTS_VCARD_VER_3_0;
-       else
-               return CTS_VCARD_VER_2_1;
-}
-
-
-static inline char* cts_get_content_value(char *val)
-{
-       char *temp;
-
-       temp = strchr(val, ':');
-       if (temp)
-               temp++;
-       else
-               temp = val;
-
-       retvm_if('\0' == *(temp) || '\r' == *(temp) || '\n' == *(temp),
-               NULL, "Invalid vcard content(%s)", val);
-
-       return temp;
-}
-
-
-static char* cts_strtok(char *val, char c)
-{
-       while(*val) {
-               if(*val == c) {
-                       *val = '\0';
-                       return (val+1);
-               }
-               val++;
-       }
-       return val;
-}
-
-
-static inline int cts_vcard_get_display_name(cts_name *name, char *val)
-{
-       char *temp;
-
-       temp = cts_get_content_value(val);
-       name->display = SAFE_STRDUP(temp);
-
-       return CTS_SUCCESS;
-}
-
-
-static inline int cts_vcard_get_name(cts_name *name, char *val)
-{
-       char *temp, *start;
-       const char separator = ';';
-
-       start = cts_get_content_value(val);
-       retv_if(NULL == start, CTS_ERR_NO_DATA);
-
-       temp = cts_strtok(start, separator);
-       name->last = SMART_STRDUP(start);
-       start = temp;
-       temp = cts_strtok(start, separator);
-       name->first = SMART_STRDUP(start);
-       start = temp;
-       temp = cts_strtok(start, separator);
-       name->addition = SMART_STRDUP(start);
-       start = temp;
-       temp = cts_strtok(start, separator);
-       name->prefix = SMART_STRDUP(start);
-       start = temp;
-       temp = cts_strtok(start, separator);
-       name->suffix = SMART_STRDUP(start);
-
-       return CTS_SUCCESS;
-}
-
-static inline GSList* cts_vcard_get_nickname(GSList *nicks, char *val)
-{
-       char *temp;
-       cts_nickname *result;
-       const char *separator = ",";
-
-       temp = strtok(val, separator);
-       while (temp) {
-               if ('\0' == *temp) continue;
-
-               result = (cts_nickname *)contacts_svc_value_new(CTS_VALUE_NICKNAME);
-               if (result) {
-                       result->embedded = true;
-                       result->nick = strdup(temp);
-                       nicks = g_slist_append(nicks, result);
-               }
-
-               temp = strtok(NULL, separator);
-       }
-
-       return nicks;
-}
-
-static inline GSList* cts_vcard_get_event(GSList *events, int type, char *val)
-{
-       cts_event *event;
-
-       event = (cts_event *)contacts_svc_value_new(CTS_VALUE_EVENT);
-       if (event) {
-               char *dest, *src;
-
-               event->embedded = true;
-               event->type = type;
-
-               dest = src = val;
-               while (*src) {
-                       if ('0' <= *src && *src <= '9') {
-                               *dest = *src;
-                               dest++;
-                       }
-                       src++;
-                       if (8 <= dest - val)
-                               break;
-               }
-               *dest = '\0';
-
-               event->date = atoi(val);
-
-               events = g_slist_append(events, event);
-       }
-
-       return events;
-}
-
-static inline int cts_vcard_get_company(cts_company *org, char *val)
-{
-       char *temp, *start;
-
-       start = cts_get_content_value(val);
-       retv_if(NULL == start, CTS_ERR_NO_DATA);
-
-       temp = strchr(start, ';');
-       if (temp) {
-               *temp = '\0';
-               org->name = SMART_STRDUP(start);
-               org->department = SMART_STRDUP(temp+1);
-       }
-       else
-               org->name = strdup(start);
-
-       return CTS_SUCCESS;
-}
-
-
-static inline char* cts_vcard_get_note(char *val)
-{
-       char *temp;
-
-       temp = cts_get_content_value(val);
-
-       if (temp)
-               return g_strcompress(temp);
-       else
-               return NULL;
-}
-
-
-static inline int cts_vcard_get_time(char *val)
-{
-       int i;
-       char tmp[10];
-       struct tm ts = {0};
-
-       i = 0;
-       while (*val && (*val < '0' || '9' < *val)) val++;
-       while (*val) {
-               tmp[i++] = *val;
-               val++;
-               if (4<=i || *val < '0' || '9' < *val) break;
-       }
-       tmp[i] = 0;
-       ts.tm_year = atoi(tmp)-1900;
-
-       i = 0;
-       while (*val && (*val < '0' || '9' < *val)) val++;
-       while (*val) {
-               tmp[i++] = *val;
-               val++;
-               if (2<=i || *val < '0' || '9' < *val) break;
-       }
-       tmp[i] = 0;
-       ts.tm_mon = atoi(tmp)-1;
-
-       i = 0;
-       while (*val && (*val < '0' || '9' < *val)) val++;
-       while (*val) {
-               tmp[i++] = *val;
-               val++;
-               if (2<=i || *val < '0' || '9' < *val) break;
-       }
-       tmp[i] = 0;
-       ts.tm_mday = atoi(tmp);
-
-       i = 0;
-       while (*val && (*val < '0' || '9' < *val)) val++;
-       while (*val) {
-               tmp[i++] = *val;
-               val++;
-               if (2<=i || *val < '0' || '9' < *val) break;
-       }
-       tmp[i] = 0;
-       ts.tm_hour = atoi(tmp);
-
-       i = 0;
-       while (*val && (*val < '0' || '9' < *val)) val++;
-       while (*val) {
-               tmp[i++] = *val;
-               val++;
-               if (2<=i || *val < '0' || '9' < *val) break;
-       }
-       tmp[i] = 0;
-       ts.tm_min = atoi(tmp);
-
-       i = 0;
-       while (*val && (*val < '0' || '9' < *val)) val++;
-       while (*val) {
-               tmp[i++] = *val;
-               val++;
-               if (2<=i || *val < '0' || '9' < *val) break;
-       }
-       tmp[i] = 0;
-       ts.tm_sec = atoi(tmp);
-
-       return (int)mktime(&ts);
-}
-
-
-static inline GSList* cts_vcard_get_web(GSList *webs, char *val)
-{
-       cts_web *web;
-       char *temp;
-
-       temp = cts_get_content_value(val);
-       retvm_if(NULL == temp, webs, "Invalid vcard(%s)", val);
-
-       web = (cts_web *)contacts_svc_value_new(CTS_VALUE_WEB);
-       if (web) {
-               web->embedded = true;
-               web->url = strdup(temp);;
-               if (val != temp) {
-                       *(temp-1) = '\0';
-                       temp = val;
-                       while (*temp)
-                       {
-                               *temp = tolower(*temp);
-                               temp++;
-                       }
-
-                       temp = strchr(val, ';');
-                       if (temp) {
-                               if (strstr(val, "home"))
-                                       web->type = CTS_WEB_TYPE_HOME;
-                               else if (strstr(val, "work"))
-                                       web->type = CTS_WEB_TYPE_WORK;
-                       }
-               }
-               webs = g_slist_append(webs, web);
-       } else {
-               ERR("contacts_svc_value_new() Failed");
-       }
-
-       return webs;
-}
-
-
-static inline bool cts_vcard_get_number_type(cts_number *number, char *val)
-{
-       char *temp, *result;
-       int type = CTS_NUM_TYPE_NONE;
-       bool pref = false;
-
-       temp = val;
-       while (*temp)
-       {
-               *temp = tolower(*temp);
-               temp++;
-       }
-
-       temp = strchr(val , ';');
-       if (temp) {
-               result = strstr(val, "home");
-               if (result) type |= CTS_NUM_TYPE_HOME;
-               result = strstr(val, "msg");
-               if (result) type |= CTS_NUM_TYPE_MSG;
-               result = strstr(val, "work");
-               if (result) type |= CTS_NUM_TYPE_WORK;
-               result = strstr(val, "pref");
-               if (result) pref = true;
-               result = strstr(val, "voice");
-               if (result) type |= CTS_NUM_TYPE_VOICE;
-               result = strstr(val, "fax");
-               if (result) type |= CTS_NUM_TYPE_FAX;
-               result = strstr(val, "cell");
-               if (result) type |= CTS_NUM_TYPE_CELL;
-               result = strstr(val, "video");
-               if (result) type |= CTS_NUM_TYPE_VIDEO;
-               result = strstr(val, "pager");
-               if (result) type |= CTS_NUM_TYPE_PAGER;
-               result = strstr(val, "bbs");
-               if (result) type |= CTS_NUM_TYPE_BBS;
-               result = strstr(val, "modem");
-               if (result) type |= CTS_NUM_TYPE_MODEM;
-               result = strstr(val, "car");
-               if (result) type |= CTS_NUM_TYPE_CAR;
-               result = strstr(val, "isdn");
-               if (result) type |= CTS_NUM_TYPE_ISDN;
-               result = strstr(val, "pcs");
-               if (result) type |= CTS_NUM_TYPE_PCS;
-       }
-       number->type = type;
-
-       return pref;
-}
-
-
-static inline GSList* cts_vcard_get_number(GSList *numbers, char *val)
-{
-       cts_number *number;
-       char *temp;
-
-       temp = cts_get_content_value(val);
-       retvm_if(NULL == temp, numbers, "Invalid vcard(%s)", val);
-
-       number = (cts_number *)contacts_svc_value_new(CTS_VALUE_NUMBER);
-       if (number) {
-               number->embedded = true;
-               number->number = strdup(temp);
-               if (val != temp) {
-                       *(temp-1) = '\0';
-                       number->is_default = cts_vcard_get_number_type(number, val);
-               }
-               numbers = g_slist_append(numbers, number);
-       } else {
-               ERR("contacts_svc_value_new() Failed");
-       }
-
-       return numbers;
-}
-
-static inline bool cts_vcard_get_email_type(cts_email *email, char *val)
-{
-       char *temp;
-       int type = CTS_EMAIL_TYPE_NONE;
-       bool pref = false;
-
-       temp = val;
-       while (*temp)
-       {
-               *temp = tolower(*temp);
-               temp++;
-       }
-
-       temp = strchr(val , ';');
-       if (temp) {
-               if (strstr(val, "home"))
-                       type = CTS_EMAIL_TYPE_HOME;
-               else if (strstr(val, "work"))
-                       type = CTS_EMAIL_TYPE_WORK;
-               if (strstr(val, "pref"))
-                       pref = true;
-       }
-       email->type = type;
-
-       return pref;
-}
-
-static inline GSList* cts_vcard_get_email(GSList *emails, char *val)
-{
-       cts_email *email;
-       char *temp;
-
-       temp = cts_get_content_value(val);
-       retvm_if(NULL == temp, emails, "Invalid vcard(%s)", val);
-
-       email = (cts_email *)contacts_svc_value_new(CTS_VALUE_EMAIL);
-       if (email) {
-               email->embedded = true;
-               email->email_addr = strdup(temp);
-               if (val != temp) {
-                       *(temp-1) = '\0';
-                       email->is_default = cts_vcard_get_email_type(email, val);
-               }
-               emails = g_slist_append(emails, email);
-       } else {
-               ERR("contacts_svc_value_new() Failed");
-       }
-
-       return emails;
-}
-
-static inline bool cts_vcard_get_postal_type(cts_postal *postal, char *val)
-{
-       char *temp, *result;
-       int type = CTS_ADDR_TYPE_NONE;
-       bool pref = false;
-
-       temp = val;
-       while (*temp)
-       {
-               *temp = tolower(*temp);
-               temp++;
-       }
-
-       temp = strchr(val , ';');
-       if (temp) {
-               result = strstr(val, "dom");
-               if (result) type |= CTS_ADDR_TYPE_DOM;
-               result = strstr(val, "intl");
-               if (result) type |= CTS_ADDR_TYPE_INTL;
-               result = strstr(val, "postal");
-               if (result) type |= CTS_ADDR_TYPE_POSTAL;
-               result = strstr(val, "parcel");
-               if (result) type |= CTS_ADDR_TYPE_PARCEL;
-               result = strstr(val, "home");
-               if (result) type |= CTS_ADDR_TYPE_HOME;
-               result = strstr(val, "work");
-               if (result) type |= CTS_ADDR_TYPE_WORK;
-               result = strstr(val, "pref");
-               if (result) pref = true;
-       }
-       postal->type = type;
-
-       return pref;
-}
-
-#define CTS_GET_ADDR_COMPONENT(dest, src, tmp_char) \
-       tmp_char = strchr(src , ';'); \
-if (tmp_char) { \
-       *tmp_char = '\0'; \
-       dest = SMART_STRDUP(src); \
-       src = tmp_char+1; \
-} \
-else { \
-       dest = SMART_STRDUP(src); \
-       break; \
-} \
-
-static inline GSList* cts_vcard_get_postal(GSList *postals, char *val)
-{
-       char *text;
-       cts_postal *postal;
-
-       postal = (cts_postal *)contacts_svc_value_new(CTS_VALUE_POSTAL);
-       if (postal) {
-               postal->embedded = true;
-
-               text = strrchr(val , ':');
-               if (text)
-                       text++;
-               else
-                       text = val;
-
-               while (true) {
-                       char *temp;
-
-                       CTS_GET_ADDR_COMPONENT(postal->pobox, text, temp);
-                       CTS_GET_ADDR_COMPONENT(postal->extended, text, temp);
-                       CTS_GET_ADDR_COMPONENT(postal->street, text, temp);
-                       CTS_GET_ADDR_COMPONENT(postal->locality, text, temp);
-                       CTS_GET_ADDR_COMPONENT(postal->region, text, temp);
-                       CTS_GET_ADDR_COMPONENT(postal->postalcode, text, temp);
-                       CTS_GET_ADDR_COMPONENT(postal->country, text, temp);
-
-                       ERR("invalid ADR type(%s)", temp);
-                       break;
-               }
-               if (postal->pobox || postal->extended || postal->street || postal->locality
-                               || postal->region || postal->postalcode || postal->country) {
-                       postal->is_default = cts_vcard_get_postal_type(postal, val);
-               } else {
-                       ERR("Invalid vcard(%s)", val);
-                       contacts_svc_value_free((CTSvalue *)postal);
-                       return postals;
-               }
-
-               postals = g_slist_append(postals, postal);
-       }
-
-       return postals;
-}
-
-static inline int cts_vcard_get_photo_type(char *val)
-{
-       char *temp, *result;
-
-       temp = val;
-       while (*temp)
-       {
-               *temp = tolower(*temp);
-               temp++;
-       }
-
-       result = strstr(val, "jpeg");
-       if (result) return CTS_VCARD_IMG_JPEG;
-       result = strstr(val, "jpg");
-       if (result) return CTS_VCARD_IMG_JPEG;
-
-       result = strstr(val, "png");
-       if (result) return CTS_VCARD_IMG_PNG;
-
-       result = strstr(val, "gif");
-       if (result) return CTS_VCARD_IMG_GIF;
-
-       result = strstr(val, "tiff");
-       if (result) return CTS_VCARD_IMG_TIFF;
-
-       return CTS_VCARD_IMG_NONE;
-}
-
-static inline const char* cts_get_img_suffix(int type)
-{
-       switch (type)
-       {
-       case CTS_VCARD_IMG_TIFF:
-               return "tiff";
-       case CTS_VCARD_IMG_GIF:
-               return "gif";
-       case CTS_VCARD_IMG_PNG:
-               return "png";
-       case CTS_VCARD_IMG_JPEG:
-       case CTS_VCARD_IMG_NONE:
-       default:
-               return "jpeg";
-       }
-}
-
-static inline int cts_vcard_get_photo(cts_ct_base *base, char *val)
-{
-       int ret, type, fd;
-       gsize size;
-       guchar *buf;
-       char *temp;
-       char dest[CTS_IMG_PATH_SIZE_MAX];
-
-       temp = strchr(val , ':');
-       retvm_if(NULL == temp, CTS_ERR_ARG_INVALID, "val is invalid(%s)", val);
-
-       *temp = '\0';
-       type = cts_vcard_get_photo_type(val);
-
-       ret = snprintf(dest, sizeof(dest), "%s/%d-%d.%s", CTS_VCARD_IMAGE_LOCATION,
-                       getpid(), cts_tmp_photo_id++, cts_get_img_suffix(type));
-       retvm_if(ret<=0, CTS_ERR_FAIL, "Destination file name was not created");
-
-       fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0660);
-       retvm_if(fd < 0, CTS_ERR_FAIL, "open(%s) Failed(%d)", dest, errno);
-
-       buf = g_base64_decode(temp+1, &size);
-
-       while (0 < size) {
-               ret = write(fd, buf, size);
-               if (ret <= 0) {
-                       if (EINTR == errno)
-                               continue;
-                       else {
-                               ERR("write() Failed(%d)", errno);
-                               close(fd);
-                               if (ENOSPC == errno)
-                                       return CTS_ERR_NO_SPACE;
-                               else
-                                       return CTS_ERR_IO_ERR;
-                       }
-               }
-               size -= ret;
-       }
-
-       close(fd);
-       g_free(buf);
-
-       base->vcard_img_path = strdup(dest);
-
-       return CTS_SUCCESS;
-}
-
-static inline GSList* cts_vcard_get_group(GSList *groups, char *val)
-{
-       char *temp;
-       cts_group *result;
-       const char *separator = ",";
-
-       temp = strtok(val, separator);
-       while (temp) {
-               if ('\0' == *temp) continue;
-
-               result = (cts_group *)contacts_svc_value_new(CTS_VALUE_GROUP_RELATION);
-               if (result) {
-                       result->embedded = true;
-                       result->vcard_group = strdup(temp);
-                       groups = g_slist_append(groups, result);
-               }
-
-               temp = strtok(NULL, separator);
-       }
-
-       return groups;
-}
-
-static inline char* cts_vcard_pass_unsupported(char *vcard)
-{
-       while (*vcard) {
-               if ('\n' == *vcard)
-                       return (vcard + 1);
-               vcard++;
-       }
-
-       return NULL;
-}
-
-static inline int cts_vcard_get_contact(int ver, int flags,
-               char *vcard, contact_t *contact)
-{
-       int type;
-       char *cursor, *new_start, *val;
-
-       cursor = vcard;
-       while (cursor)
-       {
-               type = cts_vcard_check_content_type(&cursor);
-               if (CTS_VCARD_VALUE_NONE == type) {
-                       new_start = cts_vcard_pass_unsupported(cursor);
-                       if (new_start) {
-                               cursor = new_start;
-                               continue;
-                       }
-                       else
-                               break;
-               }
-
-               new_start = cts_vcard_get_val(ver, cursor, &val);
-               if (NULL == new_start)
-                       continue;
-
-               if (NULL == val) {
-                       cursor = new_start;
-                       continue;
-               }
-
-               switch (type) {
-               case CTS_VCARD_VALUE_FN:
-                       cts_vcard_get_display_name(contact->name, val);
-                       free(val);
-                       break;
-               case CTS_VCARD_VALUE_N:
-                       cts_vcard_get_name(contact->name, val);
-                       free(val);
-                       break;
-               case CTS_VCARD_VALUE_NICKNAME:
-                       contact->nicknames = cts_vcard_get_nickname(contact->nicknames, val);
-                       free(val);
-                       break;
-               case CTS_VCARD_VALUE_PHOTO:
-                       cts_vcard_get_photo(contact->base, val);
-                       free(val);
-                       break;
-               case CTS_VCARD_VALUE_BDAY:
-                       contact->events = cts_vcard_get_event(contact->events,
-                                       CTS_EVENT_TYPE_BIRTH, val);
-                       free(val);
-                       break;
-               case CTS_VCARD_VALUE_ADR:
-               case CTS_VCARD_VALUE_LABEL:
-                       contact->postal_addrs = cts_vcard_get_postal(contact->postal_addrs, val);
-                       free(val);
-                       break;
-               case CTS_VCARD_VALUE_TEL:
-                       contact->numbers = cts_vcard_get_number(contact->numbers, val);
-                       free(val);
-                       break;
-               case CTS_VCARD_VALUE_EMAIL:
-                       contact->emails = cts_vcard_get_email(contact->emails, val);
-                       free(val);
-                       break;
-               case CTS_VCARD_VALUE_TITLE:
-                       if (NULL == contact->company) {
-                               contact->company = (cts_company*)contacts_svc_value_new(CTS_VALUE_COMPANY);
-                               if (NULL == contact->company) {
-                                       free(val);
-                                       ERR("contacts_svc_value_new(CTS_VALUE_COMPANY) Failed");
-                                       return CTS_ERR_OUT_OF_MEMORY;
-                               }
-                               contact->company->embedded = true;
-                       }
-                       contact->company->jot_title = val;
-                       break;
-               case CTS_VCARD_VALUE_ROLE:
-                       if (NULL == contact->company) {
-                               contact->company = (cts_company*)contacts_svc_value_new(CTS_VALUE_COMPANY);
-                               if (NULL == contact->company) {
-                                       free(val);
-                                       ERR("contacts_svc_value_new(CTS_VALUE_COMPANY) Failed");
-                                       return CTS_ERR_OUT_OF_MEMORY;
-                               }
-                               contact->company->embedded = true;
-                       }
-                       contact->company->role = val;
-                       break;
-               case CTS_VCARD_VALUE_ORG:
-                       if (NULL == contact->company) {
-                               contact->company = (cts_company*)contacts_svc_value_new(CTS_VALUE_COMPANY);
-                               if (NULL == contact->company) {
-                                       free(val);
-                                       ERR("contacts_svc_value_new(CTS_VALUE_COMPANY) Failed");
-                                       return CTS_ERR_OUT_OF_MEMORY;
-                               }
-                               contact->company->embedded = true;
-                       }
-                       cts_vcard_get_company(contact->company, val);
-                       free(val);
-                       break;
-               case CTS_VCARD_VALUE_NOTE:
-                       contact->base->note = cts_vcard_get_note(val);
-                       free(val);
-                       break;
-               case CTS_VCARD_VALUE_REV:
-                       if (*val)
-                               contact->base->changed_time = cts_vcard_get_time(val);;
-                       free(val);
-                       break;
-               case CTS_VCARD_VALUE_UID:
-                       contact->base->uid = val;
-                       break;
-               case CTS_VCARD_VALUE_URL:
-                       contact->web_addrs = cts_vcard_get_web(contact->web_addrs, val);
-                       free(val);
-                       break;
-               case CTS_VCARD_VALUE_X_ANNIVERSARY:
-                       contact->events = cts_vcard_get_event(contact->events,
-                                       CTS_EVENT_TYPE_ANNIVERSARY, val);
-                       free(val);
-                       break;
-               case CTS_VCARD_VALUE_X_SLP_GROUP:
-                       if (flags & CTS_VCARD_CONTENT_X_SLP_GROUP)
-                               contact->grouprelations = cts_vcard_get_group(contact->grouprelations, val);
-                       free(val);
-                       break;
-               case CTS_VCARD_VALUE_END:
-                       free(val);
-                       return CTS_SUCCESS;
-               default:
-                       ERR("cts_vcard_check_content_type() Failed(%d)", type);
-                       return CTS_ERR_VOBJECT_FAILED;
-               }
-               cursor = new_start;
-       }
-
-       ERR("Invalid vcard(%s)", vcard);
-       return CTS_ERR_ARG_INVALID;
-}
-
-static void cts_vcard_initial(void)
-{
-       if (NULL == *content_name) {
-               //content_name[CTS_VCARD_VALUE_NAME] = "NAME"; /* not supported */
-               //content_name[CTS_VCARD_VALUE_PROFILE] = "PROFILE"; /* not supported */
-               //content_name[CTS_VCARD_VALUE_SOURCE] = "SOURCE"; /* not supported */
-               content_name[CTS_VCARD_VALUE_FN] = "FN";
-               content_name[CTS_VCARD_VALUE_N] = "N";
-               content_name[CTS_VCARD_VALUE_NICKNAME] = "NICKNAME";
-               content_name[CTS_VCARD_VALUE_PHOTO] = "PHOTO";
-               content_name[CTS_VCARD_VALUE_BDAY] = "BDAY";
-               content_name[CTS_VCARD_VALUE_ADR] = "ADR";
-               content_name[CTS_VCARD_VALUE_LABEL] = "LABEL"; /* not supported */
-               content_name[CTS_VCARD_VALUE_TEL] = "TEL";
-               content_name[CTS_VCARD_VALUE_EMAIL] = "EMAIL";
-               //content_name[CTS_VCARD_VALUE_MAILER] = "MAILER"; /* not supported */
-               //content_name[CTS_VCARD_VALUE_TZ] = "TZ"; /* not supported */
-               //content_name[CTS_VCARD_VALUE_GEO] = "GEO"; /* not supported */
-               content_name[CTS_VCARD_VALUE_TITLE] = "TITLE";
-               content_name[CTS_VCARD_VALUE_ROLE] = "ROLE";
-               //content_name[CTS_VCARD_VALUE_LOGO] = "LOGO"; /* not supported */
-               //content_name[CTS_VCARD_VALUE_AGENT] = "AGENT"; /* not supported */
-               content_name[CTS_VCARD_VALUE_ORG] = "ORG";
-               //content_name[CTS_VCARD_VALUE_CATEGORIES] = "CATEGORIES"; /* not supported */
-               content_name[CTS_VCARD_VALUE_NOTE] = "NOTE";
-               //content_name[CTS_VCARD_VALUE_PRODID] = "PRODID"; /* not supported */
-               content_name[CTS_VCARD_VALUE_REV] = "REV";
-               //content_name[CTS_VCARD_VALUE_SORT-STRING] = "SORT-STRING"; /* not supported */
-               //content_name[CTS_VCARD_VALUE_SOUND] = "SOUND"; /* not supported */
-               content_name[CTS_VCARD_VALUE_UID] = "UID";
-               content_name[CTS_VCARD_VALUE_URL] = "URL";
-               //content_name[CTS_VCARD_VALUE_VERSION] = "VERSION"; /* not supported */
-               //content_name[CTS_VCARD_VALUE_CLASS] = "CLASS";         /* not supported */
-               //content_name[CTS_VCARD_VALUE_KEY] = "KEY"; /* not supported */
-               content_name[CTS_VCARD_VALUE_X_ANNIVERSARY] = "X-ANNIVERSARY";
-               //content_name[CTS_VCARD_VALUE_X_CHILDREN] = "X-CHILDREN";
-               content_name[CTS_VCARD_VALUE_X_SLP_GROUP] = "X-SLP-GROUP";
-               content_name[CTS_VCARD_VALUE_END] = "END";
-       }
-};
-
-int cts_vcard_parse(const void *vcard_stream, CTSstruct **contact, int flags)
-{
-       int ret, ver;
-       contact_t *result;
-       char *val_begin, *new_start, *val;
-       char *vcard = (char *)vcard_stream;
-
-       retv_if(NULL == vcard_stream, CTS_ERR_ARG_NULL);
-
-       cts_vcard_initial();
-
-       vcard = cts_vcard_check_word(vcard, "BEGIN:VCARD");
-       retvm_if(NULL == vcard, CTS_ERR_ARG_INVALID, "The vcard is invalid.");
-
-       val_begin = cts_vcard_check_word(vcard, "VERSION:");
-       new_start = cts_vcard_get_val(CTS_VCARD_VER_NONE, val_begin, &val);
-       if (NULL == new_start || NULL == val)
-               ver = CTS_VCARD_VER_2_1;
-       else {
-               ver = cts_vcard_check_version(val);
-               free(val);
-               vcard = new_start;
-       }
-
-       result = (contact_t *)contacts_svc_struct_new(CTS_STRUCT_CONTACT);
-       retvm_if(NULL == result, CTS_ERR_OUT_OF_MEMORY, "contacts_svc_struct_new() Failed");
-
-       result->name = (cts_name*)contacts_svc_value_new(CTS_VALUE_NAME);
-       if (NULL == result->name) {
-               ERR("contacts_svc_value_new(CTS_VALUE_NAME) Failed");
-               contacts_svc_struct_free((CTSstruct *)result);
-               return CTS_ERR_OUT_OF_MEMORY;
-       }
-       result->name->embedded = true;
-
-       result->base = (cts_ct_base*)contacts_svc_value_new(CTS_VALUE_CONTACT_BASE_INFO);
-       if (NULL == result->base) {
-               ERR("contacts_svc_value_new(CTS_VALUE_CONTACT_BASE_INFO) Failed");
-               contacts_svc_struct_free((CTSstruct *)result);
-               return CTS_ERR_OUT_OF_MEMORY;
-       }
-       result->base->embedded = true;
-
-       ret = cts_vcard_get_contact(ver, flags, vcard, result);
-
-       if (CTS_SUCCESS != ret) {
-               contacts_svc_struct_free((CTSstruct *)result);
-               if (CTS_ERR_ARG_INVALID == ret)
-                       ERR("cts_vcard_get_contact() Failed(%d)\n %s \n", ret, vcard);
-               else
-                       ERR("cts_vcard_get_contact() Failed(%d)", ret);
-
-               return ret;
-       }
-
-       *contact = (CTSstruct *)result;
-       return CTS_SUCCESS;
-}
-
-/**************************
- *
- * Contact To VCard
- *
- **************************/
-
-const char *CTS_CRLF = "\r\n";
-
-static inline int cts_vcard_append_name(cts_name *name,
-               char *dest, int dest_size)
-{
-       int ret_len;
-       ret_len = snprintf(dest, dest_size, "%s", content_name[CTS_VCARD_VALUE_N]);
-       ret_len += snprintf(dest+ret_len, dest_size-ret_len, ":%s",
-                       SAFE_STR(name->last));
-       ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s",
-                       SAFE_STR(name->first));
-       ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s",
-                       SAFE_STR(name->addition));
-       ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s",
-                       SAFE_STR(name->prefix));
-       ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s%s",
-                       SAFE_STR(name->suffix), CTS_CRLF);
-
-       if (name->display)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s",
-                               content_name[CTS_VCARD_VALUE_FN],
-                               name->display, CTS_CRLF);
-       else {
-               char display[1024];
-
-               if (name->first && name->last) {
-                       if (CTS_ORDER_NAME_FIRSTLAST == contacts_svc_get_order(CTS_ORDER_OF_SORTING)) {
-                               snprintf(display, sizeof(display), "%s %s", name->first, name->last);
-                       } else {
-                               int lang;
-                               if (CTS_LANG_DEFAULT == name->lang_type)
-                                       lang = cts_get_default_language();
-                               else
-                                       lang = name->lang_type;
-
-                               if (CTS_LANG_ENGLISH == lang)
-                                       snprintf(display, sizeof(display), "%s, %s", name->last, name->first);
-                               else
-                                       snprintf(display, sizeof(display), "%s %s", name->last, name->first);
-                       }
-               }
-               else
-                       snprintf(display, sizeof(display), "%s%s", SAFE_STR(name->first), SAFE_STR(name->last));
-
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s",
-                               content_name[CTS_VCARD_VALUE_FN],
-                               display, CTS_CRLF);
-       }
-
-       return ret_len;
-}
-
-static inline int cts_vcard_put_number_type(int type, char *dest, int dest_size)
-{
-       int ret_len = 0;
-       if (type & CTS_NUM_TYPE_HOME)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "HOME");
-       if (type & CTS_NUM_TYPE_MSG)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "MSG");
-       if (type & CTS_NUM_TYPE_WORK)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "WORK");
-       if (type & CTS_NUM_TYPE_VOICE)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "VOICE");
-       if (type & CTS_NUM_TYPE_FAX)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "FAX");
-       if (type & CTS_NUM_TYPE_VOICE)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "VOICE");
-       if (type & CTS_NUM_TYPE_CELL)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "CELL");
-       if (type & CTS_NUM_TYPE_VIDEO)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "VIDEO");
-       if (type & CTS_NUM_TYPE_PAGER)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "PAGER");
-       if (type & CTS_NUM_TYPE_BBS)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "BBS");
-       if (type & CTS_NUM_TYPE_MODEM)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "MODEM");
-       if (type & CTS_NUM_TYPE_CAR)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "CAR");
-       if (type & CTS_NUM_TYPE_ISDN)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "ISDN");
-       if (type & CTS_NUM_TYPE_PCS)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "PCS");
-
-       return ret_len;
-}
-
-static inline int cts_vcard_append_numbers(GSList *numbers,
-               char *dest, int dest_size)
-{
-       int ret_len = 0;
-       GSList *cursor;
-       cts_number *data;
-
-       for (cursor=numbers;cursor;cursor=cursor->next) {
-               data = cursor->data;
-               if (data->number) {
-                       ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s",
-                                       content_name[CTS_VCARD_VALUE_TEL]);
-                       ret_len += cts_vcard_put_number_type(data->type, dest+ret_len,
-                                       dest_size-ret_len);
-                       if (data->is_default)
-                               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "PREF");
-                       ret_len += snprintf(dest+ret_len, dest_size-ret_len, ":%s%s",
-                                       data->number, CTS_CRLF);
-               }
-       }
-
-       return ret_len;
-}
-
-static inline int cts_vcard_append_emails(GSList *emails,
-               char *dest, int dest_size)
-{
-       int ret_len = 0;
-       GSList *cursor;
-       cts_email *data;
-
-       for (cursor=emails;cursor;cursor=cursor->next) {
-               data = cursor->data;
-               if (data->email_addr) {
-                       ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s",
-                                       content_name[CTS_VCARD_VALUE_EMAIL]);
-                       if (CTS_EMAIL_TYPE_HOME & data->type)
-                               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "HOME");
-                       if (CTS_EMAIL_TYPE_WORK & data->type)
-                               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "WORK");
-
-                       if (data->is_default)
-                               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "PREF");
-                       ret_len += snprintf(dest+ret_len, dest_size-ret_len, ":%s%s",
-                                       data->email_addr, CTS_CRLF);
-               }
-       }
-
-       return ret_len;
-}
-
-static inline int cts_vcard_put_postal_type(int type, char *dest, int dest_size)
-{
-       int ret_len = 0;
-       if (type & CTS_ADDR_TYPE_DOM)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "DOM");
-       if (type & CTS_ADDR_TYPE_INTL)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "INTL");
-       if (type & CTS_ADDR_TYPE_HOME)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "HOME");
-       if (type & CTS_ADDR_TYPE_WORK)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "WORK");
-       if (type & CTS_ADDR_TYPE_POSTAL)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "POSTAL");
-       if (type & CTS_ADDR_TYPE_PARCEL)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "PARCEL");
-
-       return ret_len;
-}
-
-static inline int cts_vcard_append_postals(GSList *numbers,
-               char *dest, int dest_size)
-{
-       int ret_len = 0;
-       GSList *cursor;
-       cts_postal *data;
-
-       for (cursor=numbers;cursor;cursor=cursor->next) {
-               data = cursor->data;
-               if (data) {
-                       ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s",
-                                       content_name[CTS_VCARD_VALUE_ADR]);
-                       ret_len += cts_vcard_put_postal_type(data->type, dest+ret_len,
-                                       dest_size-ret_len);
-                       if (data->is_default)
-                               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "PREF");
-                       ret_len += snprintf(dest+ret_len, dest_size-ret_len, ":%s",
-                                       SAFE_STR(data->pobox));
-                       ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s",
-                                       SAFE_STR(data->extended));
-                       ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s",
-                                       SAFE_STR(data->street));
-                       ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s",
-                                       SAFE_STR(data->locality));
-                       ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s",
-                                       SAFE_STR(data->region));
-                       ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s",
-                                       SAFE_STR(data->postalcode));
-                       ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s%s",
-                                       SAFE_STR(data->country), CTS_CRLF);
-               }
-       }
-
-       return ret_len;
-}
-
-static inline int cts_vcard_append_company(cts_company *org,
-               char *dest, int dest_size)
-{
-       int ret_len = 0;
-
-       ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s",
-                       content_name[CTS_VCARD_VALUE_ORG],
-                       SAFE_STR(org->name));
-       if (org->department)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s",
-                               org->department);
-
-       ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s", CTS_CRLF);
-
-       if (org->jot_title)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s",
-                               content_name[CTS_VCARD_VALUE_TITLE],
-                               org->jot_title, CTS_CRLF);
-       if (org->role)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s",
-                               content_name[CTS_VCARD_VALUE_ROLE],
-                               org->role, CTS_CRLF);
-
-       return ret_len;
-}
-
-static inline int cts_vcard_append_nicks(GSList *nicks,
-               char *dest, int dest_size)
-{
-       bool first;
-       int ret_len = 0;
-       GSList *cursor;
-       cts_nickname *data;
-
-       ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:",
-                       content_name[CTS_VCARD_VALUE_NICKNAME]);
-
-       first = true;
-       for (cursor=nicks;cursor;cursor=cursor->next) {
-               data = cursor->data;
-               if (data->nick && *data->nick) {
-                       if (first) {
-                               ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s", data->nick);
-                               first = false;
-                       }
-                       else {
-                               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ",%s", data->nick);
-                       }
-               }
-       }
-
-       ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s", CTS_CRLF);
-
-       return ret_len;
-}
-
-static inline int cts_vcard_append_webs(GSList *webs,
-               char *dest, int dest_size)
-{
-       int ret_len = 0;
-       GSList *cursor;
-       cts_web *data;
-
-       for (cursor=webs;cursor;cursor=cursor->next) {
-               data = cursor->data;
-               if (data->url && *data->url) {
-                       ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s",
-                                       content_name[CTS_VCARD_VALUE_URL],
-                                       data->url, CTS_CRLF);
-               }
-       }
-
-       return ret_len;
-}
-
-static inline int cts_vcard_append_events(GSList *webs,
-               char *dest, int dest_size)
-{
-       int ret_len = 0;
-       GSList *cursor;
-       cts_event *data;
-
-       for (cursor=webs;cursor;cursor=cursor->next) {
-               data = cursor->data;
-               if (!data->date) continue;
-
-               if (CTS_EVENT_TYPE_BIRTH == data->type) {
-                       ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%d-%02d-%d%s",
-                                       content_name[CTS_VCARD_VALUE_BDAY],
-                                       data->date/10000, (data->date%10000)/100, data->date%100,
-                                       CTS_CRLF);
-               }
-               else if (CTS_EVENT_TYPE_ANNIVERSARY == data->type) {
-                       ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%d-%02d-%d%s",
-                                       content_name[CTS_VCARD_VALUE_X_ANNIVERSARY],
-                                       data->date/10000, (data->date%10000)/100, data->date%100,
-                                       CTS_CRLF);
-               }
-       }
-
-       return ret_len;
-}
-
-static inline const char* cts_get_photo_type_str(int type)
-{
-       switch (type)
-       {
-       case CTS_VCARD_IMG_TIFF:
-               return "TIFF";
-       case CTS_VCARD_IMG_GIF:
-               return "GIF";
-       case CTS_VCARD_IMG_PNG:
-               return "PNG";
-       case CTS_VCARD_IMG_JPEG:
-       default:
-               return "JPEG";
-       }
-}
-
-static inline int cts_vcard_put_photo(const char *path, char *dest, int dest_size)
-{
-       int ret, fd, type;
-       gsize read_len;
-       char *suffix;
-       gchar *buf;
-       guchar image[CTS_VCARD_PHOTO_MAX_SIZE];
-
-       suffix = strrchr(path, '.');
-       retvm_if(NULL == suffix, 0, "Image Type(%s) is invalid", path);
-
-       type = cts_vcard_get_photo_type(suffix);
-       retvm_if(CTS_VCARD_IMG_NONE == type, 0, "Image Type(%s) is invalid", path);
-
-       fd = open(path, O_RDONLY);
-       retvm_if(fd < 0, 0, "Open(%s) Failed(%d)", path, errno);
-
-       read_len = 0;
-       while ((ret=read(fd, image+read_len, sizeof(image)-read_len))) {
-               if (-1 == ret) {
-                       if (EINTR == errno)
-                               continue;
-                       else
-                               break;
-               }
-               read_len += ret;
-       }
-       close(fd);
-       retvm_if(ret < 0, 0, "read() Failed(%d)", errno);
-
-       ret = 0;
-       buf = g_base64_encode(image, read_len);
-       if (buf) {
-               ret = snprintf(dest, dest_size, "%s;ENCODING=BASE64;TYPE=%s:%s%s%s",
-                               content_name[CTS_VCARD_VALUE_PHOTO],
-                               cts_get_photo_type_str(type), buf, CTS_CRLF, CTS_CRLF);
-               g_free(buf);
-       }
-
-       return ret;
-}
-static inline int cts_vcard_append_base(cts_ct_base *base,
-               char *dest, int dest_size)
-{
-       int ret_len = 0;
-
-       if (base->img_path)
-               ret_len += cts_vcard_put_photo(base->img_path,
-                               dest+ret_len, dest_size-ret_len);
-       if (base->uid)
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s",
-                               content_name[CTS_VCARD_VALUE_UID],
-                               base->uid, CTS_CRLF);
-       if (base->note) {
-               gchar *escaped_note;
-               escaped_note = g_strescape(base->note, NULL);
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s",
-                               content_name[CTS_VCARD_VALUE_NOTE],
-                               escaped_note, CTS_CRLF);
-               g_free(escaped_note);
-       }
-
-       if (base->changed_time) {
-               struct tm ts;
-               gmtime_r((time_t *)&base->changed_time, &ts);
-               ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%04d-%02d-%02dT%02d:%02d:%02dZ%s",
-                               content_name[CTS_VCARD_VALUE_REV],
-                               1900+ts.tm_year, 1+ts.tm_mon, ts.tm_mday,
-                               ts.tm_hour, ts.tm_min, ts.tm_sec,
-                               CTS_CRLF);
-       }
-
-       return ret_len;
-}
-
-static inline int cts_vcard_append_grouprelations(GSList *grouprelations,
-               char *dest, int dest_size)
-{
-       bool first;
-       int ret_len = 0;
-       GSList *cursor;
-       cts_group *data;
-
-       ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:",
-                       content_name[CTS_VCARD_VALUE_X_SLP_GROUP]);
-
-       first = true;
-       for (cursor=grouprelations;cursor;cursor=cursor->next) {
-               data = cursor->data;
-               if (data->name && *data->name) {
-                       if (first) {
-                               ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s", data->name);
-                               first = false;
-                       }
-                       else {
-                               ret_len += snprintf(dest+ret_len, dest_size-ret_len, ",%s", data->name);
-                       }
-               }
-       }
-
-       ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s", CTS_CRLF);
-
-       return ret_len;
-}
-
-static inline int cts_vcard_append_contact(int flags, contact_t *contact,
-               char *dest, int dest_size)
-{
-       int ret_len = 0;
-
-       if (contact->name)
-               ret_len += cts_vcard_append_name(contact->name,
-                               dest+ret_len, dest_size-ret_len);
-       if (contact->company)
-               ret_len += cts_vcard_append_company(contact->company,
-                               dest+ret_len, dest_size-ret_len);
-       if (contact->postal_addrs)
-               ret_len += cts_vcard_append_postals(contact->postal_addrs,
-                               dest+ret_len, dest_size-ret_len);
-       if (contact->numbers)
-               ret_len += cts_vcard_append_numbers(contact->numbers,
-                               dest+ret_len, dest_size-ret_len);
-       if (contact->emails)
-               ret_len += cts_vcard_append_emails(contact->emails,
-                               dest+ret_len, dest_size-ret_len);
-       if (contact->nicknames)
-               ret_len += cts_vcard_append_nicks(contact->nicknames,
-                               dest+ret_len, dest_size-ret_len);
-       if (contact->web_addrs)
-               ret_len += cts_vcard_append_webs(contact->web_addrs,
-                               dest+ret_len, dest_size-ret_len);
-       if (contact->events)
-               ret_len += cts_vcard_append_events(contact->events,
-                               dest+ret_len, dest_size-ret_len);
-       if (contact->base)
-               ret_len += cts_vcard_append_base(contact->base,
-                               dest+ret_len, dest_size-ret_len);
-       if (contact->grouprelations && (flags & CTS_VCARD_CONTENT_X_SLP_GROUP))
-               ret_len += cts_vcard_append_grouprelations(contact->grouprelations,
-                               dest+ret_len, dest_size-ret_len);
-
-       return ret_len;
-}
-
-#define CTS_VCARD_FOLDING_LIMIT 75
-
-static inline int cts_vcard_add_folding(char *src)
-{
-       int len, result_len;
-       char result[CTS_VCARD_FILE_MAX_SIZE];
-       char *r;
-       const char *s;
-
-       s = src;
-       r = result;
-       len = result_len = 0;
-       while (*s) {
-               if ('\r' == *s)
-                       len--;
-               else if ('\n' == *s)
-                       len = -1;
-
-               if (CTS_VCARD_FOLDING_LIMIT == len) {
-                       *r = '\r';
-                       r++;
-                       *r = '\n';
-                       r++;
-                       *r = ' ';
-                       r++;
-                       len = 1;
-                       result_len += 3;
-               }
-
-               *r = *s;
-               r++;
-               s++;
-               len++;
-               result_len++;
-               retvm_if(sizeof(result) - 5 < result_len, CTS_ERR_ARG_INVALID,
-                               "src is too long\n(%s)", src);
-       }
-       *r = '\0';
-
-       memcpy(src, result, result_len+1);
-       return CTS_SUCCESS;
-}
-
-int cts_vcard_make(const CTSstruct *contact, char **vcard_stream, int flags)
-{
-       int ret_len, ret;
-       char result[CTS_VCARD_FILE_MAX_SIZE];
-
-       retv_if(NULL == contact, CTS_ERR_ARG_NULL);
-       retv_if(NULL == vcard_stream, CTS_ERR_ARG_NULL);
-       retvm_if(CTS_STRUCT_CONTACT != contact->s_type, CTS_ERR_ARG_INVALID,
-                       "The record(%d) must be type of CTS_STRUCT_CONTACT.", contact->s_type);
-
-       cts_vcard_initial();
-
-       ret_len = snprintf(result, sizeof(result), "%s%s", "BEGIN:VCARD", CTS_CRLF);
-       ret_len += snprintf(result+ret_len, sizeof(result)-ret_len,
-                       "%s%s%s", "VERSION:", "3.0", CTS_CRLF);
-
-       ret_len += cts_vcard_append_contact(flags, (contact_t *)contact,
-                       result+ret_len, sizeof(result)-ret_len);
-
-       retvm_if(sizeof(result)-ret_len <= 0, CTS_ERR_EXCEEDED_LIMIT,
-                       "This contact has too many information");
-
-       ret_len += snprintf(result+ret_len, sizeof(result)-ret_len,
-                       "%s%s", "END:VCARD", CTS_CRLF);
-
-       ret = cts_vcard_add_folding(result);
-       if (CTS_SUCCESS != ret)
-               return ret;
-       *vcard_stream = strdup(result);
-
-       return CTS_SUCCESS;
-}
-
diff --git a/src/cts-vcard.c b/src/cts-vcard.c
deleted file mode 100755 (executable)
index 8f02dfc..0000000
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * 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 <errno.h>
-
-#include "cts-internal.h"
-#include "cts-types.h"
-#include "cts-contact.h"
-#include "cts-vcard.h"
-#include "cts-utils.h"
-#include "cts-sqlite.h"
-#include "cts-vcard-file.h"
-#include "cts-struct-ext.h"
-
-API int contacts_svc_get_vcard_from_contact(
-               const CTSstruct *contact, char **vcard_stream)
-{
-       return cts_vcard_make(contact, vcard_stream, CTS_VCARD_CONTENT_BASIC);
-}
-
-API int contacts_svc_get_contact_from_vcard(
-               const char *vcard_stream, CTSstruct **contact)
-{
-       int ret;
-
-       ret = cts_vcard_parse(vcard_stream, contact, CTS_VCARD_CONTENT_BASIC);
-       retvm_if(ret, ret, "cts_vcard_parse() Failed(%d)", ret);
-
-       return CTS_SUCCESS;
-}
-
-static inline void cts_remove_name(cts_name *name)
-{
-       name->is_changed = true;
-       if (name->first) {
-               free(name->first);
-               name->first = NULL;
-       }
-       if (name->last) {
-               free(name->last);
-               name->last = NULL;
-       }
-       if (name->addition) {
-               free(name->addition);
-               name->addition = NULL;
-       }
-       if (name->display) {
-               free(name->display);
-               name->display = NULL;
-       }
-       if (name->prefix) {
-               free(name->prefix);
-               name->prefix = NULL;
-       }
-       if (name->suffix) {
-               free(name->suffix);
-               name->suffix = NULL;
-       }
-}
-
-static inline void cts_remove_company(cts_company *company)
-{
-       if (company->name) {
-               free(company->name);
-               company->name = NULL;
-       }
-       if (company->department) {
-               free(company->department);
-               company->department = NULL;
-       }
-       if (company->jot_title) {
-               free(company->jot_title);
-               company->jot_title = NULL;
-       }
-       if (company->role) {
-               free(company->role);
-               company->role = NULL;
-       }
-}
-
-static inline void cts_remove_base(cts_ct_base *base)
-{
-       if (base->img_path) {
-               free(base->img_path);
-               base->img_path = NULL;
-               base->img_changed = true;
-       }
-       if (base->full_img_path) {
-               free(base->full_img_path);
-               base->full_img_path = NULL;
-               base->full_img_changed = true;
-       }
-       if (base->note) {
-               free(base->note);
-               base->note = NULL;
-               base->note_changed = true;
-       }
-}
-
-static void cts_remove_number(gpointer data, gpointer user_data)
-{
-       ((cts_number*)data)->deleted = true;
-}
-
-void cts_remove_email(gpointer data, gpointer user_data)
-{
-       ((cts_email*)data)->deleted = true;
-}
-
-void cts_remove_event(gpointer data, gpointer user_data)
-{
-       ((cts_event*)data)->deleted = true;
-}
-
-void cts_remove_postal(gpointer data, gpointer user_data)
-{
-       ((cts_postal*)data)->deleted = true;
-}
-
-void cts_remove_web(gpointer data, gpointer user_data)
-{
-       ((cts_web*)data)->deleted = true;
-}
-
-void cts_remove_nick(gpointer data, gpointer user_data)
-{
-       ((cts_nickname*)data)->deleted = true;
-}
-
-void cts_remove_grouprel(gpointer data, gpointer user_data)
-{
-       ((cts_group*)data)->deleted = true;
-}
-
-/*
-       void cts_remove_extend(gpointer data, gpointer user_data)
-       {
-       cts_extend *extend = data;
-       if(0000 == extend->type) extend->deleted = true;
-       }
-       */
-
-static inline void cts_contact_remove_vcard_field(contact_t *contact, int flags)
-{
-       if (contact->name)
-               cts_remove_name(contact->name);
-       if (contact->company)
-               cts_remove_company(contact->company);
-       if (contact->base)
-               cts_remove_base(contact->base);
-
-       g_slist_foreach(contact->numbers, cts_remove_number, NULL);
-       g_slist_foreach(contact->emails, cts_remove_email, NULL);
-       g_slist_foreach(contact->events, cts_remove_event, NULL);
-       g_slist_foreach(contact->postal_addrs, cts_remove_postal, NULL);
-       g_slist_foreach(contact->web_addrs, cts_remove_web, NULL);
-       g_slist_foreach(contact->nicknames, cts_remove_nick, NULL);
-       if (flags & CTS_VCARD_CONTENT_X_SLP_GROUP)
-               g_slist_foreach(contact->grouprelations, cts_remove_grouprel, NULL);
-       //g_slist_foreach(contact->extended_values, cts_remove_extend, NULL);
-}
-
-API int contacts_svc_insert_vcard(int addressbook_id, const char* a_vcard_stream)
-{
-       int ret;
-       CTSstruct *vcard_ct;
-
-       retv_if(NULL == a_vcard_stream, CTS_ERR_ARG_NULL);
-
-       ret = cts_vcard_parse(a_vcard_stream, &vcard_ct, CTS_VCARD_CONTENT_BASIC);
-       retvm_if(CTS_SUCCESS != ret, ret, "cts_vcard_parse() Failed(%d)", ret);
-
-       ret = contacts_svc_insert_contact(addressbook_id, vcard_ct);
-       warn_if(ret < CTS_SUCCESS, "contacts_svc_insert_contact() Failed(%d)", ret);
-
-       contacts_svc_struct_free(vcard_ct);
-
-       return ret;
-}
-
-API int contacts_svc_replace_by_vcard(int contact_id, const char* a_vcard_stream)
-{
-       int ret;
-       CTSstruct *vcard_ct, *contact=NULL;
-
-       retv_if(NULL == a_vcard_stream, CTS_ERR_ARG_NULL);
-
-       ret = contacts_svc_get_contact(contact_id, &contact);
-       retvm_if(CTS_SUCCESS != ret, ret, "contacts_svc_get_contact() Failed(%d)", ret);
-
-       ret = cts_vcard_parse(a_vcard_stream, &vcard_ct, CTS_VCARD_CONTENT_BASIC);
-       if (CTS_SUCCESS != ret) {
-               if (contact) contacts_svc_struct_free(contact);
-               ERR("cts_vcard_parse() Failed(%d)", ret);
-               return ret;
-       }
-
-       cts_contact_remove_vcard_field((contact_t *)contact, CTS_VCARD_CONTENT_BASIC);
-       ret = contacts_svc_struct_merge(contact, vcard_ct);
-       if (CTS_SUCCESS == ret) {
-               ret = contacts_svc_update_contact(contact);
-               warn_if(CTS_SUCCESS != ret, "contacts_svc_update_contact() Failed(%d)", ret);
-       } else {
-               ERR("contacts_svc_struct_merge() Failed(%d)", ret);
-       }
-
-       contacts_svc_struct_free(contact);
-       contacts_svc_struct_free(vcard_ct);
-
-       return ret;
-}
-
-#define CTS_VCARD_MAX_SIZE 1024*1024
-
-API int contacts_svc_vcard_foreach(const char *vcard_file_name,
-               int (*fn)(const char *a_vcard_stream, void *data), void *data)
-{
-       FILE *file;
-       int buf_size, len;
-       char *stream;
-       char line[1024];
-
-       retv_if(NULL == vcard_file_name, CTS_ERR_ARG_NULL);
-       retv_if(NULL == fn, CTS_ERR_ARG_NULL);
-
-       file = fopen(vcard_file_name, "r");
-       retvm_if(NULL == file, CTS_ERR_FAIL, "fopen() Failed(%d)", errno);
-
-       len = 0;
-       buf_size = CTS_VCARD_MAX_SIZE;
-       stream = malloc(CTS_VCARD_MAX_SIZE);
-       retvm_if(NULL == stream, CTS_ERR_OUT_OF_MEMORY, "malloc() Failed");
-
-       while (fgets(line, sizeof(line), file)) {
-               if (0 == len)
-                       if (strncmp(line, "BEGIN:VCARD", sizeof("BEGIN:VCARD")-1))
-                               continue;
-
-               if (len + sizeof(line) < buf_size)
-                       len += snprintf(stream + len, buf_size - len, "%s", line);
-               else {
-                       char *new_stream;
-                       buf_size += sizeof(line) * 2;
-                       new_stream = realloc(stream, buf_size);
-                       if (new_stream)
-                               stream = new_stream;
-                       else {
-                               free(stream);
-                               fclose(file);
-                               return CTS_ERR_OUT_OF_MEMORY;
-                       }
-
-                       len += snprintf(stream + len, buf_size - len, "%s", line);
-               }
-
-               if (0 == strncmp(line, "END:VCARD", 9)) {
-                       if (fn)
-                               if (fn(stream, data)) {
-                                       free(stream);
-                                       fclose(file);
-                                       return CTS_ERR_FINISH_ITER;
-                               }
-                       len = 0;
-               }
-       }
-
-       free(stream);
-       fclose(file);
-       return CTS_SUCCESS;
-}
-
-API int contacts_svc_vcard_count(const char *vcard_file_name)
-{
-       FILE *file;
-       int cnt;
-       char line[1024];
-
-       retv_if(NULL == vcard_file_name, CTS_ERR_ARG_NULL);
-
-       file = fopen(vcard_file_name, "r");
-       retvm_if(NULL == file, CTS_ERR_FAIL, "fopen() Failed(%d)", errno);
-
-       cnt = 0;
-       while (fgets(line, sizeof(line), file)) {
-               if (0 == strncmp(line, "END:VCARD", 9))
-                       cnt++;
-       }
-       fclose(file);
-
-       return cnt;
-}
-
-static inline char* cts_new_strcpy(char *dest, const char *src, int size)
-{
-       int i;
-       for (i=0;i < size && src[i];i++)
-               dest[i] = src[i];
-       dest[i] = '\0';
-
-       return &dest[i];
-}
-
-API char* contacts_svc_vcard_put_content(const char *vcard_stream,
-               const char *content_type, const char *content_value)
-{
-       int i, org_len, new_len;
-       char *new_stream, *cur;
-       const char *end_content = "END:VCARD";
-
-       retvm_if(NULL == vcard_stream, NULL, "vcard_stream is NULL");
-       retvm_if(NULL == content_type, NULL, "content_type is NULL");
-       retvm_if(NULL == content_value, NULL, "content_value is NULL");
-
-       org_len = strlen(vcard_stream);
-       new_len = org_len + strlen(content_type) + strlen(content_value) + 8;
-
-       new_stream = malloc(new_len);
-       retvm_if(NULL == new_stream, NULL, "malloc() Failed");
-
-       memcpy(new_stream, vcard_stream, org_len);
-
-       i = 1;
-       for (cur = new_stream + new_len - 1 ;cur;cur--) {
-               if (end_content[9-i] == *cur) {
-                       if (9 == i) break;
-                       i++;
-                       continue;
-               } else {
-                       i = 1;
-               }
-       }
-       if (9 != i) {
-               ERR("vcard_stream is invalid(%s)", vcard_stream);
-               free(new_stream);
-               return NULL;
-       }
-
-       cur += snprintf(cur, new_len - (cur - new_stream), "%s:", content_type);
-       cur = cts_new_strcpy(cur, content_value, new_len - (cur - new_stream));
-       snprintf(cur, new_len - (cur - new_stream), "\r\n%s\r\n", end_content);
-
-       return new_stream;
-}
-
-API int contacts_svc_vcard_get_content(const char *vcard_stream,
-               const char *content_type, int (*fn)(const char *content_value, void *data), void *data)
-{
-       int len, buf_size, type_len;
-       char *cursor, *found, *value;
-
-       retv_if(NULL == vcard_stream, CTS_ERR_ARG_NULL);
-       retv_if(NULL == content_type, CTS_ERR_ARG_NULL);
-       retv_if(NULL == fn, CTS_ERR_ARG_NULL);
-
-       type_len = strlen(content_type);
-       value = malloc(1024);
-       retvm_if(NULL == value, CTS_ERR_OUT_OF_MEMORY, "malloc() Failed");
-       buf_size = 1024;
-
-       while ((found = strstr(vcard_stream, content_type))) {
-               if ((found != vcard_stream && '\n' != *(found-1))
-                               && ':' != *(found+type_len+1))
-                       continue;
-
-               cursor = found;
-               while (*cursor) {
-                       if ('\r' == *cursor) cursor++;
-                       if ('\n' == *cursor) {
-                               if (' ' != *(cursor+1))
-                                       break;
-                       }
-
-                       cursor++;
-               }
-               len = cursor - found;
-               if (len < buf_size)
-                       memcpy(value, found, len);
-               else {
-                       value = realloc(value, len + 1);
-                       if (value) {
-                               buf_size = len + 1;
-                               memcpy(value, found, len);
-                       }else {
-                               vcard_stream = found + type_len;
-                               continue;
-                       }
-               }
-               value[len] = '\0';
-               if (fn)
-                       if (fn(value+type_len+1, data)) {
-                               free(value);
-                               return CTS_ERR_FINISH_ITER;
-                       }
-               vcard_stream = found + type_len;
-       }
-
-       free(value);
-       return CTS_SUCCESS;
-}
diff --git a/src/cts-vcard.h b/src/cts-vcard.h
deleted file mode 100755 (executable)
index 82336fd..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * 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_VCARD_H__
-#define __CTS_VCARD_H__
-
-enum{
-       CTS_VCARD_IMG_NONE,
-       CTS_VCARD_IMG_JPEG,
-       CTS_VCARD_IMG_PNG,
-       CTS_VCARD_IMG_GIF,
-       CTS_VCARD_IMG_TIFF,
-};
-
-/**
- * content type
- */
-enum VCARDCONTENT {
-       CTS_VCARD_CONTENT_NONE = 0,
-       CTS_VCARD_CONTENT_BASIC = 1<<0,
-       CTS_VCARD_CONTENT_X_SLP_GROUP = 1<<1,
-       CTS_VCARD_CONTENT_ALL = 1<<0|1<<1,
-};
-
-//<!--
-/**
- * @defgroup   CONTACTS_SVC_VCARD vcard handling
- * @ingroup    CONTACTS_SVC
- * @addtogroup CONTACTS_SVC_VCARD
- * @{
- *
- * This interface provides methods to handle the vcard.
- *
- */
-
-/**
- * This function makes contact record by using vcard file stream.
- *
- * @param[in] vcard_stream start point of the stream of vcard.
- * @param[out] contact Points of the contact record which is returned
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_get_contact_from_vcard(const char *vcard_stream, CTSstruct **contact);
-
-/**
- * This function makes vcard file stream by using contact record.
- *
- * @param[in] contact A contact information
- * @param[out] vcard_stream start point of the stream of vcard.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_get_vcard_from_contact(const CTSstruct *contact, char **vcard_stream);
-
-/**
- * This function inserts a contact made from vcard file stream.
- *
- * @param[in] addressbook_id The index of addressbook. 0 is local(phone internal)
- * @param[in] a_vcard_stream start point of the stream of vcard.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_insert_vcard(int addressbook_id, const char* a_vcard_stream);
-
-/**
- * This function replaces a saved contact made from vcard file stream.
- * \n If index(ex. LUID) exist, it is invalid. Always contact_id is valid and processed.
- * If the contact related with contact_id is not existed, return error.
- *
- * @param[in] contact_id The related index of contact.
- * @param[in] a_vcard_stream start point of the stream of vcard.
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_replace_by_vcard(int contact_id, const char* a_vcard_stream);
-
-/**
- * This function calls handling function for each vcard of vcard file.
- *
- * @param[in] vcard_file_name the name of vcard file
- * @param[in] fn function pointer for handling each vcard stream.
- *               If this function doesn't return #CTS_SUCCESS, this function is terminated.
- * @param[in] data data which is passed to callback function
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_vcard_foreach(const char *vcard_file_name,
-               int (*fn)(const char *a_vcard_stream, void *data), void *data);
-
-/**
- * This function gets count of vcard in the file.
- *
- * @param[in] vcard_file_name the name of vcard file
- * @return The count number on success, Negative value(#cts_error) on error
- */
-int contacts_svc_vcard_count(const char *vcard_file_name);
-
-/**
- * This function puts vcard content.
- * If vcard stream has vcards, this function puts new content into the last vcard.
- * you should free new vcard stream after using.
- * \n This should be used for extended type("X-").
- *
- * @param[in] vcard_stream start point of the stream of vcard.
- * @param[in] content_type The type of vcard content
- * @param[in] content_value The value of vcard content
- * @return new vcard stream on success, NULL on error
- */
-char* contacts_svc_vcard_put_content(const char *vcard_stream,
-               const char *content_type, const char *content_value);
-
-/**
- * This function gets values of vcard content.
- * The each value will be passed to fn function.
- * \n This should be used for extended type("X-").
- *
- * @param[in] vcard_stream start point of the stream of vcard.
- * @param[in] content_type The type of vcard content
- * @param[in] fn function pointer for handling each content_value.
- *               If this function doesn't return #CTS_SUCCESS, this function is terminated.
- * @param[in] data data which is passed to callback function
- * @return #CTS_SUCCESS on success, Negative value(#cts_error) on error
- */
-int contacts_svc_vcard_get_content(const char *vcard_stream,
-               const char *content_type, int (*fn)(const char *content_value, void *data), void *data);
-
-/**
- * @}
- */
-//-->
-
-#endif //__CTS_VCARD_H__
-
diff --git a/test/Makefile b/test/Makefile
deleted file mode 100755 (executable)
index e158bc4..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-CC = gcc
-
-REQUIRED_PKG = contacts-service
-CFLAGS = -g -Wall
-LDFLAGS = # -L../ -lefence -pthread
-ifdef REQUIRED_PKG
-       CFLAGS += `pkg-config --cflags $(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 person-test.c restriction-test.c myprofile-test.c SIMexport-test.c
-TIMESRC = timetest.c
-OBJECTS = $(SRCS:.c=.o)
-TIMEOBJ = $(TIMESRC:.c=.o)
-TARGETS = $(OBJECTS:.o=)
-#A:.c=.o  //A안에 있는 .c를 .o로 바꿔라
-
-
-all: $(OBJECTS) $(TARGETS)
-#-mv test1 testlocal /usr/
-
-$(TARGETS): $(TIMEOBJ)
-$(TIMEOBJ): timetest.h
-
-% : %.o
-       $(CC) -o $@ $< $(TIMEOBJ) $(LDFLAGS)
-
-clean:
-       rm -rf $(OBJECTS) $(TARGETS) $(TIMEOBJ)
-
diff --git a/test/addressbook-test.c b/test/addressbook-test.c
deleted file mode 100755 (executable)
index 32ba2d9..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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 insert_addrbook(int acc_id, int acc_type, int mode, const char *group_name)
-{
-       int ret;
-       CTSvalue *ab;
-       ab = contacts_svc_value_new(CTS_VALUE_ADDRESSBOOK);
-
-       contacts_svc_value_set_int(ab, CTS_ADDRESSBOOK_VAL_ACC_ID_INT, acc_id);
-       contacts_svc_value_set_int(ab, CTS_ADDRESSBOOK_VAL_ACC_TYPE_INT, acc_type);
-       contacts_svc_value_set_int(ab, CTS_ADDRESSBOOK_VAL_MODE_INT, mode);
-       contacts_svc_value_set_str(ab, CTS_ADDRESSBOOK_VAL_NAME_STR, group_name);
-
-       ret = contacts_svc_insert_addressbook(ab);
-       if (ret < CTS_SUCCESS)
-               printf("contacts_svc_insert_addressbook() Failed\n");
-
-       contacts_svc_value_free(ab);
-       return ret;
-}
-
-void get_addrbook(int addressbook_id)
-{
-       int ret;
-       const char *name;
-       CTSvalue *ab = NULL;
-
-       ret = contacts_svc_get_addressbook(addressbook_id, &ab);
-       if (CTS_SUCCESS != ret) {
-               printf("contacts_svc_get_addressbook() Failed\n");
-               return;
-       }
-
-       printf("///////////%d//////////////\n",
-                       contacts_svc_value_get_int(ab, CTS_ADDRESSBOOK_VAL_ID_INT));
-       printf("The related account ID : %d\n",
-                       contacts_svc_value_get_int(ab, CTS_ADDRESSBOOK_VAL_ACC_ID_INT));
-       printf("The related account type : %d\n",
-                       contacts_svc_value_get_int(ab, CTS_ADDRESSBOOK_VAL_ACC_TYPE_INT));
-       printf("permission : %d\n",
-                       contacts_svc_value_get_int(ab, CTS_ADDRESSBOOK_VAL_MODE_INT));
-
-       name = contacts_svc_value_get_str(ab, CTS_ADDRESSBOOK_VAL_NAME_STR);
-       if (name)
-               printf("Name : %s\n", name);
-       printf("//////////////////////////\n");
-
-       contacts_svc_value_free(ab);
-}
-
-void update_addrbook(void)
-{
-       int ret;
-       CTSvalue *ab = NULL;
-       ret = contacts_svc_get_addressbook(2, &ab);
-       if (CTS_SUCCESS != ret) {
-               printf("contacts_svc_get_addressbook() Failed\n");
-               return;
-       }
-
-       contacts_svc_value_set_str(ab, CTS_ADDRESSBOOK_VAL_NAME_STR,"Fixed-addressbook");
-
-       ret = contacts_svc_update_addressbook(ab);
-       if (ret < CTS_SUCCESS)
-               printf("contacts_svc_update_addressbook() Failed\n");
-
-       contacts_svc_value_free(ab);
-}
-
-void delete_addrbook(int addressbook_id)
-{
-       int ret;
-       ret = contacts_svc_delete_addressbook(addressbook_id);
-       if (CTS_SUCCESS != ret)
-               printf("Error : contacts_svc_delete_addressbook() Failed(%d)\n", ret);
-}
-
-static int list_cb(CTSvalue *ab, void *user_data)
-{
-       const char *name;
-
-       printf("///////////%d//////////////\n",
-                       contacts_svc_value_get_int(ab, CTS_LIST_ADDRESSBOOK_ID_INT));
-       printf("The related account ID : %d\n",
-                       contacts_svc_value_get_int(ab, CTS_LIST_ADDRESSBOOK_ACC_ID_INT));
-       printf("The related account type : %d\n",
-                       contacts_svc_value_get_int(ab, CTS_LIST_ADDRESSBOOK_ACC_TYPE_INT));
-       printf("permission : %d\n",
-                       contacts_svc_value_get_int(ab, CTS_LIST_ADDRESSBOOK_MODE_INT));
-
-       name = contacts_svc_value_get_str(ab, CTS_LIST_ADDRESSBOOK_NAME_STR);
-       if (name)
-               printf("Name : %s\n", name);
-       printf("//////////////////////////\n");
-
-       return CTS_SUCCESS;
-}
-
-void addrbook_list(void)
-{
-       int ret;
-
-       printf("///////////0//////////////\n");
-       printf("Name : %s\n", "Internal Addressbook(This is logical value)");
-       printf("//////////////////////////\n");
-
-       ret = contacts_svc_list_foreach(CTS_LIST_ALL_ADDRESSBOOK, list_cb, NULL);
-       if (CTS_SUCCESS != ret) {
-               printf("contacts_svc_list_foreach() Failed\n");
-               return;
-       }
-}
-
-void addrbook_list2(void)
-{
-       int ret, count;
-       CTSiter *iter;
-
-       count = contacts_svc_count_with_int(CTS_GET_COUNT_CONTACTS_IN_ADDRESSBOOK, 0);
-       printf("Phone(%d)", count);
-
-       ret = contacts_svc_get_list(CTS_LIST_ALL_ADDRESSBOOK, &iter);
-       if (CTS_SUCCESS != ret) {
-               printf("contacts_svc_get_list() Failed(%d)\n", ret);
-               return;
-       }
-
-       while (CTS_SUCCESS == contacts_svc_iter_next(iter)) {
-               int id;
-               const char *name;
-               CTSvalue *info;
-
-               info = contacts_svc_iter_get_info(iter);
-               id = contacts_svc_value_get_int(info, CTS_LIST_ADDRESSBOOK_ID_INT);
-               name = contacts_svc_value_get_str(info, CTS_LIST_ADDRESSBOOK_NAME_STR);
-               count = contacts_svc_count_with_int(CTS_GET_COUNT_CONTACTS_IN_ADDRESSBOOK, id);
-
-               printf("%s(%d)", name, count);
-       }
-       contacts_svc_iter_remove(iter);
-}
-
-int main()
-{
-       int id;
-       contacts_svc_connect();
-       insert_addrbook(1, CTS_ADDRESSBOOK_TYPE_GOOGLE, CTS_ADDRESSBOOK_MODE_NONE, "test1");
-       insert_addrbook(1, CTS_ADDRESSBOOK_TYPE_GOOGLE, CTS_ADDRESSBOOK_MODE_NONE, "test2");
-       id = insert_addrbook(2, CTS_ADDRESSBOOK_TYPE_FACEBOOK, CTS_ADDRESSBOOK_MODE_READONLY,
-                       "facebook-test");
-       get_addrbook(id);
-       addrbook_list();
-       update_addrbook();
-       addrbook_list();
-       delete_addrbook(id);
-       addrbook_list();
-       addrbook_list2();
-
-       contacts_svc_disconnect();
-       return 0;
-}
-
-
-
diff --git a/test/change-noti-test.c b/test/change-noti-test.c
deleted file mode 100755 (executable)
index fcba23a..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * 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 <glib.h>
-#include <contacts-svc.h>
-
-static void favorite_change_callback(void *data)
-{
-       printf("Favorite data of contacts service is changed\n");
-}
-
-static void plog_change_callback(void *data)
-{
-       printf("Phone log data of contacts service is changed\n");
-}
-
-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)
-{
-       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;
-
-       contacts_svc_connect();
-       contacts_svc_subscribe_change(CTS_SUBSCRIBE_CONTACT_CHANGE, contact_change_callback, NULL);
-       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);
-
-       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, 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);
-
-       return 0;
-}
-
diff --git a/test/contact-test.c b/test/contact-test.c
deleted file mode 100755 (executable)
index 037178f..0000000
+++ /dev/null
@@ -1,868 +0,0 @@
-/*
- * 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 <stdlib.h>
-#include <glib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <contacts-svc.h>
-
-static int insert_test(void)
-{
-       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);
-
-       int ret = contacts_svc_insert_contact(0, contact);
-       contacts_svc_struct_free(contact);
-
-       return ret;
-}
-
-void delete_test(void)
-{
-       //get contact
-       //CTSstruct *contact;
-       //contacts_svc_struct_get_value(contact, CTS_CF_INDEX_INT, &value);
-       //int index = contacts_svc_value_get_int(value, CTS_BASIC_VAL_INT);
-
-       contacts_svc_delete_contact(2);
-
-       //contacts_svc_struct_free(contact);
-
-#if DELETE_CONTACTS
-       // TODO: get each index of contacts
-       int i, index_list[10] ={1,3,4,65,345,54,5,2,9,10};
-       int ret;
-
-       ret = contacts_svc_begin_trans();
-       if (CTS_SUCCESS != ret) return;
-       for (i=0;i<10;i++) {
-               ret = contacts_svc_delete_contact(index_list[i]);
-               if (CTS_SUCCESS != ret) {
-                       contacts_svc_end_trans(false);
-                       return;
-               }
-       }
-       ret = contacts_svc_end_trans(true);
-       if (ret < CTS_SUCCESS){
-               printf("all work were rollbacked");
-               return;
-       }
-#endif
-
-}
-
-void update_test()
-{
-       int ret;
-       GSList *numbers, *cursor, *groupList, *nicknames;
-       CTSvalue *number=NULL, *name=NULL, *group = NULL, *company, *nick;
-       CTSstruct *contact=NULL;
-
-       ret = contacts_svc_get_contact(1, &contact);
-       if (ret < CTS_SUCCESS) return;
-
-       contacts_svc_struct_get_value(contact, CTS_CF_NAME_VALUE, &name);
-       contacts_svc_value_set_str(name, CTS_NAME_VAL_FIRST_STR, "Changed first");
-       contacts_svc_value_set_str(name, CTS_NAME_VAL_LAST_STR, "Changed last");
-       contacts_svc_value_set_str(name, CTS_NAME_VAL_PREFIX_STR, "Changed prefix");
-       contacts_svc_value_set_str(name, CTS_NAME_VAL_SUFFIX_STR, NULL);
-
-       numbers = NULL;
-       contacts_svc_struct_get_list(contact, CTS_CF_NUMBER_LIST, &numbers);
-       cursor = numbers;
-       if (cursor) {
-               //char *temp = contacts_svc_value_get_str(cursor->data, CTS_NUM_VAL_NUMBER_STR);
-               contacts_svc_value_set_str(cursor->data, CTS_NUM_VAL_NUMBER_STR, "0987651234");
-
-               cursor = g_slist_next(cursor);
-               if (cursor)
-                       contacts_svc_value_set_bool(cursor->data, CTS_NUM_VAL_DELETE_BOOL, true);
-
-               number = contacts_svc_value_new(CTS_VALUE_NUMBER);
-               if (number) {
-                       contacts_svc_value_set_str(number, CTS_NUM_VAL_NUMBER_STR, "+82125439876");
-                       contacts_svc_value_set_int(number, CTS_NUM_VAL_TYPE_INT,
-                                       CTS_NUM_TYPE_WORK|CTS_NUM_TYPE_FAX);
-                       //         contacts_svc_value_set_bool(number, CTS_NUM_VAL_DEFAULT_BOOL, true);
-                       numbers = g_slist_append(numbers, number);
-               }
-       }
-
-       contacts_svc_struct_store_list(contact, CTS_CF_NUMBER_LIST, numbers);
-       contacts_svc_value_free(number);
-       //free("+82125439876");
-
-       groupList = NULL;
-       contacts_svc_struct_get_list(contact, CTS_CF_GROUPREL_LIST, &groupList);
-
-       cursor = groupList;
-       cursor=g_slist_next(groupList);
-       if (cursor)
-               contacts_svc_value_set_bool(cursor->data, CTS_GROUPREL_VAL_DELETE_BOOL, true);
-
-       group = contacts_svc_value_new(CTS_VALUE_GROUP_RELATION);
-       if (group) {
-               contacts_svc_value_set_int(group, CTS_GROUPREL_VAL_ID_INT, 2);
-               groupList = g_slist_append(groupList, group);
-       }
-       contacts_svc_struct_store_list(contact, CTS_CF_GROUPREL_LIST, groupList);
-       contacts_svc_value_free(group);
-
-       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);
-
-       nicknames = NULL;
-       contacts_svc_struct_get_list(contact, CTS_CF_NICKNAME_LIST, &nicknames);
-       cursor = nicknames;
-       if (cursor) {
-               contacts_svc_value_set_bool(cursor->data, CTS_NICKNAME_VAL_DELETE_BOOL, true);
-
-               nick = contacts_svc_value_new(CTS_VALUE_NICKNAME);
-               if (nick) {
-                       contacts_svc_value_set_str(nick, CTS_NICKNAME_VAL_NAME_STR, "good company");
-                       nicknames = g_slist_append(nicknames, nick);
-               }
-               contacts_svc_struct_store_list(contact, CTS_CF_NICKNAME_LIST, nicknames);
-               contacts_svc_value_free(nick);
-       }
-
-
-       contacts_svc_update_contact(contact);
-       contacts_svc_struct_free(contact);
-}
-
-static void translation_type(int type, char *dest, int dest_size)
-{
-       const char *type_str;
-       if (type & CTS_NUM_TYPE_CUSTOM)
-       {
-               char *custom;
-               custom = contacts_svc_get_custom_type(CTS_TYPE_CLASS_NUM, type);
-               if (NULL == custom)
-                       type_str = "Other";
-               else {
-                       snprintf(dest, dest_size, custom);
-                       free(custom);
-                       return;
-               }
-       }
-       else if (type & CTS_NUM_TYPE_CELL)
-               type_str = "Mobile";
-       else if (type & CTS_NUM_TYPE_VOICE)
-       {
-               if (type & CTS_NUM_TYPE_HOME)
-                       type_str = "Home";
-               else if (type & CTS_NUM_TYPE_WORK)
-                       type_str = "Work";
-               else
-                       type_str = "Telephone";
-       }
-       else if (type & CTS_NUM_TYPE_FAX)
-       {
-               if (type & CTS_NUM_TYPE_HOME)
-                       type_str = "Fax(home)";
-               else if (type & CTS_NUM_TYPE_WORK)
-                       type_str = "Fax(work)";
-               else
-                       type_str = "Fax";
-       }
-       else if (type & CTS_NUM_TYPE_PAGER)
-               type_str = "Pager";
-       else if (type & CTS_NUM_TYPE_CAR)
-               type_str = "Car Telephone";
-       else if (type & CTS_NUM_TYPE_ASSISTANT)
-               type_str = "Assistant";
-       else
-               type_str = "Other";
-
-       snprintf(dest, dest_size, type_str);
-}
-
-void get_contact(CTSstruct *contact)
-{
-       int index=0, ret=-1;
-       CTSvalue *value=NULL;
-       GSList *get_list, *cursor;
-
-       if (!contact) {
-               index = contacts_svc_find_contact_by(CTS_FIND_BY_NUMBER, "125439876");
-               if (index > CTS_SUCCESS)
-                       ret = contacts_svc_get_contact(index, &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;
-               char type_str[100];
-               type = contacts_svc_value_get_int(cursor->data, CTS_NUM_VAL_TYPE_INT);
-               translation_type(type, type_str, sizeof(type_str));
-               printf("number Type = %s  ", type_str);
-
-               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(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);
-
-}
-
-void get_contact_default_num(void)
-{
-       int index, ret;
-       CTSvalue *number=NULL;
-       const char *default_num;
-
-       index = contacts_svc_find_contact_by(CTS_FIND_BY_NUMBER, "0125439876");
-
-       ret = contacts_svc_get_contact_value(CTS_GET_DEFAULT_NUMBER_VALUE, index, &number);
-       if (CTS_SUCCESS != ret) {
-               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);
-}
-void get_contact_list(void)
-{
-       CTSiter *iter = NULL;
-       printf("Phone contact NUM = %d\n",
-                       contacts_svc_count_with_int(CTS_GET_COUNT_CONTACTS_IN_ADDRESSBOOK, 0));
-
-       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))
-       {
-               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);
-}
-
-void sync_data(int ver)
-{
-       int ret, index_num;
-       CTSiter *iter;
-
-       contacts_svc_get_updated_contacts(0, ver, &iter);
-
-       while (CTS_SUCCESS == contacts_svc_iter_next(iter))
-       {
-               CTSstruct *contact= NULL;
-               CTSvalue *row_info = NULL;
-               row_info = contacts_svc_iter_get_info(iter);
-
-               index_num = contacts_svc_value_get_int(row_info, CTS_LIST_CHANGE_ID_INT);
-               printf("(%8d)\n", index_num);
-               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_UPDATED == type || CTS_OPERATION_INSERTED == type) {
-                       contacts_svc_get_contact(index_num, &contact);
-                       char *vcard_stream, *new_stream;
-                       char file[128];
-                       snprintf(file, sizeof(file), "test%d.vcf", index_num);
-                       ret = contacts_svc_get_vcard_from_contact(contact, &vcard_stream);
-                       new_stream = contacts_svc_vcard_put_content(vcard_stream, "X-TEST", "1234");
-                       printf("%s\n", (char *)new_stream);
-                       free(new_stream);
-                       if (CTS_SUCCESS == ret) {
-                               //int fd = open(file, O_RDWR | O_CREAT);
-                               //write(fd, (char *)vcard_stream, strlen((char *)vcard_stream));
-                               //close(fd);
-                               CTSstruct *new_contact = NULL;
-                               ret = contacts_svc_get_contact_from_vcard(vcard_stream, &new_contact);
-                               if (CTS_SUCCESS == ret) {
-                                       get_contact(new_contact);
-                                       contacts_svc_struct_free(new_contact);
-                               }
-                               free(vcard_stream);
-                       }
-                       if (CTS_OPERATION_INSERTED == type)
-                               printf("Added : %d \n", ver);
-                       else
-                               printf("Updated : %d \n", ver);
-                       contacts_svc_struct_free(contact);
-               }
-               else
-                       printf("Deleted : %d \n", ver);
-
-               contacts_svc_value_free(row_info);
-       }
-       contacts_svc_iter_remove(iter);
-}
-
-void search_contacts_by_name(void)
-{
-       int ret;
-       CTSiter *iter;
-       ret = contacts_svc_get_list_with_str(CTS_LIST_CONTACTS_WITH_NAME,
-                       "ch", &iter);
-       if (CTS_SUCCESS != ret) return;
-
-       while (CTS_SUCCESS == contacts_svc_iter_next(iter))
-       {
-               CTSvalue *row_info = NULL;
-               const char *first, *last, *display;
-               row_info = contacts_svc_iter_get_info(iter);
-
-               printf("(%8d)", contacts_svc_value_get_int(row_info, CTS_LIST_CONTACT_ID_INT));
-
-               display = contacts_svc_value_get_str(row_info, CTS_LIST_CONTACT_DISPLAY_STR);
-               if (display)
-                       printf("%s :", display);
-               else
-               {
-                       first = contacts_svc_value_get_str(row_info, CTS_LIST_CONTACT_FIRST_STR);
-                       last = contacts_svc_value_get_str(row_info, 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(row_info, CTS_LIST_CONTACT_IMG_PATH_STR));
-               printf("\n");
-               contacts_svc_value_free(row_info);
-       }
-       contacts_svc_iter_remove(iter);
-}
-
-void get_favorite_list(void)
-{
-       CTSiter *iter;
-       contacts_svc_get_list(CTS_LIST_ALL_NUMBER_FAVORITE, &iter);
-
-       while (CTS_SUCCESS == contacts_svc_iter_next(iter)) {
-               CTSvalue *favorite = NULL;
-               const char *first, *last, *display;
-               favorite = contacts_svc_iter_get_info(iter);
-
-               printf("(%8d)", contacts_svc_value_get_int(favorite, CTS_LIST_SHORTCUT_ID_INT));
-               printf(":%d", contacts_svc_value_get_int(favorite, CTS_LIST_SHORTCUT_CONTACT_ID_INT));
-               display = contacts_svc_value_get_str(favorite, CTS_LIST_SHORTCUT_DISPLAY_NAME_STR);
-               if (display)
-                       printf("%s :", display);
-               else
-               {
-                       first = contacts_svc_value_get_str(favorite, CTS_LIST_SHORTCUT_FIRST_NAME_STR);
-                       last = contacts_svc_value_get_str(favorite, CTS_LIST_SHORTCUT_LAST_NAME_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(favorite, CTS_LIST_SHORTCUT_NUMBER_STR));
-               printf("(%d)", contacts_svc_value_get_int(favorite, CTS_LIST_SHORTCUT_NUMBER_TYPE_INT));
-               printf("-%d)", contacts_svc_value_get_int(favorite, CTS_LIST_SHORTCUT_SPEEDDIAL_INT));
-               printf("%s", contacts_svc_value_get_str(favorite, CTS_LIST_SHORTCUT_IMG_PATH_STR));
-               printf("\n");
-               contacts_svc_value_free(favorite);
-       }
-       contacts_svc_iter_remove(iter);
-}
-
-void put_value_test()
-{
-       CTSvalue *value, *number;
-
-       value = contacts_svc_value_new(CTS_VALUE_CONTACT_BASE_INFO);
-       if (value) {
-               contacts_svc_value_set_str(value, CTS_BASE_VAL_RINGTONE_PATH_STR,
-                               "/opt/test/test.mp3");
-               contacts_svc_put_contact_value(CTS_PUT_VAL_REPLACE_RINGTONE, 1, value);
-               contacts_svc_value_free(value);
-       }
-
-       number = contacts_svc_value_new(CTS_VALUE_NUMBER);
-       if (number) {
-               contacts_svc_value_set_str(number, CTS_NUM_VAL_NUMBER_STR, "0123337777");
-               contacts_svc_value_set_int(number, CTS_NUM_VAL_TYPE_INT, CTS_NUM_TYPE_CELL);
-               //      contacts_svc_value_set_bool(number, CTS_NUM_VAL_DEFAULT_BOOL, true);
-
-               contacts_svc_put_contact_value(CTS_PUT_VAL_ADD_NUMBER, 1, number);
-               contacts_svc_value_free(number);
-       }
-}
-
-static void print_extend_contact(CTSstruct *contact)
-{
-       int ret;
-       CTSvalue *value;
-       GSList *get_list, *cursor;
-       value = NULL;
-       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));
-
-       value = NULL;
-       ret = contacts_svc_find_custom_type(CTS_TYPE_CLASS_EXTEND_DATA, "YomiName");
-       ret = contacts_svc_struct_get_value(contact, ret, &value);
-       if (CTS_SUCCESS == ret) {
-               printf("extend1 data2 : %s\n", contacts_svc_value_get_str(value, CTS_EXTEND_VAL_DATA2_STR));
-               printf("extend1 data3 : %s\n", contacts_svc_value_get_str(value, CTS_EXTEND_VAL_DATA3_STR));
-               printf("extend1 data4 : %s\n", contacts_svc_value_get_str(value, CTS_EXTEND_VAL_DATA4_STR));
-       }
-       value = NULL;
-       ret = contacts_svc_find_custom_type(CTS_TYPE_CLASS_EXTEND_DATA, "Family");
-       ret = contacts_svc_struct_get_value(contact, ret, &value);
-       if (CTS_SUCCESS == ret) {
-               printf("extend2 data2 : %s\n", contacts_svc_value_get_str(value, CTS_EXTEND_VAL_DATA2_STR));
-               printf("extend2 data3 : %s\n", contacts_svc_value_get_str(value, CTS_EXTEND_VAL_DATA3_STR));
-               printf("extend2 data4 : %s\n", contacts_svc_value_get_str(value, CTS_EXTEND_VAL_DATA4_STR));
-       }
-       get_list = NULL;
-       contacts_svc_struct_get_list(contact, CTS_CF_NUMBER_LIST, &get_list);
-
-       cursor = get_list;
-       for (;cursor;cursor=g_slist_next(cursor))
-       {
-               int type;
-               char type_str[100];
-               type = contacts_svc_value_get_int(cursor->data, CTS_NUM_VAL_TYPE_INT);
-               translation_type(type, type_str, sizeof(type_str));
-               printf("number Type = %s", type_str);
-
-               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));
-       }
-}
-
-void extend_data_test(void)
-{
-       int ret, index;
-       CTSstruct *contact;
-       CTSvalue *name, *number1, *extend_value;
-       GSList *numbers=NULL;
-
-       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, "People");
-               contacts_svc_value_set_str(name, CTS_NAME_VAL_LAST_STR, "Japan");
-       }
-       contacts_svc_struct_store_value(contact, CTS_CF_NAME_VALUE, name);
-       contacts_svc_value_free(name);
-
-       number1 = contacts_svc_value_new(CTS_VALUE_NUMBER);
-       if (number1) {
-               contacts_svc_value_set_str(number1, CTS_NUM_VAL_NUMBER_STR, "0333333333");
-               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);
-
-       extend_value = contacts_svc_value_new(CTS_VALUE_EXTEND);
-       if (extend_value) {
-               contacts_svc_value_set_str(extend_value, CTS_EXTEND_VAL_DATA2_STR, "YomiFirstName");
-               contacts_svc_value_set_str(extend_value, CTS_EXTEND_VAL_DATA3_STR, "YomiLastName");
-               contacts_svc_value_set_str(extend_value, CTS_EXTEND_VAL_DATA4_STR, "YomiCompanyName");
-       }
-       ret = contacts_svc_find_custom_type(CTS_TYPE_CLASS_EXTEND_DATA, "YomiName");
-       if (CTS_ERR_DB_RECORD_NOT_FOUND == ret)
-               ret = contacts_svc_insert_custom_type(CTS_TYPE_CLASS_EXTEND_DATA, "YomiName");
-       contacts_svc_struct_store_value(contact, ret, extend_value);
-       contacts_svc_value_free(extend_value);
-
-       extend_value = contacts_svc_value_new(CTS_VALUE_EXTEND);
-       if (extend_value) {
-               contacts_svc_value_set_str(extend_value, CTS_EXTEND_VAL_DATA2_STR, "Children1");
-               contacts_svc_value_set_str(extend_value, CTS_EXTEND_VAL_DATA3_STR, "Children2");
-               contacts_svc_value_set_str(extend_value, CTS_EXTEND_VAL_DATA4_STR, "Children3");
-       }
-       ret = contacts_svc_find_custom_type(CTS_TYPE_CLASS_EXTEND_DATA, "Family");
-       if (CTS_ERR_DB_RECORD_NOT_FOUND == ret)
-               ret = contacts_svc_insert_custom_type(CTS_TYPE_CLASS_EXTEND_DATA, "Family");
-       contacts_svc_struct_store_value(contact, ret, extend_value);
-       contacts_svc_value_free(extend_value);
-
-       index = contacts_svc_insert_contact(0, contact);
-       contacts_svc_struct_free(contact);
-       contact = NULL;
-
-       ret = contacts_svc_get_contact(index, &contact);
-       if (ret < 0)
-       {
-               printf("No found record\n");
-               return;
-       }
-       print_extend_contact(contact);
-
-       //update test
-
-       extend_value = NULL;
-       int type = contacts_svc_find_custom_type(CTS_TYPE_CLASS_EXTEND_DATA, "Family");
-       ret = contacts_svc_struct_get_value(contact, type, &extend_value);
-       if (CTS_SUCCESS == ret)
-               contacts_svc_value_set_str(extend_value, CTS_EXTEND_VAL_DATA2_STR, "Children4");
-       contacts_svc_struct_store_value(contact, type, extend_value);
-
-       contacts_svc_update_contact(contact);
-       contacts_svc_struct_free(contact);
-       contact = NULL;
-
-       ret = contacts_svc_get_contact(index, &contact);
-       if (ret < 0)
-       {
-               printf("No found record\n");
-               return;
-       }
-       print_extend_contact(contact);
-       contacts_svc_struct_free(contact);
-}
-
-void get_number_list(void)
-{
-       CTSiter *iter;
-       contacts_svc_get_list_with_str(CTS_LIST_NUMBERINFOS_WITH_NUM, "123", &iter);
-       //contacts_svc_get_list_with_str(CTS_LIST_NUMBERINFOS_WITH_NAME, "kim", &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_NUM_CONTACT_ID_INT));
-               display = contacts_svc_value_get_str(contact, CTS_LIST_NUM_CONTACT_DISPLAY_STR);
-               if (display)
-                       printf("%s :", display);
-               else
-               {
-                       first = contacts_svc_value_get_str(contact, CTS_LIST_NUM_CONTACT_FIRST_STR);
-                       last = contacts_svc_value_get_str(contact, CTS_LIST_NUM_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_NUM_CONTACT_IMG_PATH_STR));
-               printf("\n");
-               printf("%s\n", contacts_svc_value_get_str(contact, CTS_LIST_NUM_NUMBER_STR));
-               contacts_svc_value_free(contact);
-       }
-       contacts_svc_iter_remove(iter);
-}
-
-static int get_search_cb(CTSvalue *value, void *user_data)
-{
-       const char *number, *img_path;
-       const char *first, *last, *display;
-
-       printf("(%8d)", contacts_svc_value_get_int(value, CTS_LIST_NUM_CONTACT_ID_INT));
-       display = contacts_svc_value_get_str(value, CTS_LIST_NUM_CONTACT_DISPLAY_STR);
-       if (display)
-               printf("%s :", display);
-       else
-       {
-               first = contacts_svc_value_get_str(value, CTS_LIST_NUM_CONTACT_FIRST_STR);
-               last = contacts_svc_value_get_str(value, CTS_LIST_NUM_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);
-       }
-
-       img_path = contacts_svc_value_get_str(value, CTS_LIST_NUM_CONTACT_IMG_PATH_STR);
-       if (img_path)
-               printf("%s\n", img_path);
-       else
-               printf("\n");
-
-       number = contacts_svc_value_get_str(value, CTS_LIST_NUM_NUMBER_STR);
-       if (number)
-               printf("%s\n", number);
-
-       return CTS_SUCCESS;
-}
-
-void get_search(void)
-{
-       contacts_svc_smartsearch_excl("fir", 0, 0, get_search_cb, NULL);
-}
-
-static int get_list_with_filter_cb(CTSvalue *value, void *user_data)
-{
-       const char *img_path;
-       const char *first, *last, *display;
-
-       printf("(%8d)", contacts_svc_value_get_int(value, CTS_LIST_CONTACT_ID_INT));
-       display = contacts_svc_value_get_str(value, CTS_LIST_CONTACT_DISPLAY_STR);
-       if (display)
-               printf("%s :", display);
-       else
-       {
-               first = contacts_svc_value_get_str(value, CTS_LIST_CONTACT_FIRST_STR);
-               last = contacts_svc_value_get_str(value, 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);
-       }
-
-       img_path = contacts_svc_value_get_str(value, CTS_LIST_CONTACT_IMG_PATH_STR);
-       if (img_path)
-               printf("%s\n", img_path);
-       else
-               printf("\n");
-
-       return CTS_SUCCESS;
-}
-
-void get_list_with_filter(void)
-{
-       int ret;
-       CTSfilter *filter;
-
-       filter = contacts_svc_list_str_filter_new(CTS_FILTERED_CONTACTS_WITH_NAME,
-                       "kim", CTS_LIST_FILTER_ADDRESBOOK_ID_INT, 0, CTS_LIST_FILTER_NONE);
-       if (NULL == filter) {
-               printf("contacts_svc_list_str_filter_new() Failed\n");
-               return;
-       }
-
-       ret = contacts_svc_list_with_filter_foreach(filter, get_list_with_filter_cb, NULL);
-       if (CTS_SUCCESS != ret)
-               printf("contacts_svc_list_with_filter_foreach() Failed(%d)\n", ret);
-
-       contacts_svc_list_filter_free(filter);
-}
-
-int main()
-{
-       int ret, ver;
-       contacts_svc_connect();
-       printf("\n##Insert##\n");
-
-       contacts_svc_begin_trans();
-       ret = insert_test();
-       if (CTS_SUCCESS < ret)
-               ver = contacts_svc_end_trans(true);
-       else
-               contacts_svc_end_trans(false);
-       printf("\n##Insert##\n");
-       insert_test();
-       sleep(2);
-       printf("\n##Update test##\n");
-       update_test();
-       put_value_test();
-       printf("\n##All Contact Information##\n");
-       get_contact(NULL);
-       printf("\n##Default Number##\n");
-       get_contact_default_num();
-
-       printf("\n##Contact List##\n");
-       get_contact_list();
-       printf("\n##Delete Test##\n");
-       delete_test();
-       printf("\n##Sync Test##\n");
-       sync_data(ver);
-
-       printf("\n##Search Name##\n");
-       search_contacts_by_name();
-       printf("\n##Favorite List##\n");
-       get_favorite_list();
-       printf("\n##Favorite 1 Delete##\n");
-       contacts_svc_delete_favorite(1);
-       get_favorite_list();
-
-       printf("\n##Extend Data insert##\n");
-       extend_data_test();
-
-       printf("\n##Number List##\n");
-       get_number_list();
-
-       printf("\n##search##\n");
-       get_search();
-
-       printf("\n##list_with_filter##\n");
-       get_list_with_filter();
-
-       contacts_svc_disconnect();
-
-       return 0;
-}
diff --git a/test/group-test.c b/test/group-test.c
deleted file mode 100755 (executable)
index b682da2..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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 <glib.h>
-#include <contacts-svc.h>
-
-void insert_group(const char *group_name)
-{
-       int ret;
-       CTSvalue *group;
-       group = contacts_svc_value_new(CTS_VALUE_GROUP);
-
-       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)
-               printf("contacts_svc_insert_group() Failed\n");
-
-       contacts_svc_value_free(group);
-}
-void get_group(void)
-{
-       int ret;
-       CTSvalue *group = NULL;
-       ret = contacts_svc_get_group(2, &group);
-       if (CTS_SUCCESS != ret) {
-               printf("contacts_svc_get_group() Failed\n");
-               return;
-       }
-
-       printf("Addressbook ID : %d\n",
-                       contacts_svc_value_get_int(group, CTS_GROUP_VAL_ADDRESSBOOK_ID_INT));
-       printf("Name : %s\n",
-                       contacts_svc_value_get_str(group, CTS_GROUP_VAL_NAME_STR));
-       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)
-{
-       int ret;
-       CTSvalue *group = NULL;
-       ret = contacts_svc_get_group(2, &group);
-       if (CTS_SUCCESS != ret) {
-               printf("contacts_svc_get_group() Failed\n");
-               return;
-       }
-
-       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");
-       ret = contacts_svc_update_group(group);
-       if (ret < CTS_SUCCESS)
-               printf("contacts_svc_update_group() Failed\n");
-
-       contacts_svc_value_free(group);
-}
-
-void delete_group(void)
-{
-       int ret;
-       ret = contacts_svc_delete_group(3);
-       if (CTS_SUCCESS != ret)
-               printf("Error : contacts_svc_delete_group() Failed(%d)\n", ret);
-}
-
-void delete_group_with_members(void)
-{
-       int ret;
-       ret = contacts_svc_delete_group_with_members(1);
-       if (CTS_SUCCESS != ret)
-               printf("Error : contacts_svc_delete_group_with_members() Failed(%d)\n", ret);
-}
-
-void group_list(void)
-{
-       int ret;
-       CTSiter *iter;
-       ret = contacts_svc_get_list(CTS_LIST_ALL_GROUP, &iter);
-       if (CTS_SUCCESS != ret) {
-               printf("contacts_svc_get_list() Failed\n");
-               return;
-       }
-
-       while (CTS_SUCCESS == contacts_svc_iter_next(iter))
-       {
-               CTSvalue *group;
-               const char *name;
-               group = contacts_svc_iter_get_info(iter);
-
-               printf("%8d", contacts_svc_value_get_int(group, CTS_LIST_GROUP_ID_INT));
-               printf("(%d)", contacts_svc_value_get_int(group, CTS_LIST_GROUP_ADDRESSBOOK_ID_INT));
-               name = contacts_svc_value_get_str(group, CTS_LIST_GROUP_NAME_STR);
-               if (name)
-                       printf("%s :", name);
-               printf("\n");
-               contacts_svc_value_free(group);
-       }
-       contacts_svc_iter_remove(iter);
-}
-
-
-int main()
-{
-       contacts_svc_connect();
-       insert_group("Friends");
-       insert_group("Home");
-       get_group();
-       update_group();
-       group_list();
-       delete_group();
-       delete_group_with_members();
-       contacts_svc_disconnect();
-       return 0;
-}
-
diff --git a/test/myprofile-test.c b/test/myprofile-test.c
deleted file mode 100755 (executable)
index 96ddd64..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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
deleted file mode 100755 (executable)
index e86583d..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * 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
deleted file mode 100755 (executable)
index 9dd79dd..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * 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 <stdlib.h>
-#include <glib.h>
-#include <unistd.h>
-#include <string.h>
-#include <contacts-svc.h>
-
-void phonelog_insert_test(void)
-{
-       CTSvalue *plog;
-
-       plog = contacts_svc_value_new(CTS_VALUE_PHONELOG);
-       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_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_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);
-       contacts_svc_value_set_int(plog, CTS_PLOG_VAL_DURATION_INT, 65);
-       contacts_svc_insert_phonelog(plog);
-
-
-       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);
-
-       contacts_svc_delete_phonelog(CTS_PLOG_DEL_BY_ID, 3);
-       contacts_svc_delete_phonelog(CTS_PLOG_DEL_BY_NUMBER, "0123456789");
-}
-
-void phonelog_get_list_test(int op)
-{
-       CTSiter *iter = NULL;
-       char display[1024]={0};
-
-       contacts_svc_get_list(op, &iter);
-
-       while (CTS_SUCCESS == contacts_svc_iter_next(iter))
-       {
-               CTSvalue *plog= NULL;
-               plog = contacts_svc_iter_get_info(iter);
-
-               const char *img_path = contacts_svc_value_get_str(plog, CTS_LIST_PLOG_IMG_PATH_STR);
-               const char *display_name = contacts_svc_value_get_str(plog, CTS_LIST_PLOG_DISPLAY_NAME_STR);
-               const char *number = contacts_svc_value_get_str(plog, CTS_LIST_PLOG_NUMBER_STR);
-               if (display_name)
-                       snprintf(display, sizeof(display), "%s", display_name);
-               else
-               {
-                       const char *first = contacts_svc_value_get_str(plog, CTS_LIST_PLOG_FIRST_NAME_STR);
-                       const char *last = contacts_svc_value_get_str(plog, CTS_LIST_PLOG_LAST_NAME_STR);
-                       if (first && last) {
-                               if (CTS_ORDER_NAME_FIRSTLAST == contacts_svc_get_order(CTS_ORDER_OF_DISPLAY))
-                                       snprintf(display, sizeof(display), "%s %s", first, last);
-                               else
-                                       snprintf(display, sizeof(display), "%s %s", last, first);
-                       }else if (first)
-                               strcpy(display, first);
-                       else if (last)
-                               strcpy(display, last);
-                       else {
-                               if (number)
-                                       strcpy(display, number);
-                       }
-               }
-
-               int num_type = contacts_svc_value_get_int(plog, CTS_LIST_PLOG_NUM_TYPE_INT);
-
-               int index = contacts_svc_value_get_int(plog, CTS_LIST_PLOG_ID_INT);
-               int type = contacts_svc_value_get_int(plog, CTS_LIST_PLOG_LOG_TYPE_INT);
-               int time = contacts_svc_value_get_int(plog, CTS_LIST_PLOG_LOG_TIME_INT);
-
-               if (strlen(display))
-                       printf("%d:%s(%s:%d):type=%d:time=%d\n",
-                                       index, display, number, num_type, type, time);
-               if (img_path)
-                       printf("%s\n", img_path);
-               contacts_svc_value_free(plog);
-       }
-       contacts_svc_iter_remove(iter);
-}
-
-void phonelog_get_detail_list_test(void)
-{
-       int ret;
-       CTSiter *iter = NULL;
-       contacts_svc_get_list_with_str(CTS_LIST_PLOGS_OF_NUMBER,"0987654321", &iter);
-
-       ret = contacts_svc_iter_next(iter);
-       while (CTS_SUCCESS == ret)
-       {
-               CTSvalue *plog=NULL;
-               plog = contacts_svc_iter_get_info(iter);
-
-               int index = contacts_svc_value_get_int(plog, CTS_LIST_PLOG_ID_INT);
-               int type = contacts_svc_value_get_int(plog, CTS_LIST_PLOG_LOG_TYPE_INT);
-               int time = contacts_svc_value_get_int(plog, CTS_LIST_PLOG_LOG_TIME_INT);
-               int duration = contacts_svc_value_get_int(plog, CTS_LIST_PLOG_DURATION_INT);
-
-               printf("%d::type=%d:time=%d:duration=%d\n", index, type, time, duration);
-               contacts_svc_value_free(plog);
-               ret = contacts_svc_iter_next(iter);
-       }
-       contacts_svc_iter_remove(iter);
-}
-
-static int plog_get_number_list_cb(const char *number, void *user_data)
-{
-       printf("number = %s\n", number);
-       return CTS_SUCCESS;
-}
-
-void phonelog_get_number_list_test(void)
-{
-       int ret;
-
-       ret = contacts_svc_phonelog_get_all_number(plog_get_number_list_cb, NULL);
-       if (CTS_SUCCESS != ret)
-               printf("contacts_svc_phonelog_get_all_number() Failed(%d)\n", ret);
-
-}
-
-void phonelog_get_last_call_number_test(void)
-{
-       char *number = contacts_svc_phonelog_get_last_number(CTS_PLOG_LAST_ALL);
-
-       printf("Last Call Number is %s\n", number);
-       free(number);
-}
-
-int main()
-{
-       contacts_svc_connect();
-       phonelog_insert_test();
-       sleep(2);
-       phonelog_insert_test();
-       printf("grouping List 1 <<<<<<<<<<<\n");
-       phonelog_get_list_test(CTS_LIST_GROUPING_PLOG);
-       phonelog_modify_test();
-       printf("grouping List 2 <<<<<<<<<<<\n");
-       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");
-       phonelog_get_number_list_test();
-
-       phonelog_get_last_call_number_test();
-
-       contacts_svc_disconnect();
-       return 0;
-}
diff --git a/test/restriction-test.c b/test/restriction-test.c
deleted file mode 100755 (executable)
index c92b4d5..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * 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
deleted file mode 100755 (executable)
index bfe8e85..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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__ */
diff --git a/test/timetest.c b/test/timetest.c
deleted file mode 100755 (executable)
index ac3d3be..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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 <unistd.h>
-#include <sys/time.h>
-#include "timetest.h"
-
-FILE *outfp;
-
-
-double correction;
-
-double set_start_time(void)
-{
-       //      DEBUG_FUNC_START;
-
-       struct timeval tv;
-       double curtime;
-
-       gettimeofday(&tv, NULL);
-       curtime = tv.tv_sec * 1000 + (double)tv.tv_usec/1000;
-       return curtime;
-}
-
-double exec_time(double start)
-{
-       //      DEBUG_FUNC_START;
-
-       double end = set_start_time();
-       return (end - start - correction);
-}
-
-int init_time(void)
-{
-       //      DEBUG_FUNC_START;
-
-       double temp_t;
-       temp_t = set_start_time();
-       correction = exec_time(temp_t);
-
-       return 0;
-}
-
-int print_time(char *prn_args, double time)
-{
-       DEBUG_FUNC_START;
-
-#ifdef USE_STD_OUT
-       printf("%200s =\t", prn_args);
-       printf("%f \n", time);
-#else
-       fprintf(outfp, "%.50s\t", prn_args);
-       fprintf(outfp, "%f \n", time);
-#endif
-
-       return 0;
-}
-
-
-int print_argument(char *prn_args)
-{
-       DEBUG_FUNC_START;
-
-#ifdef USE_STD_OUT
-       printf("%s", prn_args);
-#else
-       fprintf(outfp, "%s\n", prn_args);
-#endif
-
-       return 0;
-}
-
-
-
-int print_milestone(char *prn_args, int level)
-{
-       DEBUG_FUNC_START;
-       int i;
-
-       if (level > 1) {
-               for (i=0;i<level;i++)
-                       printf("\n##################################################################\n");
-               printf("\n%s =\n", prn_args);
-               for (i=0;i<level;i++)
-                       printf("\n##################################################################\n");
-       }
-
-#ifdef USE_STD_OUT
-       if (1 == level)
-               printf("\n##################################################################\n");
-       printf("\n%s =\n", prn_args);
-       printf("\n##################################################################\n");
-#else
-       for (i=0;i<level;i++)
-               fprintf(outfp, "\n##################################################################\n");
-       fprintf(outfp, "%s \n", prn_args);
-       for (i=0;i<level;i++)
-               fprintf(outfp, "\n##################################################################\n");
-#endif
-
-
-       return 0;
-}
-
-int std_output(char *prn_args, double time)
-{
-       DEBUG_FUNC_START;
-
-       printf("%.50s =\t", prn_args);
-       printf("%f \n", time);
-
-       return 0;
-}
-
-
-int file_print_init(char *filename)
-{
-       DEBUG_FUNC_START;
-
-       outfp = fopen(filename, "w"); //"aw"
-       TEST_ERR_PRN_TREAT(NULL == outfp , ("(%s) Open Error \n", filename),
-                       {return -1;});
-       return 0;
-}
-
diff --git a/test/timetest.h b/test/timetest.h
deleted file mode 100755 (executable)
index 37b5e05..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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 _TIMETEST_H_
-#define _TIMETEST_H_
-
-
-#define TEST_TRACE(fmt, arg...) \
-       printf("[TEST]%s %d:\n" fmt "", __FUNCTION__, __LINE__, ##arg)
-
-#define TEST_DEBUG(fmt, arg...) \
-       printf("\x1b[105;37m[TEST]\x1b[0m(%d)" fmt "", __LINE__, ##arg)
-
-
-#define DEBUG_FUNC_START \
-       printf("\x1b[104;93m[FUNC_START]\x1b[0m%s\n", __FUNCTION__)
-
-
-#define TEST_ERROR_PRINT(fmt, arg...) \
-       printf("\n\x1b[101;38m[ERROR]\x1b[0m%s(%d): " fmt "", __FUNCTION__, __LINE__, ##arg)
-
-#define TEST_ERR_PRN_TREAT(eval, X, expr) if (eval) {TEST_ERROR_PRINT X; expr;} else {;}
-
-
-int init_time(void);
-double set_start_time(void);
-double exec_time(double start);
-
-int print_time(char *prn_args, double time);
-int print_argument(char *prn_args);
-int print_milestone(char *prn_args, int level);
-int std_output(char *prn_args, double time);
-int file_print_init(char *filename);
-
-
-#endif //_TIMETEST_H_
diff --git a/test/vcard2contact-test.c b/test/vcard2contact-test.c
deleted file mode 100755 (executable)
index 3339c8d..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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 <glib.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include <contacts-svc.h>
-
-#define MAX_BUF 1048576
-
-static void get_contact(CTSstruct *contact)
-{
-       CTSvalue *value;
-       GSList *get_list, *cursor;
-       const char *tmp_str;
-
-       value = NULL;
-       contacts_svc_struct_get_value(contact, CTS_CF_BASE_INFO_VALUE, &value);
-       printf("ID = %d\n", contacts_svc_value_get_int(value, CTS_BASE_VAL_ID_INT));
-       printf("changed time = %d\n", contacts_svc_value_get_int(value, CTS_BASE_VAL_CHANGED_TIME_INT));
-       printf("note = %s\n", contacts_svc_value_get_str(value, CTS_BASE_VAL_NOTE_STR));
-
-       value = NULL;
-       contacts_svc_struct_get_value(contact, CTS_CF_NAME_VALUE, &value);
-       if ((tmp_str = contacts_svc_value_get_str(value, CTS_NAME_VAL_FIRST_STR)))
-               printf("First Name : %s\n", tmp_str);
-       if ((tmp_str = contacts_svc_value_get_str(value, CTS_NAME_VAL_LAST_STR)))
-               printf("Last Name : %s\n", tmp_str);
-       if ((tmp_str = contacts_svc_value_get_str(value, CTS_NAME_VAL_ADDITION_STR)))
-               printf("Additional Name : %s\n", tmp_str);
-       if ((tmp_str = contacts_svc_value_get_str(value, CTS_NAME_VAL_DISPLAY_STR)))
-               printf("Display Name : %s\n", tmp_str);
-       if ((tmp_str = contacts_svc_value_get_str(value, CTS_NAME_VAL_PREFIX_STR)))
-               printf("Prefix Name : %s\n", tmp_str);
-       if ((tmp_str = contacts_svc_value_get_str(value, CTS_NAME_VAL_SUFFIX_STR)))
-               printf("Suffix Name : %s\n", tmp_str);
-
-       value = NULL;
-       contacts_svc_struct_get_value(contact, CTS_CF_COMPANY_VALUE, &value);
-       if ((tmp_str = contacts_svc_value_get_str(value, CTS_COMPANY_VAL_NAME_STR)))
-               printf("Company Name : %s\n", tmp_str);
-       if ((tmp_str = contacts_svc_value_get_str(value, CTS_COMPANY_VAL_DEPARTMENT_STR)))
-               printf("Company Department : %s\n", tmp_str);
-
-       get_list = NULL;
-       contacts_svc_struct_get_list(contact, CTS_CF_NUMBER_LIST, &get_list);
-
-       for (cursor = get_list;cursor;cursor=cursor->next)
-       {
-               printf("number Type = %d",
-                               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))
-                       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);
-
-       for (cursor = get_list;cursor;cursor=cursor->next)
-       {
-               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_POSTAL_ADDR_LIST, &get_list);
-       for (cursor = get_list;cursor;cursor=cursor->next)
-       {
-               printf(">>> Postal(type = %d) <<<\n",
-                               contacts_svc_value_get_int(cursor->data, CTS_POSTAL_VAL_TYPE_INT));
-               if ((tmp_str = contacts_svc_value_get_str(cursor->data, CTS_POSTAL_VAL_POBOX_STR)))
-                       printf("Pobox = %s\n", tmp_str);
-               if ((tmp_str = contacts_svc_value_get_str(cursor->data, CTS_POSTAL_VAL_POSTALCODE_STR)))
-                       printf("POSTALCODE = %s\n", tmp_str);
-               if ((tmp_str = contacts_svc_value_get_str(cursor->data, CTS_POSTAL_VAL_REGION_STR)))
-                       printf("REGION = %s\n", tmp_str);
-               if ((tmp_str = contacts_svc_value_get_str(cursor->data, CTS_POSTAL_VAL_LOCALITY_STR)))
-                       printf("LOCALITY = %s\n", tmp_str);
-               if ((tmp_str = contacts_svc_value_get_str(cursor->data, CTS_POSTAL_VAL_STREET_STR)))
-                       printf("STREET = %s\n", tmp_str);
-               if ((tmp_str = contacts_svc_value_get_str(cursor->data, CTS_POSTAL_VAL_EXTENDED_STR)))
-                       printf("EXTENDED = %s\n", tmp_str);
-               if ((tmp_str = contacts_svc_value_get_str(cursor->data, CTS_POSTAL_VAL_COUNTRY_STR)))
-                       printf("COUNTRY = %s\n", tmp_str);
-       }
-       get_list = NULL;
-       contacts_svc_struct_get_list(contact, CTS_CF_EVENT_LIST, &get_list);
-       for (cursor = get_list;cursor;cursor=cursor->next)
-       {
-               printf("type=%d:%d\n",
-                               contacts_svc_value_get_int(cursor->data, CTS_EVENT_VAL_TYPE_INT),
-                               contacts_svc_value_get_int(cursor->data, CTS_EVENT_VAL_DATE_INT));
-       }
-}
-
-static int vcard_handler(const char *vcard, void *data)
-{
-       int ret;
-       CTSstruct *new_contact = NULL;
-
-       ret = contacts_svc_get_contact_from_vcard(vcard, &new_contact);
-       if (CTS_SUCCESS == ret) {
-               get_contact(new_contact);
-               contacts_svc_struct_free(new_contact);
-       }
-
-       contacts_svc_insert_vcard(0, vcard);
-       contacts_svc_replace_by_vcard(1, vcard);
-
-       return CTS_SUCCESS;
-}
-
-int main(int argc, char **argv)
-{
-       if (argc < 2) return -1;
-       contacts_svc_connect();
-
-       printf("vcard file has %d vcards\n", contacts_svc_vcard_count(argv[1]));
-       contacts_svc_vcard_foreach(argv[1], vcard_handler, NULL);
-
-       contacts_svc_disconnect();
-
-       return 0;
-}