diff options
author | Jinkun Jang <jinkun.jang@samsung.com> | 2013-03-13 01:51:18 +0900 |
---|---|---|
committer | Jinkun Jang <jinkun.jang@samsung.com> | 2013-03-13 01:51:18 +0900 |
commit | 914aa1e2236ac93b14e1f19a1c1931385a58d572 (patch) | |
tree | 849d38523452703d214ad84cb97ece31d1e25866 | |
parent | a1311c9da85162a82223c73aa63e6c9b7d91c565 (diff) | |
download | contacts-service-914aa1e2236ac93b14e1f19a1c1931385a58d572.tar.gz contacts-service-914aa1e2236ac93b14e1f19a1c1931385a58d572.tar.bz2 contacts-service-914aa1e2236ac93b14e1f19a1c1931385a58d572.zip |
Tizen 2.1 base
260 files changed, 63467 insertions, 229 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e79af0..cff5090 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,17 +14,17 @@ SET(EXEC_PREFIX "\${prefix}") SET(LIBDIR "\${prefix}/lib") SET(INCLUDEDIR "\${prefix}/${DEST_INCLUDE_DIR}") SET(VERSION_MAJOR 0) -SET(VERSION "${VERSION_MAJOR}.5.2") +SET(VERSION "${VERSION_MAJOR}.9.24.8") 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) FOREACH(flag ${pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") @@ -32,32 +32,28 @@ ENDFOREACH(flag) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") -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 notification files +FILE(GLOB NOTI_FILES ${CMAKE_SOURCE_DIR}/res/.CONTACTS_SVC_*) +INSTALL(FILES ${NOTI_FILES} DESTINATION /opt/usr/data/contacts-svc + PERMISSIONS OWNER_WRITE OWNER_READ GROUP_WRITE GROUP_READ) -INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib) -INSTALL(FILES ${PROJECT_NAME}.pc DESTINATION lib/pkgconfig) +# Install directory for image +INSTALL(DIRECTORY DESTINATION /opt/usr/data/contacts-svc/img/vcard) +INSTALL(DIRECTORY DESTINATION /opt/usr/data/contacts-svc/img/my) +INSTALL(DIRECTORY DESTINATION /opt/usr/data/contacts-svc/img/group) +INSTALL(DIRECTORY DESTINATION /opt/usr/data/contacts-svc/img/logo) -FILE(GLOB HEADER_FILES ${SRC_INCLUDE_DIR}/contacts-svc*.h) +# Install header file +FILE(GLOB HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h) INSTALL(FILES ${HEADER_FILES} DESTINATION ${DEST_INCLUDE_DIR}) -INSTALL(FILES ${SRC_INCLUDE_DIR}/ContactsService_PG.h DESTINATION ${DEST_INCLUDE_DIR}) - -FILE(GLOB NOTI_FILES ${CMAKE_SOURCE_DIR}/.CONTACTS_SVC_*_CHANGED) -INSTALL(FILES ${NOTI_FILES} DESTINATION /opt/data/contacts-svc) - -INSTALL(DIRECTORY DESTINATION /opt/data/contacts-svc/img/vcard) -ADD_SUBDIRECTORY(helper) +ADD_SUBDIRECTORY(native) +ADD_SUBDIRECTORY(client) +ADD_SUBDIRECTORY(server) diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100644 index 0000000..19c4054 --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,204 @@ +Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
@@ -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. diff --git a/build-util/generator.sh b/build-util/generator.sh index 0bc0730..366aeba 100755 --- a/build-util/generator.sh +++ b/build-util/generator.sh @@ -25,37 +25,10 @@ echo "###### API 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-normalize.h >> ../include/contacts-svc.h -./API-generator ../src/cts-list.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 +# New server daemon Schema +echo "static const char *schema_query = \"\\" > ../server/schema.h +./DB-schema-gen ../schema.sql >> ../server/schema.h +echo \"\; >> ../server/schema.h make clean diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt new file mode 100755 index 0000000..fdc06b4 --- /dev/null +++ b/client/CMakeLists.txt @@ -0,0 +1,97 @@ +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_phonelog.c + ctsvc_client_service.c + ctsvc_client_ipc.c + ctsvc_client_noti.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_phonelog.c + ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_result.c + ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_sdn.c + ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_simple_contact.c + ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_speeddial.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.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_normalize.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_phonelog.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_record_result.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_record_sdn.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_record_speeddial.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_record_updated_info.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_setting.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_sim.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_socket.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_vcard.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_view.c +) + +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 ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${CLIENT} PROPERTIES VERSION ${VERSION}) +TARGET_LINK_LIBRARIES(${CLIENT} ${client_pkgs_LDFLAGS} ${pkgs_LDFLAGS} -lpthread) + +INSTALL(TARGETS ${CLIENT} DESTINATION lib) +INSTALL(FILES ${CLIENT}.pc DESTINATION lib/pkgconfig) + diff --git a/client/contacts-service2.pc.in b/client/contacts-service2.pc.in new file mode 100644 index 0000000..5ac7490 --- /dev/null +++ b/client/contacts-service2.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: @TARGET@ +Description: @PROJECT_NAME@ library +Version: @VERSION@ +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 index 0000000..b3856a9 --- /dev/null +++ b/client/ctsvc_client_activity.c @@ -0,0 +1,126 @@ +/*
+ * 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_ipc_marshal.h"
+#include "ctsvc_client_ipc.h"
+#include <pims-ipc-data.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");
+ 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("pims_ipc_call failed");
+ pims_ipc_data_destroy(indata);
+ return CONTACTS_ERROR_IPC;
+ }
+
+ if (indata)
+ {
+ pims_ipc_data_destroy(indata);
+ }
+
+ if (outdata)
+ {
+ // check result
+ unsigned int size = 0;
+ ret = *(int*) pims_ipc_data_get(outdata, &size);
+
+ 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");
+ 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("pims_ipc_call failed");
+ pims_ipc_data_destroy(indata);
+ return CONTACTS_ERROR_IPC;
+ }
+
+ if (indata)
+ {
+ pims_ipc_data_destroy(indata);
+ }
+
+ if (outdata)
+ {
+ // check result
+ unsigned int size = 0;
+ ret = *(int*) pims_ipc_data_get(outdata, &size);
+
+ pims_ipc_data_destroy(outdata);
+ }
+
+ return ret;
+}
+
diff --git a/client/ctsvc_client_db.c b/client/ctsvc_client_db.c new file mode 100644 index 0000000..cf1f9a0 --- /dev/null +++ b/client/ctsvc_client_db.c @@ -0,0 +1,1521 @@ +/* + * 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_query.h" +#include "ctsvc_inotify.h" + +#include "ctsvc_internal.h" +#include "ctsvc_ipc_define.h" +#include "ctsvc_ipc_marshal.h" +#include "ctsvc_view.h" + +#include "ctsvc_client_ipc.h" +#include <pims-ipc-data.h> + +#include "ctsvc_inotify.h" + +typedef struct { + void *callback; + void *user_data; + contacts_list_h list; +}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; + contacts_list_h list = sync_data->list; + int *ids = NULL; + unsigned int count = 0; + + if (data_out) + { + // check outdata + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(data_out,&size); + + if (ret == CONTACTS_ERROR_NONE && list != NULL) + { + int i=0; + unsigned int size = 0; + + count = *(unsigned int*) pims_ipc_data_get(data_out,&size); + ids = calloc(count, sizeof(int)); + for(i=0;i<count;i++) + { + ids[i] = *(int*) pims_ipc_data_get(data_out,&size); + } + } + } + + 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 + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(data_out,&size); + } + + 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 + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(data_out,&size); + } + + 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"); + return ret; + } + + // ipc call + if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_INSERT_RECORD, indata, &outdata) != 0) + { + CTS_ERR("pims_ipc_call failed"); + pims_ipc_data_destroy(indata); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + 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) + { + 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"); + + // 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"); + return ret; + } + ret = ctsvc_ipc_marshal_int(id,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_RECORD, indata, &outdata) != 0) + { + CTS_ERR("pims_ipc_call failed"); + pims_ipc_data_destroy(indata); + *out_record = NULL; + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + 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"); + return ret; + } + + // ipc call + if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_UPDATE_RECORD, indata, &outdata) != 0) + { + CTS_ERR("pims_ipc_call failed"); + pims_ipc_data_destroy(indata); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + pims_ipc_data_destroy(indata); + } + + if (outdata) + { + // check outdata + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata,&size); + + 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"); + return ret; + } + ret = ctsvc_ipc_marshal_int(id,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_DELETE_RECORD, indata, &outdata) != 0) + { + CTS_ERR("pims_ipc_call failed"); + pims_ipc_data_destroy(indata); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + pims_ipc_data_destroy(indata); + } + + if (outdata) + { + // check outdata + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata,&size); + + 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 paramter : 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"); + return ret; + } + ret = ctsvc_ipc_marshal_int(id, 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_REPLACE_RECORD, indata, &outdata) != 0) { + CTS_ERR("pims_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); + 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"); + 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"); + 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"); + return ret; + } + + // ipc call + if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_ALL_RECORDS, indata, &outdata) != 0) + { + CTS_ERR("pims_ipc_call failed"); + pims_ipc_data_destroy(indata); + *out_list = NULL; + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + 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(query==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"query is NULL"); + RETVM_IF(out_list==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"list 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"); + 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"); + 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("pims_ipc_call failed"); + pims_ipc_data_destroy(indata); + *out_list = NULL; + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + 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"); + + // 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"); + return ret; + } + + // ipc call + if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_COUNT, indata, &outdata) != 0) + { + CTS_ERR("pims_ipc_call failed"); + pims_ipc_data_destroy(indata); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + 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"); + + // 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"); + 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("pims_ipc_call failed"); + pims_ipc_data_destroy(indata); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + 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_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; + pims_ipc_data_h outdata = NULL; + contacts_list_h clone_list = NULL; + ctsvc_ipc_async_userdata_s *async_data = NULL; + + RETVM_IF(list==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"list is NULL"); + + + ret = ctsvc_list_clone(list, &clone_list); + RETV_IF(CONTACTS_ERROR_NONE != ret, ret); + + // make indata + indata = pims_ipc_data_create(0); + if (indata == NULL) + { + CTS_ERR("ipc data created fail!"); + ret = CONTACTS_ERROR_OUT_OF_MEMORY; + contacts_list_destroy(clone_list, true); + return ret; + } + ret = ctsvc_ipc_marshal_list(clone_list,indata); + if (ret != CONTACTS_ERROR_NONE) + { + CTS_ERR("marshal fail"); + contacts_list_destroy(clone_list, true); + return ret; + } + + if (callback == NULL) + { + if (ctsvc_ipc_call( CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_INSERT_RECORDS, + indata,&outdata) != 0) + { + CTS_ERR("pims_ipc_call_async failed"); + contacts_list_destroy(clone_list, true); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + 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) + { + goto SET_DATA; + } + + pims_ipc_data_destroy(outdata); + } + + contacts_list_destroy(clone_list, true); + 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; + contacts_list_destroy(clone_list, true); + return ret; + } + async_data->callback = callback; + async_data->user_data = user_data; + async_data->list = clone_list; + 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("pims_ipc_call_async failed"); + contacts_list_destroy(clone_list, true); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + pims_ipc_data_destroy(indata); + } + contacts_list_destroy(clone_list, true); + + return ret; + +SET_DATA: + if (outdata) + { +/* + int count = 0; + int id = 0; + unsigned int property_id = 0; + int i=0; + unsigned int size = 0; + + contacts_list_first(list); + count = *(int*) pims_ipc_data_get(outdata,&size); + property_id = *(unsigned int*) pims_ipc_data_get(outdata,&size); + for(i=0;i<count;i++) + { + contacts_record_h record = NULL; + if (contacts_list_get_current_record_p(list,&record) != CONTACTS_ERROR_NONE) + { + CTS_ERR("contacts_list_get_current_record_p fail"); + pims_ipc_data_destroy(outdata); + return ret; + } + id = *(int*) pims_ipc_data_get(outdata,&size); + ctsvc_record_set_int(record,property_id,id); + } +*/ + pims_ipc_data_destroy(outdata); + } + contacts_list_destroy(clone_list, true); + + 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; + pims_ipc_data_h outdata = NULL; + ctsvc_ipc_async_userdata_s *async_data = NULL; + + RETVM_IF(list==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_list(list,indata); + if (ret != CONTACTS_ERROR_NONE) + { + CTS_ERR("marshal fail"); + return ret; + } + + if (callback == NULL) + { + // ipc call + if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_UPDATE_RECORDS, + indata, &outdata) != 0) + { + CTS_ERR("pims_ipc_call failed"); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + pims_ipc_data_destroy(indata); + } + + if (outdata) + { + // check outdata + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata,&size); + + pims_ipc_data_destroy(outdata); + } + + 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; + return ret; + } + async_data->callback = callback; + async_data->user_data = user_data; + async_data->list = list; + 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("pims_ipc_call_async failed"); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + 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; + pims_ipc_data_h outdata = 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 paramter"); + RETVM_IF(0 == count, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid paramter"); + + // 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"); + return ret; + } + ret = ctsvc_ipc_marshal_int(count,indata); + if (ret != CONTACTS_ERROR_NONE) + { + CTS_ERR("marshal fail"); + 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"); + return ret; + } + } + + if (callback == NULL) + { + // ipc call + if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_DELETE_RECORDS, + indata, &outdata) != 0) + { + CTS_ERR("pims_ipc_call failed"); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + pims_ipc_data_destroy(indata); + } + + if (outdata) + { + // check outdata + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata,&size); + + pims_ipc_data_destroy(outdata); + } + + 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("pims_ipc_call_async failed"); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + 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) { + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(data_out,&size); + //pims_ipc_data_destroy(data_out); + } + + 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[], unsigned int count, + contacts_db_result_cb callback, void *user_data ) +{ + int i; + int ret = CONTACTS_ERROR_NONE; + pims_ipc_data_h indata = NULL; + pims_ipc_data_h outdata = NULL; + ctsvc_ipc_async_userdata_s *async_data = NULL; + + RETVM_IF(NULL == list,CONTACTS_ERROR_INVALID_PARAMETER, "list is NULL"); + RETVM_IF(NULL == ids, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid paramter"); + RETVM_IF(0 == count, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid paramter"); + + // 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"); + return ret; + } + + ret = ctsvc_ipc_marshal_unsigned_int(count, indata); + if (ret != CONTACTS_ERROR_NONE) { + CTS_ERR("marshal fail"); + 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"); + return ret; + } + } + + if (callback == NULL) { + if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_REPLACE_RECORDS, + indata, &outdata) != 0) { + CTS_ERR("pims_ipc_call failed"); + 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; + } + + async_data = (ctsvc_ipc_async_userdata_s*)malloc(sizeof(ctsvc_ipc_async_userdata_s)); + async_data->callback = callback; + async_data->user_data = user_data; + async_data->list = list; + 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("pims_ipc_call_async failed"); + return CONTACTS_ERROR_IPC; + } + + pims_ipc_data_destroy(indata); + + return ret; +} + +API int contacts_db_insert_records( contacts_list_h list, int **ids, unsigned 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"); + RETVM_IF(ctsvc_get_ipc_handle()==NULL,CONTACTS_ERROR_IPC, "contacts not connected"); + + 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("pims_ipc_call_async 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 (ids && count) { + int i = 0; + int *id = NULL; + unsigned int c; + c = *(unsigned 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, "record is NULL"); + RETVM_IF(ctsvc_get_ipc_handle() == NULL, CONTACTS_ERROR_IPC, "contacts not connected"); + + 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("pims_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_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"); + RETVM_IF(ctsvc_get_ipc_handle() == NULL, CONTACTS_ERROR_IPC, "contacts not connected"); + + 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("pims_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_db_replace_records( contacts_list_h list, int ids[], unsigned 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 paramter"); + RETVM_IF(0 == count, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid paramter"); + + // 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"); + return ret; + } + + ret = ctsvc_ipc_marshal_unsigned_int(count, indata); + if (ret != CONTACTS_ERROR_NONE) { + CTS_ERR("marshal fail"); + 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"); + return ret; + } + } + + if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_REPLACE_RECORDS, + indata, &outdata) != 0) { + CTS_ERR("pims_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_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(view_uri==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"view_uri is NULL"); + RETVM_IF(record_list==NULL,CONTACTS_ERROR_INVALID_PARAMETER,"record_list 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"); + return ret; + } + ret = ctsvc_ipc_marshal_int(addressbook_id,indata); + if (ret != CONTACTS_ERROR_NONE) + { + CTS_ERR("marshal fail"); + return ret; + } + ret = ctsvc_ipc_marshal_int(contacts_db_version,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_CHANGES_BY_VERSION, indata, &outdata) != 0) + { + CTS_ERR("pims_ipc_call failed"); + pims_ipc_data_destroy(indata); + *record_list = NULL; + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + 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"); + + // ipc call + if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_GET_CURRENT_VERSION, NULL, &outdata) != 0) + { + CTS_ERR("pims_ipc_call failed"); + return CONTACTS_ERROR_IPC; + } + + 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,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"); + RETVM_IF(ctsvc_get_ipc_handle() == NULL, CONTACTS_ERROR_IPC, "contacts not connected"); + + // 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"); + return ret; + } + ret = ctsvc_ipc_marshal_string(keyword,indata); + if (ret != CONTACTS_ERROR_NONE) + { + CTS_ERR("marshal fail"); + 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"); + return ret; + } + + // ipc call + if (ctsvc_ipc_call(CTSVC_IPC_DB_MODULE, CTSVC_IPC_SERVER_DB_SEARCH_RECORDS, indata, &outdata) != 0) + { + CTS_ERR("pims_ipc_call failed"); + pims_ipc_data_destroy(indata); + *out_list = NULL; + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + 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_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(query==NULL, CONTACTS_ERROR_INVALID_PARAMETER, "query is NULL"); + RETVM_IF(out_list==NULL, CONTACTS_ERROR_INVALID_PARAMETER, "list is NULL"); + RETVM_IF(ctsvc_get_ipc_handle() == NULL, CONTACTS_ERROR_IPC, "contacts not connected"); + + // 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"); + return ret; + } + ret = ctsvc_ipc_marshal_string(keyword,indata); + if (ret != CONTACTS_ERROR_NONE) + { + CTS_ERR("marshal fail"); + 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"); + 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("pims_ipc_call failed"); + pims_ipc_data_destroy(indata); + *out_list = NULL; + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + 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; +} + diff --git a/client/ctsvc_client_group.c b/client/ctsvc_client_group.c new file mode 100644 index 0000000..dc284d8 --- /dev/null +++ b/client/ctsvc_client_group.c @@ -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. + * + */ + +#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"); + RETVM_IF(ctsvc_get_ipc_handle() == NULL,CONTACTS_ERROR_IPC,"contacts not connected"); + + // 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"); + return ret; + } + ret = ctsvc_ipc_marshal_int( contact_id, indata); + if (ret != CONTACTS_ERROR_NONE) + { + CTS_ERR("marshal fail"); + return ret; + } + + // ipc call + if (ctsvc_ipc_call(CTSVC_IPC_GROUP_MODULE, CTSVC_IPC_SERVER_GROUP_ADD_CONTACT, indata, &outdata) != 0) + { + CTS_ERR("pims_ipc_call failed"); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + pims_ipc_data_destroy(indata); + } + + if (outdata) + { + // check result + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata, &size); + + 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"); + RETVM_IF(ctsvc_get_ipc_handle() == NULL,CONTACTS_ERROR_IPC,"contacts not connected"); + + // 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"); + return ret; + } + ret = ctsvc_ipc_marshal_int( contact_id, indata); + if (ret != CONTACTS_ERROR_NONE) + { + CTS_ERR("marshal fail"); + return ret; + } + + // ipc call + if (ctsvc_ipc_call(CTSVC_IPC_GROUP_MODULE, CTSVC_IPC_SERVER_GROUP_REMOVE_CONTACT, indata, &outdata) != 0) + { + CTS_ERR("pims_ipc_call failed"); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + pims_ipc_data_destroy(indata); + } + + if (outdata) + { + // check result + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata, &size); + + pims_ipc_data_destroy(outdata); + } + + return ret; +} + diff --git a/client/ctsvc_client_ipc.c b/client/ctsvc_client_ipc.c new file mode 100755 index 0000000..339dd77 --- /dev/null +++ b/client/ctsvc_client_ipc.c @@ -0,0 +1,279 @@ + + +#include <glib.h> +//#include <glib-oject.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_internal.h" +#include "ctsvc_ipc_define.h" +#include "ctsvc_ipc_marshal.h" +#include "ctsvc_view.h" +#include <pims-ipc-data.h> +#include "ctsvc_mutex.h" + +static __thread pims_ipc_h contacts_ipc = NULL; + +static pims_ipc_h contacts_global_ipc = NULL; + +int ctsvc_ipc_connect_on_thread(void) +{ + int ret = CONTACTS_ERROR_NONE; + pims_ipc_data_h indata = NULL; + pims_ipc_data_h outdata = NULL; + + // ipc create + if (contacts_ipc == NULL) + { + contacts_ipc = pims_ipc_create(CTSVC_IPC_SOCKET_PATH); + if (contacts_ipc == NULL) + { + CTS_ERR("pims_ipc_create() Failed(%d)", CONTACTS_ERROR_IPC_NOT_AVALIABLE); + return CONTACTS_ERROR_IPC_NOT_AVALIABLE; + } + } + else + { + CTS_DBG("contacts already connected"); + return CONTACTS_ERROR_NONE; + } + + // ipc call + if (pims_ipc_call(contacts_ipc, CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_CONNECT, indata, &outdata) != 0) + { + CTS_ERR("pims_ipc_call failed"); + return CONTACTS_ERROR_IPC; + } + + if (outdata) + { + // check outdata + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata,&size); + + pims_ipc_data_destroy(outdata); + + if (ret == CONTACTS_ERROR_NONE) + { + + } + else + { + pims_ipc_destroy(contacts_ipc); + contacts_ipc = NULL; + } + } + + return ret; +} + +int ctsvc_ipc_disconnect_on_thread(void) +{ + int ret = CONTACTS_ERROR_NONE; + pims_ipc_data_h indata = NULL; + pims_ipc_data_h outdata = NULL; + + RETVM_IF(contacts_ipc == NULL, CONTACTS_ERROR_IPC, "contacts not connected"); + + // ipc call + if (pims_ipc_call(contacts_ipc, CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_DISCONNECT, indata, &outdata) != 0) + { + CTS_ERR("pims_ipc_call failed"); + return CONTACTS_ERROR_IPC; + } + + if (outdata) + { + // check outdata + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata,&size); + + pims_ipc_data_destroy(outdata); + } + + if (contacts_ipc && ret != CONTACTS_ERROR_NONE) + { + pims_ipc_destroy(contacts_ipc); + contacts_ipc = NULL; + } + + return ret; +} + +pims_ipc_h ctsvc_get_ipc_handle() +{ + if(contacts_ipc == NULL) + { + if(contacts_global_ipc == NULL ) + { + ASSERT_NOT_REACHED("IPC haven't been initialized yet."); + return NULL; + } + CTS_DBG("fallback to global ipc channel"); + return contacts_global_ipc; + } + + return contacts_ipc; +} + +bool ctsvc_ipc_is_busy() +{ + bool ret = false; + + if(contacts_ipc != NULL) + { + ret = pims_ipc_is_call_in_progress(contacts_ipc); + if(ret) + { + CTS_ERR("thread local ipc channel is busy."); + } + } + else { + ret = pims_ipc_is_call_in_progress(contacts_global_ipc); + if(ret) + { + CTS_ERR("global ipc channel is busy."); + } + } + + return ret; +} + + + +int ctsvc_ipc_connect(void) +{ + int ret = CONTACTS_ERROR_NONE; + pims_ipc_data_h indata = NULL; + pims_ipc_data_h outdata = NULL; + + // ipc create + if (contacts_global_ipc == NULL) + { + contacts_global_ipc = pims_ipc_create(CTSVC_IPC_SOCKET_PATH); + if (contacts_global_ipc == NULL) + { + CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc_create() Failed(%d)", CONTACTS_ERROR_IPC_NOT_AVALIABLE); + return CONTACTS_ERROR_IPC_NOT_AVALIABLE; + } + } + else + { + CTS_DBG("[GLOBAL_IPC_CHANNEL] contacts already connected"); + return CONTACTS_ERROR_NONE; + } + + // ipc call + if (pims_ipc_call(contacts_global_ipc, CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_CONNECT, indata, &outdata) != 0) + { + CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc_call failed"); + return CONTACTS_ERROR_IPC; + } + + if (outdata) + { + // check outdata + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata,&size); + + pims_ipc_data_destroy(outdata); + + if (ret == CONTACTS_ERROR_NONE) + { + + } + else + { + pims_ipc_destroy(contacts_global_ipc); + contacts_global_ipc = NULL; + } + } + + return ret; +} + + +int ctsvc_ipc_disconnect(void) +{ + int ret = CONTACTS_ERROR_NONE; + pims_ipc_data_h indata = NULL; + pims_ipc_data_h outdata = NULL; + + RETVM_IF(contacts_global_ipc == NULL, CONTACTS_ERROR_IPC, "[GLOBAL_IPC_CHANNEL] contacts not connected"); + + // ipc call + if (pims_ipc_call(contacts_global_ipc, CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_DISCONNECT, indata, &outdata) != 0) + { + CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc_call failed"); + return CONTACTS_ERROR_IPC; + } + + if (outdata) + { + // check outdata + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata,&size); + + pims_ipc_data_destroy(outdata); + } + + if (contacts_global_ipc && ret == CONTACTS_ERROR_NONE) + { + pims_ipc_destroy(contacts_global_ipc); + contacts_global_ipc = NULL; + } + else + { + CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc didn't destroyed!!!(%d)", ret); + } + + return ret; +} + + +void __ctsvc_ipc_lock() +{ + if (contacts_ipc == NULL) + { + ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_CALL); + } +} + +void __ctsvc_ipc_unlock(void) +{ + if (contacts_ipc == NULL) + { + 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) +{ + 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) +{ + 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; +} diff --git a/client/ctsvc_client_ipc.h b/client/ctsvc_client_ipc.h new file mode 100644 index 0000000..39515d7 --- /dev/null +++ b/client/ctsvc_client_ipc.h @@ -0,0 +1,44 @@ +/* + * 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); + +int ctsvc_ipc_connect_on_thread(void); +int ctsvc_ipc_disconnect_on_thread(void); + + +bool ctsvc_ipc_is_busy(); + +int ctsvc_ipc_create_for_change_subscription(); +int ctsvc_ipc_destroy_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); + + +#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 index 0000000..946197f --- /dev/null +++ b/client/ctsvc_client_noti.c @@ -0,0 +1,179 @@ +/*
+ * 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"
+
+typedef struct
+{
+ contacts_db_change_cb_with_info cb;
+ void *user_data;
+}callback_info_s;
+
+typedef struct
+{
+ char *view_uri;
+ GSList *callbacks;
+}subscribe_info_s;
+
+static pims_ipc_h __ipc = NULL;
+static GSList *__subscribe_list = NULL;
+
+static void __ctsvc_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;
+
+ INFO("(%x) subscribe_callback(%p)", (unsigned int)pthread_self(), ipc);
+ if (data) {
+ str = (char*)pims_ipc_data_get(data, &size);
+ if (!str) {
+ CTS_ERR("pims_ipc_data_get fail()");
+ return;
+ }
+ }
+ if (info) {
+ GSList *l;
+ for (l = info->callbacks;l;l=l->next) {
+ callback_info_s *cb_info = l->data;
+ cb_info->cb(info->view_uri, str, cb_info->user_data);
+ }
+ }
+}
+
+int ctsvc_ipc_create_for_change_subscription()
+{
+ ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+
+ 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;
+ }
+ }
+ 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);
+
+ pims_ipc_destroy_for_subscribe(__ipc);
+ __ipc = NULL;
+
+ 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;
+ callback_info_s *cb_info;
+
+ ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+
+ for (it=__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_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);
+ __subscribe_list = g_slist_append(__subscribe_list, info);
+ }
+
+ cb_info = calloc(1, sizeof(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;
+
+ ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_PUBSUB);
+
+ for (it=__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) {
+ 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);
+ break;
+ }
+ }
+ if (g_slist_length(info->callbacks) == 0) {
+ pims_ipc_unsubscribe(__ipc, CTSVC_IPC_SUBSCRIBE_MODULE, info->view_uri);
+ __subscribe_list = g_slist_remove(__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 index 0000000..8b3329a --- /dev/null +++ b/client/ctsvc_client_person.c @@ -0,0 +1,418 @@ +/* + * 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_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"); + RETVM_IF(ctsvc_get_ipc_handle() == NULL,CONTACTS_ERROR_IPC,"contacts not connected"); + + // 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("pims_ipc_call failed"); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + pims_ipc_data_destroy(indata); + } + + if (outdata) + { + // check result + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata, &size); + + 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"); + RETVM_IF(ctsvc_get_ipc_handle() == NULL,CONTACTS_ERROR_IPC,"contacts not connected"); + + 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("pims_ipc_call failed"); + pims_ipc_data_destroy(indata); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + 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) { + 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"); + RETVM_IF(ctsvc_get_ipc_handle() == NULL,CONTACTS_ERROR_IPC,"contacts not connected"); + + // 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("pims_ipc_call failed"); + pims_ipc_data_destroy(indata); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + pims_ipc_data_destroy(indata); + } + + if (outdata) + { + // check result + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata, &size); + + 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"); + RETVM_IF(ctsvc_get_ipc_handle() == NULL,CONTACTS_ERROR_IPC,"contacts not connected"); + + // 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("pims_ipc_call failed"); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + pims_ipc_data_destroy(indata); + } + + if (outdata) + { + // check result + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata, &size); + + 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"); + RETVM_IF(ctsvc_get_ipc_handle() == NULL,CONTACTS_ERROR_IPC,"contacts not connected"); + + // 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("pims_ipc_call failed"); + pims_ipc_data_destroy(indata); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + pims_ipc_data_destroy(indata); + } + + if (outdata) + { + // check result + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata, &size); + + 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; + RETVM_IF(ctsvc_get_ipc_handle() == NULL,CONTACTS_ERROR_IPC,"contacts not connected"); + + // 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("pims_ipc_call failed"); + pims_ipc_data_destroy(indata); + return CONTACTS_ERROR_IPC; + } + + if (indata) { + 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 index 0000000..67e25fc --- /dev/null +++ b/client/ctsvc_client_phonelog.c @@ -0,0 +1,148 @@ +/* + * 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_phone_log_reset_statistics(void) +{ + int ret = CONTACTS_ERROR_NONE; + + pims_ipc_data_h indata = NULL; + pims_ipc_data_h outdata = NULL; + + RETVM_IF(ctsvc_get_ipc_handle() == NULL,CONTACTS_ERROR_IPC,"contacts not connected"); + + // 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("pims_ipc_call failed"); + return CONTACTS_ERROR_IPC; + } + + if (indata) + { + pims_ipc_data_destroy(indata); + } + + if (outdata) + { + // check result + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata, &size); + + pims_ipc_data_destroy(outdata); + } + + return ret; + +} + +API int contacts_phone_log_delete(contacts_phone_log_delete_e op, ...) +{ + 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; + + RETVM_IF(ctsvc_get_ipc_handle() == NULL,CONTACTS_ERROR_IPC, "contacts not connected"); + + 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); + RETV_IF(NULL == number, 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("pims_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; +} + diff --git a/client/ctsvc_client_service.c b/client/ctsvc_client_service.c new file mode 100644 index 0000000..35f3cd7 --- /dev/null +++ b/client/ctsvc_client_service.c @@ -0,0 +1,199 @@ +/* + * 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_setting.h" +#include "ctsvc_client_ipc.h" + +static int ctsvc_connection = 0; + +static int __thread ctsvc_connection_on_thread = 0; + +API int contacts_connect_with_flags(unsigned int flags) +{ + CTS_FN_CALL; + int ret = CONTACTS_ERROR_NONE; + + ret = contacts_connect2(); + if (ret == CONTACTS_ERROR_NONE) + return ret; + + if (flags & CONTACTS_CONNECT_FLAG_RETRY) { + int i; + int waiting_time = 500; + for (i=0;i<6;i++) { + usleep(waiting_time * 1000); + DBG("retry cnt=%d, ret=%x, %d",(i+1), ret, waiting_time); + ret = contacts_connect2(); + if (ret == CONTACTS_ERROR_NONE) + break; + waiting_time *= 2; + } + } + + return ret; +} + +API int contacts_connect2() +{ + 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_view_uri_init(); + ctsvc_register_vconf(); + ctsvc_ipc_create_for_change_subscription(); + } + 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_disconnect2() +{ + 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_close(); + ctsvc_socket_final(); + ctsvc_deregister_vconf(); + + } + else if (1 < ctsvc_connection) + CTS_DBG("System : connection count is %d", ctsvc_connection); + else { + CTS_DBG("System : please call contacts_connect2(), 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() +{ + int ret; + + ctsvc_mutex_lock(CTS_MUTEX_CONNECTION); + + ret = ctsvc_ipc_connect_on_thread(); + if (ret != CONTACTS_ERROR_NONE) { + CTS_ERR("ctsvc_ipc_connect_on_thread() Failed(%d)", ret); + ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION); + return ret; + } + + 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() +{ + int ret; + + ctsvc_mutex_lock(CTS_MUTEX_CONNECTION); + + ret = ctsvc_ipc_disconnect_on_thread(); + if (ret != CONTACTS_ERROR_NONE) { + CTS_ERR("ctsvc_ipc_disconnect_on_thread() Failed(%d)", ret); + ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION); + return ret; + } + + if (1 == ctsvc_connection_on_thread) { + 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_sim.c b/client/ctsvc_client_sim.c new file mode 100644 index 0000000..f68054f --- /dev/null +++ b/client/ctsvc_client_sim.c @@ -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 "contacts.h" +#include "ctsvc_internal.h" +#include "ctsvc_ipc_define.h" +#include "ctsvc_ipc_marshal.h" +#include "ctsvc_client_ipc.h" +#include <pims-ipc-data.h> + +API int contacts_sim_insert(contacts_record_h record, int *contact_id) +{ + 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; + } + + 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_SIM_MODULE, CTSVC_IPC_SERVER_SIM_INSERT_CONTACT, indata, &outdata) != 0) + { + pims_ipc_data_destroy(indata); + CTS_ERR("pims_ipc_call failed"); + return CONTACTS_ERROR_IPC; + } + + if (outdata) + { + // check result + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata, &size); + + pims_ipc_data_destroy(outdata); + } + + pims_ipc_data_destroy(indata); + + return ret; +} + +API int contacts_sim_update(contacts_record_h record) +{ + 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; + } + + 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_SIM_MODULE, CTSVC_IPC_SERVER_SIM_UPDATE_CONTACT, indata, &outdata) != 0) + { + pims_ipc_data_destroy(indata); + CTS_ERR("pims_ipc_call failed"); + return CONTACTS_ERROR_IPC; + } + + if (outdata) + { + // check result + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata, &size); + + pims_ipc_data_destroy(outdata); + } + + pims_ipc_data_destroy(indata); + + return ret; +} + +API int contacts_sim_delete(int person_id) +{ + 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,"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; + } + + // ipc call + if (ctsvc_ipc_call(CTSVC_IPC_SIM_MODULE, CTSVC_IPC_SERVER_SIM_DELETE_CONTACT, indata, &outdata) != 0) + { + pims_ipc_data_destroy(indata); + CTS_ERR("pims_ipc_call failed"); + return CONTACTS_ERROR_IPC; + } + + if (outdata) + { + // check result + unsigned int size = 0; + ret = *(int*) pims_ipc_data_get(outdata, &size); + + pims_ipc_data_destroy(outdata); + } + + pims_ipc_data_destroy(indata); + + return ret; +} diff --git a/common/ctsvc_db_notification.c b/common/ctsvc_db_notification.c new file mode 100644 index 0000000..1af62e8 --- /dev/null +++ b/common/ctsvc_db_notification.c @@ -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 <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,
+ "Invaild parameter : view_uri is null");
+
+ ret = ctsvc_inotify_subscribe(view_uri, cb, user_data);
+ RETVM_IF(CONTACTS_ERROR_NONE != ret, ret,
+ "ctsvc_inotify_subscribe(%d) 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,
+ "Invaild parameter : view_uri is null");
+
+ ret = ctsvc_inotify_unsubscribe(view_uri, cb, user_data);
+ RETVM_IF(CONTACTS_ERROR_NONE != ret, ret,
+ "ctsvc_inotify_unsubscribe(%d) 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 index 0000000..7efb32a --- /dev/null +++ b/common/ctsvc_filter.c @@ -0,0 +1,339 @@ +/* + * 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 = p->type; + 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)); + + 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)); + 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:, property_id:0x%x, match:%d, match_value :%s", + property_id, match, match_value); + + 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); + + 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, match_value :%d", + com_filter->view_uri, property_id, match, match_value); + + 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, match_value :%d", + property_id, match, match_value); + + 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, match_value :%d", + property_id, match, match_value); + + 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, match_value :%d", + property_id, match_value); + + 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->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)); + 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) +{ + GSList *cursor; + ctsvc_composite_filter_s *out; + + RETV_IF(NULL == filter, CONTACTS_ERROR_INVALID_PARAMETER); + contacts_filter_create(filter->view_uri, (contacts_filter_h *)&out); + + 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); +} diff --git a/common/ctsvc_filter.h b/common/ctsvc_filter.h new file mode 100644 index 0000000..31b22e4 --- /dev/null +++ b/common/ctsvc_filter.h @@ -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_FILTER_H__
+#define __TIZEN_SOCIAL_CTSVC_FILTER_H__
+
+int ctsvc_filter_clone(contacts_filter_h filter, contacts_filter_h *out_filter);
+
+#endif /* __TIZEN_SOCIAL_CTSVC_FILTER_H__ */
+
diff --git a/common/ctsvc_inotify.c b/common/ctsvc_inotify.c new file mode 100755 index 0000000..6b8e6cc --- /dev/null +++ b/common/ctsvc_inotify.c @@ -0,0 +1,399 @@ +/* + * 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; + +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 (__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; + } + 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; + __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; + } + + 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: + return CTSVC_NOTI_CONTACT_CHANGED; + case CTSVC_RECORD_MY_PROFILE: + return CTSVC_NOTI_MY_PROFILE_CHANGED; + case CTSVC_RECORD_SIMPLE_CONTACT: + return CTSVC_NOTI_SIMPLE_CONTACT_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_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(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); + RETVM_IF(-1 == wd, CONTACTS_ERROR_SYSTEM, + "__ctsvc_inotify_get_wd() Failed(%d)", errno); + + 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", path); + return CONTACTS_ERROR_SYSTEM; + } + + 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); + RETVM_IF(-1 == wd, CONTACTS_ERROR_SYSTEM, + "System: __ctsvc_inotify_get_wd() Failed(%d)", errno); + + 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 (__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 index 0000000..d1c6f43 --- /dev/null +++ b/common/ctsvc_inotify.h @@ -0,0 +1,32 @@ +/* + * 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(); + +#endif //__TIZEN_SOCIAL_CTSVC_INOTIFY_H__ diff --git a/common/ctsvc_internal.h b/common/ctsvc_internal.h new file mode 100644 index 0000000..049cc08 --- /dev/null +++ b/common/ctsvc_internal.h @@ -0,0 +1,143 @@ +/* + * 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 +#define API __attribute__ ((visibility("default"))) +//#undef API +#endif + + +//#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(IPC_ROLE" "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 index 0000000..3e4879a --- /dev/null +++ b/common/ctsvc_list.c @@ -0,0 +1,424 @@ +/* + * 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, 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; + + *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; + bool is_first = false; + + 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; + is_first = true; + } + 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; + bool is_first = false; + + 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; + is_first = true; + } + 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; + bool is_first = false; + + 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; + is_first = true; + } + 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; + ctsvc_record_s *data; + 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++) { + data = (ctsvc_record_s *)cursor->data; + 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; + ctsvc_record_s *data; + 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) { + data = (ctsvc_record_s *)cursor->data; + err = contacts_record_clone((contacts_record_h)cursor->data, &new_record); + RETVM_IF(CONTACTS_ERROR_NONE != err, err,"contacts_record_clone() Failed(%d)", err); + ctsvc_list_prepend(new_list, new_record); + } + ctsvc_list_reverse(new_list); + + for(cursor = list_s->deleted_records;cursor;cursor=cursor->next) { + data = (ctsvc_record_s *)cursor->data; + err = contacts_record_clone((contacts_record_h)cursor->data, &new_record); + RETVM_IF(CONTACTS_ERROR_NONE != err, err,"contacts_record_clone() Failed(%d)", 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 = (ctsvc_record_s *)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 index 0000000..b13f6bf --- /dev/null +++ b/common/ctsvc_list.h @@ -0,0 +1,40 @@ +/*
+ * 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_LIST_H__
+#define __TIZEN_SOCIAL_CTSVC_LIST_H__
+
+#include "contacts_views.h"
+
+int ctsvc_list_clone(contacts_list_h list, contacts_list_h* out_list);
+int ctsvc_list_get_nth_record_p( contacts_list_h list, int index, contacts_record_h* record );
+int ctsvc_list_add_child( contacts_list_h list, contacts_record_h child_record );
+int ctsvc_list_prepend( contacts_list_h list, contacts_record_h child_record );
+int ctsvc_list_reverse( contacts_list_h list);
+int ctsvc_list_remove_child( contacts_list_h list, contacts_record_h record, bool insert_delete_list );
+
+int ctsvc_list_get_deleted_count(contacts_list_h list, unsigned int *count );
+int ctsvc_list_get_deleted_nth_record_p( contacts_list_h list, int index, contacts_record_h* record );
+int ctsvc_list_append_deleted_record(contacts_list_h list, contacts_record_h record);
+
+#endif /* __TIZEN_SOCIAL_CTSVC_LIST_H__ */
diff --git a/common/ctsvc_localize.c b/common/ctsvc_localize.c new file mode 100755 index 0000000..c53957a --- /dev/null +++ b/common/ctsvc_localize.c @@ -0,0 +1,502 @@ +/* + * Contacts Service Helper + * + * 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_normalize.h" +#include "ctsvc_localize.h" + +#define CTSVC_COMPARE_BETWEEN(left_range, value, right_range) (((left_range) <= (value)) && ((value) <= (right_range))) + +/* 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 + +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}; + +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; +} + +static inline bool 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)) + 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 (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_check_language(UChar *word) +{ + int type; + + int unicode_value1 = 0; + int unicode_value2 = 0; + + unicode_value1 = (0xFF00 & (*word)) >> 8; + unicode_value2 = (0xFF & (*word)); + + CTS_VERBOSE("0x%x%x", unicode_value1, unicode_value2); + + if (CTSVC_COMPARE_BETWEEN('0', word[0], '9')) { + type = CTSVC_LANG_NUMBER; + } + else if (CTSVC_COMPARE_BETWEEN(0x41, word[0], 0x7A)) { /* english */ + type = CTSVC_LANG_ENGLISH; + } + else if (is_hangul(word[0])){ + type = CTSVC_LANG_KOREAN; + } + else if (0x4E00 <= *word && *word <= 0x9FA5) { + type = CTSVC_LANG_ENGLISH; + } + +#if 0 // TODO + else if () + type = CTSVC_LANG_CHINESE; + else if () + type = CTSVC_LANG_JAPANESE; + else if () + type = CTSVC_LANG_FRENCH; + else if () + type = CTSVC_LANG_GERMAN; + else if () + type = CTSVC_LANG_ITALIAN; + else if () + type = CTSVC_LANG_RUSSIAN; + else if () + type = CTSVC_LANG_DUTCH; + else if () + type = CTSVC_LANG_PORTUGUESE; + else if () + type = CTSVC_LANG_TURKISH; + else if () + type = CTSVC_LANG_GREEK; + else if () + type = CTSVC_LANG_SPANISH; + else if () + type = CTSVC_LANG_DANISH; + else if () + type = CTSVC_LANG_AZERBAIJAN; + else if () + type = CTSVC_LANG_ARABIC; + else if () + type = CTSVC_LANG_BULGARIAN; + else if () + type = CTSVC_LANG_CATALAN; + else if () + type = CTSVC_LANG_CZECH; + else if () + type = CTSVC_LANG_ESTONIAN; + else if () + type = CTSVC_LANG_BASQUE; + else if () + type = CTSVC_LANG_FINNISH; + else if () + type = CTSVC_LANG_IRISH; + else if () + type = CTSVC_LANG_GALICIAN; + else if () + type = CTSVC_LANG_HINDI; + else if () + type = CTSVC_LANG_CROATIAN; + else if () + type = CTSVC_LANG_HUNGARIAN; + else if () + type = CTSVC_LANG_ARMENIAN; + else if () + type = CTSVC_LANG_ICELANDIC; + else if () + type = CTSVC_LANG_GEORGIAN; + else if () + type = CTSVC_LANG_KAZAKHSTAN; + else if () + type = CTSVC_LANG_LITHUANIAN; + else if () + type = CTSVC_LANG_LATVIAN; + else if () + type = CTSVC_LANG_MACEDONIA; + else if () + type = CTSVC_LANG_NORWAY; + else if () + type = CTSVC_LANG_POLISH; + else if () + type = CTSVC_LANG_ROMANIA; + else if () + type = CTSVC_LANG_SLOVAK; + else if () + type = CTSVC_LANG_SLOVENIAN; + else if () + type = CTSVC_LANG_SERBIAN; + else if () + type = CTSVC_LANG_SWEDISH; + else if () + type = CTSVC_LANG_UKRAINE; +#endif + else + type = CTSVC_LANG_OTHERS; + + CTS_VERBOSE("language type = %d", type); + return type; +} + +#define array_sizeof(a) (sizeof(a) / sizeof(a[0])) + +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; + int32_t size; + + 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)); + + 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)); + + CTS_VERBOSE("0x%x%x", (0xFF00 & (tmp_result[0])) >> 8, (0xFF & (tmp_result[0]))); + + return ctsvc_check_language(result); + } + + return CONTACTS_ERROR_INVALID_PARAMETER; +} + +void ctsvc_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 ctsvc_get_language_type(const char *system_lang) +{ + 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; + // 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; + else + type = CTSVC_LANG_OTHERS; + + return type; +} + +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)); + + 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; +} + diff --git a/common/ctsvc_localize.h b/common/ctsvc_localize.h new file mode 100755 index 0000000..0621d60 --- /dev/null +++ b/common/ctsvc_localize.h @@ -0,0 +1,30 @@ +/* + * Contacts Service Helper + * + * 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> + +int ctsvc_check_utf8(char c); +int ctsvc_check_language(UChar *word); +int ctsvc_check_language_type(const char *src); +int ctsvc_get_language_type(const char *system_lang); +void ctsvc_extra_normalize(UChar *word, int32_t word_size); +int ctsvc_get_chosung(const char *src, char *dest, int dest_size); +#endif // __TIZEN_SOCIAL_CTSVC_LOCALIZE_H__ diff --git a/common/ctsvc_localize_ch.c b/common/ctsvc_localize_ch.c new file mode 100755 index 0000000..9d7f29d --- /dev/null +++ b/common/ctsvc_localize_ch.c @@ -0,0 +1,2276 @@ +/* + * Contacts Service Helper + * + * 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" + + +#define CHINESE_COUNT 20902 +#define CHINESE_DUOYINZI_MAX_COUNT 6 + + +#define CHINESE_UNICODE_START 0x4E01 +#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","di|zhai","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; +} + +#define array_sizeof(a) (sizeof(a) / sizeof(a[0])) + +bool ctsvc_has_chinese(const char *src) +{ + UChar temp[strlen(src)+1]; + UErrorCode status = 0; + + RETVM_IF(src==NULL, CONTACTS_ERROR_SYSTEM, "src is NULL"); + RETVM_IF(!*src, CONTACTS_ERROR_SYSTEM, "*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); +} + +int ctsvc_convert_chinese_to_pinyin(const char *src, pinyin_name_s **name, int *size) +{ + char spell[CHINESE_PINYIN_MAX_LEN][CHINESE_DUOYINZI_MAX_COUNT][CHINESE_PINYIN_SPELL_MAX_LEN] + = {NULL}; + int pinyin_spell_count[CHINESE_PINYIN_MAX_LEN] = {0};; + UChar temp_result[strlen(src)+1]; + int count = 0, len=0, total_count=0; + int ret, i, j; + UErrorCode status = 0; + pinyin_name_s *temp_name = NULL; + + 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); + for (count = 0; count < len && count < CHINESE_PINYIN_MAX_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); + pinyin_spell_count[count] = ret; + + if(total_count==0) + total_count = ret; + else + total_count *= ret; + } + else { + UChar temp[2]; + int size; + + temp[0] = temp_result[count]; + temp[1] = 0x00; + u_strToUTF8(spell[count][0], 10, &size, temp, -1, &status); + RETVM_IF(U_FAILURE(status), CONTACTS_ERROR_SYSTEM, "u_strToUTF8() Failed(%s)", u_errorName(status)); + spell[count][0][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(%s)"); + + int repeat = 1; + int name_len[total_count]; + int initial_len[total_count]; + 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; + } + + if (spell[i][index][0]) { + name_len[j] += snprintf(temp_name[j].pinyin_name + name_len[j], sizeof(temp_name[j].pinyin_name) - name_len[j], + "%s ", spell[i][index]); + initial_len[j] += snprintf(temp_name[j].pinyin_initial + initial_len[j], sizeof(temp_name[j].pinyin_initial) - initial_len[j], + "%c", spell[i][index][0]); + } + } + repeat *= pinyin_spell_count[i]; + } + +// for(j=0;j<total_count;j++) { +// DBG("temp_name[%d]->pinyin_name %s", j, temp_name[j].pinyin_name); +// DBG("temp_name[%d]->pinyin_initial %s", j, temp_name[j].pinyin_initial); +// } + + *name = temp_name; + + return CONTACTS_ERROR_NONE; +} + diff --git a/common/ctsvc_localize_ch.h b/common/ctsvc_localize_ch.h new file mode 100755 index 0000000..33396e4 --- /dev/null +++ b/common/ctsvc_localize_ch.h @@ -0,0 +1,34 @@ +/* + * Contacts Service Helper + * + * 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 +#define CHINESE_PINYIN_MAX_LEN 3 + +typedef struct { + char pinyin_initial[CHINESE_PINYIN_MAX_LEN+1]; + char pinyin_name[CHINESE_PINYIN_SPELL_MAX_LEN*(CHINESE_PINYIN_MAX_LEN+1)]; +} pinyin_name_s; + +int ctsvc_convert_chinese_to_pinyin(const char *src, pinyin_name_s **name, int *size); + +bool ctsvc_has_chinese(const char *src); + +#endif // __TIZEN_SOCIAL_CTSVC_LOCALIZE_CH_H__ diff --git a/common/ctsvc_mutex.c b/common/ctsvc_mutex.c new file mode 100755 index 0000000..bf7d8fd --- /dev/null +++ b/common/ctsvc_mutex.c @@ -0,0 +1,97 @@ +/* + * 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 cts_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 inline pthread_mutex_t* cts_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; + 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; + + mutex = cts_mutex_get_mutex(type); + + if (cts_mutex_funtions.lock) { + ret = cts_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 = cts_mutex_get_mutex(type); + + if (cts_mutex_funtions.unlock) { + ret = cts_mutex_funtions.unlock(mutex); + WARN_IF(ret, "mutex_unlock Failed(%d)", ret); + } +} + diff --git a/common/ctsvc_mutex.h b/common/ctsvc_mutex.h new file mode 100755 index 0000000..21de5df --- /dev/null +++ b/common/ctsvc_mutex.h @@ -0,0 +1,37 @@ +/* + * Contacts Service + * + * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngjae Shin <yj99.shin@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#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, +}; + +void ctsvc_mutex_lock(int type); +void ctsvc_mutex_unlock(int type); + + +#endif //__CTSVC_MUTEX_H__ diff --git a/common/ctsvc_normalize.c b/common/ctsvc_normalize.c new file mode 100644 index 0000000..1f3d4f4 --- /dev/null +++ b/common/ctsvc_normalize.c @@ -0,0 +1,806 @@ +/* + * 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/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" + +#define CTSVC_NORMALIZED_NUMBER_SIZE_MAX 7 +#define CTSVC_NORMALIZED_MAX_LEN 1024 + + + +static inline bool __ctsvc_check_dirty_number(char digit) +{ + switch (digit) + { + case '0' ... '9': + case 'p': + case 'w': + case 'P': + case 'W': + case '#': + case '*': + case '(': + case '/': + case ')': + case 'N': + case ',': + case '.': + case ';': + return false; + case '+': //only first position + default: + return true; + } +} + +int ctsvc_clean_number(const char *src, char *dest, int dest_size) +{ + int s_pos=0, d_pos=0, char_type; + + if (NULL == src) + CTS_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 = ctsvc_check_utf8(src[s_pos]); + if (char_type <= 1) { + if (__ctsvc_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 inline const char* __ctsvc_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: + CTS_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: + CTS_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: + CTS_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: + CTS_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: + CTS_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: + CTS_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: + 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 src; + } + + return &src[ret]; +} + +int ctsvc_normalize_number(const char *src, char *dest, int dest_size) +{ + int i; + int len; + int d_pos = 0; + const char *temp_number; + + if ('+' == src[0]) + temp_number = __ctsvc_clean_country_code(src); + else if ('0' == src[0]) + 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 < CTSVC_NORMALIZED_NUMBER_SIZE_MAX) { + 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; + } + } + + return CONTACTS_ERROR_NONE; +} + +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; +} + +#define array_sizeof(a) (sizeof(a) / sizeof(a[0])) + +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; + const char *region; + + region = vconf_get_str(VCONFKEY_REGIONFORMAT); + collator = ucol_open(region, &status); + RETVM_IF(U_FAILURE(status), CONTACTS_ERROR_SYSTEM, + "ucol_open() Failed(%s)", u_errorName(status)); + + if (U_FAILURE(status)){ + CTS_ERR("ucol_setAttribute Failed(%s)", u_errorName(status)); + 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)); + 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)); + 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); + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_collation_str(char *src, char **dest) +{ + int ret; + char temp[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 dest_size) +{ + int type = CTSVC_LANG_OTHERS; + int32_t size; + UErrorCode status = 0; + UChar tmp_result[dest_size*2]; + UChar result[dest_size*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 = ctsvc_check_utf8(src[i]); + if( char_len < 0 ) + { + return char_len; + } + + 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)); + + if (i == 0) + type = ctsvc_check_language(result); + 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; + //dest[j++] = 0x7E; + } + dest[j]='\0'; + + return type; +} + +int ctsvc_normalize_str(const char *src, char *dest, int dest_size) +{ + int ret = CONTACTS_ERROR_NONE; + char temp[dest_size]; + + dest[0] = '\0'; + ret = __ctsvc_remove_special_char(src, temp, dest_size); + RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "__ctsvc_remove_special_char() Failed(%d)", ret); + + ret = __ctsvc_normalize_str(temp, dest, dest_size); + return ret; +} + +int ctsvc_normalize_index(const char *src, char *dest, int dest_size) +{ + int ret = CONTACTS_ERROR_NONE; + char first_str[10] = {0}; + int length = 0; + + dest[0] = '\0'; + + length = ctsvc_check_utf8(src[0]); + RETVM_IF(length <= 0, CONTACTS_ERROR_INTERNAL, "check_utf8 is failed"); + + strncpy(first_str, src, length); + if (length != strlen(first_str)) + return CONTACTS_ERROR_INVALID_PARAMETER; + + ret = __ctsvc_normalize_str(first_str, dest, dest_size); + if (dest[0] != '\0') { + length = ctsvc_check_utf8(dest[0]); + dest[length] = '\0'; + } + return ret; +} + +static int __ctsvc_get_language_index(const char *locale, char ***index, int *count) +{ + ULocaleData* uld; + USet *indexChars; + UErrorCode error = U_ZERO_ERROR; + int32_t itemCount; + int32_t j; + char **temp; + + uld = ulocdata_open(locale, &error); + indexChars = uset_openEmpty(); + + ulocdata_getExemplarSet(uld, indexChars, 0, ULOCDATA_ES_INDEX, &error); + ulocdata_close(uld); + CTS_VERBOSE("locale : %s\n", locale); + + if (U_FAILURE(error)) + return 0; + + if (error == U_USING_DEFAULT_WARNING) + uset_clear(indexChars); + + itemCount = uset_size(indexChars); + CTS_VERBOSE("Size of USet : %d\n", itemCount); + + temp = (char **)calloc(itemCount, sizeof(char*)); + for (j = 0; j < itemCount; j++){ + UChar ch[2] = {0}; + char dest[10]; + int size; + ch[0] = uset_charAt(indexChars, j); + u_strToUTF8(dest, sizeof(dest)-1, &size, ch, -1, &error); + CTS_VERBOSE("[%d] len : %d, %s\n", j+1, size, dest); + temp[j] = strdup(dest); + } + *count = (int)itemCount; + *index = (char **)temp; + uset_clear(indexChars); + return 0; +} + +API int contacts_utils_get_index_characters(char **index_string) +{ + const char *first; + const char *second; + int lang_first; + int lang_second; + char **first_list = NULL; + char **second_list = NULL; + char list[1024] = {0,}; + int i; + int first_len = 0; + int second_len = 0; + + RETV_IF(NULL == index_string, CONTACTS_ERROR_INVALID_PARAMETER); + char temp[5]; + + i = 0; + sprintf(list, "%d", i); + for (i=1;i<10;i++) { + sprintf(temp, ";%d", i); + strcat(list, temp); + } + + strcat(list, ":"); + first = vconf_get_str(VCONFKEY_LANGSET); + lang_first = ctsvc_get_language_type(first); + __ctsvc_get_language_index(first, &first_list, &first_len); + for (i=0;i<first_len;i++) { + strcat(list, first_list[i]); + if (i != (first_len-1)) + strcat(list, ";"); + free(first_list[i]); + } + free(first_list); + + second = vconf_get_str(VCONFKEY_CONTACTS_SVC_SECONDARY_LANGUAGE); + lang_second = ctsvc_get_language_type(second); + if (lang_first != lang_second) + __ctsvc_get_language_index(second, &second_list, &second_len); + + if (0 < second_len) { + strcat(list, ":"); + for (i=0;i<second_len;i++) { + strcat(list, second_list[i]); + if (i != (second_len-1)) + strcat(list, ";"); + free(second_list[i]); + } + } + free(second_list); + + strcat(list, ":"); + strcat(list, "#"); + + *index_string = strdup(list); + return CONTACTS_ERROR_NONE; +} + +////// contacts_normalized_strstr API should be separated from contacts-service ///////////////////////////////////////////////////////////// +#define CTSVC_COMPARE_BETWEEN(left_range, value, right_range) (((left_range) <= (value)) && ((value) <= (right_range))) + +static inline bool __ctsvc_is_choseong(const char *src) +{ + unsigned short tmp; + + tmp = (src[1] << 8) | src[2]; + if (((char)0xE1 == src[0] && CTSVC_COMPARE_BETWEEN(0x8480, tmp, 0x859F)) /* korean -Hangul Jamo*/ + || ((char)0xEA == src[0] && CTSVC_COMPARE_BETWEEN(0xA5A0, tmp, 0xA5BC))) /* korean -Hangul Jamo extended A*/ + { + return true; + } + return false; +} + +static inline bool __ctsvc_is_diacritical(const char *src) +{ + unsigned short tmp; + + if (!src || !*src || !*(src+1)) + return false; + + tmp = (src[0] << 8) | src[1]; + if (CTSVC_COMPARE_BETWEEN(0xCC80, tmp, 0xCCBF) + || CTSVC_COMPARE_BETWEEN(0xCD80, tmp, 0xCDAF)) + { + return true; + } + return false; +} + +static inline bool __ctsvc_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 #sCONTACTS_ERROR_NONE. \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_normalized_str(str1, str2, &len); + if(CONTACTS_ERROR_NONE == 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_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_VERBOSE("haystack = %s, needle = %s", haystack, needle); + + h_len = 1; + n_len = 1; + equal_index = 0; + first_needle_len = ctsvc_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 = ctsvc_check_utf8(haystack[i]); + + if (h_len == 1 && haystack[i] == 0x7E) { //skip seperator + counted = false; + i+=h_len; + continue; + } + + n_len = ctsvc_check_utf8(needle[j]); + if (n_len == 1 && needle[j] == 0x7E) { //skip seperator + j++; + continue; + } + + if (wind == 0 && j && 0 < i) { + if (h_len == first_needle_len && __ctsvc_compare_unicode(&haystack[i], needle, first_needle_len) + && !__ctsvc_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 && __ctsvc_is_diacritical(&haystack[i])) + && (2 != n_len || !__ctsvc_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 && __ctsvc_is_choseong(&needle[j]) && !(__ctsvc_is_choseong(&haystack[i]))) { + if (j < (n_len+1) || !__ctsvc_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 = __ctsvc_compare_unicode(&haystack[i], &needle[j], n_len); + + if (equal) { + if (!counted) { + equal_length += h_len; + counted = true; + } + else if (2 == n_len && __ctsvc_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 && __ctsvc_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 = ctsvc_check_utf8(haystack[i]); + if(h_len == 2 && __ctsvc_is_diacritical(&haystack[i])) + equal_length++; + } + *len = equal_length; + return equal_index; + } + } + + CTS_VERBOSE("NOT match"); + return -1; +} + +/** + * 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_normalize_str(name, normalized_str, sizeof(normalized_str)); + + if(CONTACTS_ERROR_NONE != 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_normalize_str(const char *src, char *dest, const int dest_len) +{ + int ret; + RETV_IF(NULL == dest, CONTACTS_ERROR_INVALID_PARAMETER); + RETVM_IF(dest_len <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "dest_len(%d) is Invalid", dest_len); + + ret = ctsvc_normalize_str(src, dest, dest_len); + RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_normalize_str() Failed(%d)", ret); + + return CONTACTS_ERROR_NONE; +} + diff --git a/common/ctsvc_normalize.h b/common/ctsvc_normalize.h new file mode 100644 index 0000000..60dc3a0 --- /dev/null +++ b/common/ctsvc_normalize.h @@ -0,0 +1,79 @@ +/*
+ * 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__
+
+#define VCONFKEY_CONTACTS_SVC_SECONDARY_LANGUAGE "db/contacts-svc/secondary_lang" // It should be added to vconf-internal-keys
+
+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,
+ CTSVC_LANG_AZERBAIJAN,
+ CTSVC_LANG_ARABIC,
+ CTSVC_LANG_BULGARIAN,
+ CTSVC_LANG_CATALAN,
+ CTSVC_LANG_CZECH,
+ CTSVC_LANG_ESTONIAN,
+ CTSVC_LANG_BASQUE,
+ CTSVC_LANG_FINNISH,
+ CTSVC_LANG_IRISH,
+ CTSVC_LANG_GALICIAN,
+ CTSVC_LANG_HINDI,
+ CTSVC_LANG_CROATIAN,
+ CTSVC_LANG_HUNGARIAN,
+ CTSVC_LANG_ARMENIAN,
+ CTSVC_LANG_ICELANDIC,
+ CTSVC_LANG_GEORGIAN,
+ CTSVC_LANG_KAZAKHSTAN,
+ CTSVC_LANG_LITHUANIAN,
+ CTSVC_LANG_LATVIAN,
+ CTSVC_LANG_MACEDONIA,
+ CTSVC_LANG_NORWAY,
+ CTSVC_LANG_POLISH,
+ CTSVC_LANG_ROMANIA,
+ CTSVC_LANG_SLOVAK,
+ CTSVC_LANG_SLOVENIAN,
+ CTSVC_LANG_SERBIAN,
+ CTSVC_LANG_SWEDISH,
+ CTSVC_LANG_UKRAINE,
+ CTSVC_LANG_OTHERS = 1000,
+};
+
+int ctsvc_clean_number(const char *src, char *dest, int dest_size);
+int ctsvc_normalize_number(const char *src, char *dest, int dest_size);
+int ctsvc_normalize_str(const char *src, char *dest, int dest_size);
+int ctsvc_collation_str(char *src, char **dest);
+int ctsvc_normalize_index(const char *src, char *dest, int dest_size);
+
+#endif /* __TIZEN_SOCIAL_CTSVC_NORMALIZE_H__ */
diff --git a/common/ctsvc_notify.h b/common/ctsvc_notify.h new file mode 100644 index 0000000..40b7db9 --- /dev/null +++ b/common/ctsvc_notify.h @@ -0,0 +1,52 @@ +/*
+ * 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_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_SIMPLE_CONTACT_CHANGED "/opt/usr/data/contacts-svc/.CONTACTS_SVC_SIMPLE_CONTACT_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_MYPROFILE_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_REL_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_PHONELOG_CHANGED "/opt/usr/data/contacts-svc/.CONTACTS_SVC_PLOG_CHANGED"
+#define CTSVC_NOTI_FAVORITE_CHANGED "/opt/usr/data/contacts-svc/.CONTACTS_SVC_FAVOR_CHANGED"
+#define CTSVC_NOTI_SPEEDDIAL_CHANGED "/opt/usr/data/contacts-svc/.CONTACTS_SVC_SPEED_CHANGED"
+#define CTSVC_NOTI_MISSED_CALL_CHANGED "/opt/usr/data/contacts-svc/.CONTACTS_SVC_MISSED_CHANGED"
+
+
+#endif /* __TIZEN_SOCIAL_CTSVC_NOTIFY_H__ */
diff --git a/common/ctsvc_query.c b/common/ctsvc_query.c new file mode 100644 index 0000000..400b7d5 --- /dev/null +++ b/common/ctsvc_query.c @@ -0,0 +1,155 @@ +/* + * 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)); + 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)); + 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) +{ + 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; + + ctsvc_filter_clone(filter, &new_filter); + 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 index 0000000..ead18e9 --- /dev/null +++ b/common/ctsvc_query.h @@ -0,0 +1,29 @@ +/*
+ * 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_QUERY_H__
+#define __TIZEN_SOCIAL_CTSVC_QUERY_H__
+
+#endif /* __TIZEN_SOCIAL_CTSVC_QUERY_H__ */
+
+
diff --git a/common/ctsvc_record.c b/common/ctsvc_record.c new file mode 100644 index 0000000..771b2cb --- /dev/null +++ b/common/ctsvc_record.c @@ -0,0 +1,560 @@ +/* + * 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; +extern ctsvc_record_plugin_cb_s sdn_plugin_cbs; +extern ctsvc_record_plugin_cb_s speeddial_plugin_cbs; +extern ctsvc_record_plugin_cb_s extension_plugin_cbs; +extern ctsvc_record_plugin_cb_s phonelog_plugin_cbs; + +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 ¬e_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; + case CTSVC_RECORD_PHONELOG: + return &phonelog_plugin_cbs; + case CTSVC_RECORD_SPEEDDIAL: + return &speeddial_plugin_cbs; + case CTSVC_RECORD_SDN: + return &sdn_plugin_cbs; + 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() \ + ASSERT_NOT_REACHED("Invalid parameter: Operation restricted."); \ + return CONTACTS_ERROR_INVALID_PARAMETER; + +static inline 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 ( s_record->properties_flags == NULL) + return true; + + return ( s_record->properties_flags[index] & flag) ? true : false; +} + +static inline contacts_property_flag_e __ctsvc_record_get_property_flag(const ctsvc_record_s* s_record, unsigned int index) +{ + return s_record->properties_flags[index] & 0x0000000F; +} + +static inline void __ctsvc_record_set_property_flag(ctsvc_record_s* _record, unsigned int index, contacts_property_flag_e flag) +{ + _record->properties_flags[index] |= flag; +} + +#define __CHECK_READ_ONLY_PROPERTY() \ + if( CTSVC_READ_ONLY_CHECK(property_id, CTSVC_READ_ONLY_PROPERTY) ) \ + { \ + ASSERT_NOT_REACHED("Invalid parameter: Don't try to change read-only property.(0x%0x)", property_id); \ + return CONTACTS_ERROR_INVALID_PARAMETER; \ + } + +#define __CHECK_PROJECTED_PROPERTY() \ + if( __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; + + s_record = (ctsvc_record_s *)record; + + if (value && *value) + str = (char *)value; + else + str = NULL; + + if (s_record->plugin_cbs && s_record->plugin_cbs->set_str) + return s_record->plugin_cbs->set_str(record, property_id, str); + + __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 ) +{ + ctsvc_record_s *s_record; + s_record = (ctsvc_record_s *)record; + + if (s_record->plugin_cbs && s_record->plugin_cbs->set_bool) + return s_record->plugin_cbs->set_bool(record, property_id, value); + + __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(); + + return ctsvc_record_set_int(record, property_id, value); +} + +int ctsvc_record_set_int( contacts_record_h record, unsigned int property_id, int value ) +{ + ctsvc_record_s *s_record; + s_record = (ctsvc_record_s *)record; + + if (s_record->plugin_cbs && s_record->plugin_cbs->set_int) + return s_record->plugin_cbs->set_int(record, property_id, value); + + __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 ) +{ + ctsvc_record_s *s_record; + s_record = (ctsvc_record_s *)record; + + if (s_record->plugin_cbs && s_record->plugin_cbs->set_lli) + return s_record->plugin_cbs->set_lli(record, property_id, value); + + __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 ) +{ + ctsvc_record_s *s_record; + + s_record = (ctsvc_record_s *)record; + + if (s_record->plugin_cbs && s_record->plugin_cbs->set_double) + return s_record->plugin_cbs->set_double(record, property_id, value); + + __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); + 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); + 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, unsigned 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) +{ + 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; + + int i; + for (i = 0; i < projection_count; i++) + { + unsigned int index = projection[i] & 0x00000FFF; + if( index >= property_max_count ) { + ASSERT_NOT_REACHED("Boundary Check failed"); + return CONTACTS_ERROR_INTERNAL; + } + __ctsvc_record_set_property_flag(_record, index, CTSVC_PROPERTY_FLAG_PROJECTION); + } + + return CONTACTS_ERROR_NONE; +} + + diff --git a/common/ctsvc_record.h b/common/ctsvc_record.h new file mode 100644 index 0000000..625b234 --- /dev/null +++ b/common/ctsvc_record.h @@ -0,0 +1,53 @@ +/*
+ * 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;\
+ if ((src)->properties_flags) \
+ {\
+ (dest)->properties_flags = calloc((dest)->property_max_count, sizeof(char));\
+ memcpy((dest)->properties_flags,(src)->properties_flags,sizeof(char)*(dest)->property_max_count);\
+ }\
+} while (0)
+
+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 );
+
+#endif /* __TIZEN_SOCIAL_CTSVC_RECORD_H__ */
diff --git a/common/ctsvc_record_addressbook.c b/common/ctsvc_record_addressbook.c new file mode 100644 index 0000000..a0338fd --- /dev/null +++ b/common/ctsvc_record_addressbook.c @@ -0,0 +1,198 @@ +/*
+ * 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 :
+ ASSERT_NOT_REACHED("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 :
+ ASSERT_NOT_REACHED("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:
+ ASSERT_NOT_REACHED("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;
+/*
+ ASSERT_NOT_REACHED("Invalid parameter : property_id(%d) is a read-only value (addressbook)", property_id);
+ return CONTACTS_ERROR_INVALID_PARAMETER;
+*/
+ case CTSVC_PROPERTY_ADDRESSBOOK_MODE:
+ 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:
+ ASSERT_NOT_REACHED("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 100644 index 0000000..e4cef2d --- /dev/null +++ b/common/ctsvc_record_contact.c @@ -0,0 +1,4331 @@ +/* + * 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_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_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, unsigned 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 ); + + +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 = 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_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)); + 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 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->name); + free(company->department); + free(company->job_title); + free(company->role); + free(company->assistant_name); + 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->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->sync_data1); + free(activity->sync_data2); + free(activity->sync_data3); + free(activity->sync_data4); + 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->label); + free(profile->uid); + free(profile->text); + free(profile->appsvc_operation); + free(profile->data1); + free(profile->data2); + free(profile->data3); + free(profile->data4); + 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); + 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->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)); + contact->name->l_type = CTSVC_RECORD_NAME; + + contact->company = calloc(1, sizeof(ctsvc_list_s)); + contact->company->l_type = CTSVC_RECORD_COMPANY; + + contact->note = calloc(1, sizeof(ctsvc_list_s)); + contact->note->l_type = CTSVC_RECORD_NOTE; + + contact->numbers = calloc(1, sizeof(ctsvc_list_s)); + contact->numbers->l_type = CTSVC_RECORD_NUMBER; + + contact->emails = calloc(1, sizeof(ctsvc_list_s)); + contact->emails->l_type = CTSVC_RECORD_EMAIL; + + contact->grouprelations = calloc(1, sizeof(ctsvc_list_s)); + contact->grouprelations->l_type = CTSVC_RECORD_GROUP_RELATION; + + contact->events = calloc(1, sizeof(ctsvc_list_s)); + contact->events->l_type = CTSVC_RECORD_EVENT; + + contact->messengers = calloc(1, sizeof(ctsvc_list_s)); + contact->messengers->l_type = CTSVC_RECORD_MESSENGER; + + contact->postal_addrs = calloc(1, sizeof(ctsvc_list_s)); + contact->postal_addrs->l_type = CTSVC_RECORD_ADDRESS; + + contact->urls = calloc(1, sizeof(ctsvc_list_s)); + contact->urls->l_type = CTSVC_RECORD_URL; + + contact->nicknames = calloc(1, sizeof(ctsvc_list_s)); + contact->nicknames->l_type = CTSVC_RECORD_NICKNAME; + + contact->profiles = calloc(1, sizeof(ctsvc_list_s)); + contact->profiles->l_type = CTSVC_RECORD_PROFILE; + + contact->relationships = calloc(1, sizeof(ctsvc_list_s)); + contact->relationships->l_type = CTSVC_RECORD_RELATIONSHIP; + + contact->images = calloc(1, sizeof(ctsvc_list_s)); + contact->images->l_type = CTSVC_RECORD_IMAGE; + + contact->extensions = calloc(1, sizeof(ctsvc_list_s)); + 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->sortkey); + free(contact->reverse_sortkey); + free(contact->sync_data1); + free(contact->sync_data2); + free(contact->sync_data3); + free(contact->sync_data4); + + 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; + default: + ASSERT_NOT_REACHED("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; + default: + ASSERT_NOT_REACHED("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: + ASSERT_NOT_REACHED("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: + ASSERT_NOT_REACHED("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: + ASSERT_NOT_REACHED("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: + ASSERT_NOT_REACHED("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: + ASSERT_NOT_REACHED("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: + ASSERT_NOT_REACHED("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_LUNAR_DATE: + *out = event->lunar_date; + break; + default: + ASSERT_NOT_REACHED("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: + ASSERT_NOT_REACHED("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: + ASSERT_NOT_REACHED("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: + ASSERT_NOT_REACHED("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: + ASSERT_NOT_REACHED("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: + ASSERT_NOT_REACHED("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_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: + ASSERT_NOT_REACHED("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_TYPE: + *out = profile->type; + break; + case CTSVC_PROPERTY_PROFILE_ORDER: + *out = profile->order; + break; + default: + ASSERT_NOT_REACHED("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: + ASSERT_NOT_REACHED("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: + ASSERT_NOT_REACHED("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: + ASSERT_NOT_REACHED("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: + contact->person_id = value; + break; + case CTSVC_PROPERTY_CONTACT_CHANGED_TIME: + contact->changed_time = value; + 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_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; + 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_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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (simple contact)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (name)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (company)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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: + 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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (note)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (number)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (email)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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: + 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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (url)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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: + 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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (event)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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: + event->type = value; + break; + case CTSVC_PROPERTY_EVENT_DATE: + event->date = value; + break; + case CTSVC_PROPERTY_EVENT_LUNAR_DATE: + event->lunar_date = 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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (nickname)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (address)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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: + 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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (messenger)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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: + 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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (group relation)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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: + 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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (activity)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (profile)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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_TYPE: + profile->type = 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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (relationship)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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: + 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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (image)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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: + image->is_changed = true; + 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; +/* + CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (extension)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + 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; + 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, unsigned 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; + unsigned 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; + unsigned 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; + 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_SYNC_DATA1: + *out_str = GET_STR(copy, activity->sync_data1); + break; + case CTSVC_PROPERTY_ACTIVITY_SYNC_DATA2: + *out_str = GET_STR(copy, activity->sync_data2); + break; + case CTSVC_PROPERTY_ACTIVITY_SYNC_DATA3: + *out_str = GET_STR(copy, activity->sync_data3); + break; + case CTSVC_PROPERTY_ACTIVITY_SYNC_DATA4: + *out_str = GET_STR(copy, activity->sync_data4); + 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_LABEL: + *out_str = GET_STR(copy, profile->label); + break; + 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_APPSVC_OPERATION: + *out_str = GET_STR(copy, profile->appsvc_operation); + break; + case CTSVC_PROPERTY_PROFILE_DATA1: + *out_str = GET_STR(copy, profile->data1); + break; + case CTSVC_PROPERTY_PROFILE_DATA2: + *out_str = GET_STR(copy, profile->data2); + break; + case CTSVC_PROPERTY_PROFILE_DATA3: + *out_str = GET_STR(copy, profile->data3); + break; + case CTSVC_PROPERTY_PROFILE_DATA4: + *out_str = GET_STR(copy, profile->data4); + 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); + contact->display_name_changed = true; + 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); + contact->ringtone_changed = true; + break; + case CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL: + FREEandSTRDUP(contact->image_thumbnail_path, str); + contact->image_thumbnail_changed = true; + break; + case CTSVC_PROPERTY_CONTACT_UID: + FREEandSTRDUP(contact->uid, str); + contact->uid_changed = true; + break; + case CTSVC_PROPERTY_CONTACT_VIBRATION: + FREEandSTRDUP(contact->vibration, str); + contact->vibration_changed = true; + 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); + contact->display_name_changed = true; + 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); + contact->ringtone_changed = true; + break; + case CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL: + FREEandSTRDUP(contact->image_thumbnail_path, str); + contact->image_thumbnail_changed = true; + break; + case CTSVC_PROPERTY_CONTACT_UID: + FREEandSTRDUP(contact->uid, str); + contact->uid_changed = true; + break; + case CTSVC_PROPERTY_CONTACT_VIBRATION: + FREEandSTRDUP(contact->vibration, str); + contact->vibration_changed = true; + 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; + } + name->is_changed = true; + 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: + 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_SYNC_DATA1: + FREEandSTRDUP(activity->sync_data1, str); + break; + case CTSVC_PROPERTY_ACTIVITY_SYNC_DATA2: + FREEandSTRDUP(activity->sync_data2, str); + break; + case CTSVC_PROPERTY_ACTIVITY_SYNC_DATA3: + FREEandSTRDUP(activity->sync_data3, str); + break; + case CTSVC_PROPERTY_ACTIVITY_SYNC_DATA4: + FREEandSTRDUP(activity->sync_data4, 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_LABEL: + FREEandSTRDUP(profile->label, str); + break; + case CTSVC_PROPERTY_PROFILE_UID: + FREEandSTRDUP(profile->uid, str); + break; + case CTSVC_PROPERTY_PROFILE_TEXT: + FREEandSTRDUP(profile->text, str); + break; + case CTSVC_PROPERTY_PROFILE_APPSVC_OPERATION: + FREEandSTRDUP(profile->appsvc_operation, str); + break; + case CTSVC_PROPERTY_PROFILE_DATA1: + FREEandSTRDUP(profile->data1, str); + break; + case CTSVC_PROPERTY_PROFILE_DATA2: + FREEandSTRDUP(profile->data2, str); + break; + case CTSVC_PROPERTY_PROFILE_DATA3: + FREEandSTRDUP(profile->data3, str); + break; + case CTSVC_PROPERTY_PROFILE_DATA4: + FREEandSTRDUP(profile->data4, 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: + image->is_changed = true; + FREEandSTRDUP(image->label, str); + break; + case CTSVC_PROPERTY_IMAGE_PATH: + image->is_changed = true; + 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_LUNAR: + *value = event->is_lunar; + 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_LUNAR: + event->is_lunar = 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: + 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->display_name_changed = src_data->display_name_changed; + out_data->uid_changed = src_data->uid_changed; + out_data->vibration_changed = src_data->vibration_changed; + out_data->image_thumbnail_changed = src_data->image_thumbnail_changed; + out_data->ringtone_changed = src_data->ringtone_changed; + + 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->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->is_restricted = src_data->is_restricted; + + 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->image_thumbnail_path = SAFE_STRDUP(src_data->image_thumbnail_path); + out_data->sortkey = SAFE_STRDUP(src_data->sortkey); + out_data->reverse_sortkey = SAFE_STRDUP(src_data->reverse_sortkey); + out_data->sync_data1 = SAFE_STRDUP(src_data->sync_data1); + out_data->sync_data2 = SAFE_STRDUP(src_data->sync_data2); + out_data->sync_data3 = SAFE_STRDUP(src_data->sync_data3); + out_data->sync_data4 = SAFE_STRDUP(src_data->sync_data4); + + 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->sync_data1 = SAFE_STRDUP(src_data->sync_data1); + out_data->sync_data2 = SAFE_STRDUP(src_data->sync_data2); + out_data->sync_data3 = SAFE_STRDUP(src_data->sync_data3); + out_data->sync_data4 = SAFE_STRDUP(src_data->sync_data4); + + 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->logo_changed= src_data->logo_changed; + out_data->contact_id = src_data->contact_id; + 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); + 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; + + 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->is_changed = src_data->is_changed; + 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->type = src_data->type; + out_data->order = src_data->order; + out_data->label = SAFE_STRDUP(src_data->label); + out_data->uid = SAFE_STRDUP(src_data->uid); + out_data->text = SAFE_STRDUP(src_data->text); + out_data->appsvc_operation = SAFE_STRDUP(src_data->appsvc_operation); + out_data->data1 = SAFE_STRDUP(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); + + 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_changed = src_data->is_changed; + 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->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->uid_changed = src_data->uid_changed; + out_data->vibration_changed = src_data->vibration_changed; + out_data->image_thumbnail_changed = src_data->image_thumbnail_changed; + out_data->ringtone_changed = src_data->ringtone_changed; + + 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->is_restricted = src_data->is_restricted; + + 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->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 index 0000000..7e3bcef --- /dev/null +++ b/common/ctsvc_record_group.c @@ -0,0 +1,254 @@ +/*
+ * 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->image_thumbnail_path);
+ free(group->system_id);
+ 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->image_thumbnail_changed = src_data->image_thumbnail_changed;
+ out_data->name = SAFE_STRDUP(src_data->name);
+ out_data->system_id = SAFE_STRDUP(src_data->system_id);
+ out_data->vibration = SAFE_STRDUP(src_data->vibration);
+ 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:
+ ASSERT_NOT_REACHED("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_SYSTEM_ID:
+ *out_str = GET_STR(copy, group->system_id);
+ break;
+ default :
+ ASSERT_NOT_REACHED("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;
+/*
+ ASSERT_NOT_REACHED("Invalid parameter : property_id(%d) is a read-only value (group)", property_id);
+ return CONTACTS_ERROR_INVALID_PARAMETER;
+*/
+ 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:
+ ASSERT_NOT_REACHED("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);
+ group->image_thumbnail_changed = true;
+ break;
+ case CTSVC_PROPERTY_GROUP_VIBRATION:
+ FREEandSTRDUP(group->vibration, str);
+ break;
+ case CTSVC_PROPERTY_GROUP_SYSTEM_ID:
+ FREEandSTRDUP(group->system_id, str);
+ break;
+ default :
+ ASSERT_NOT_REACHED("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:
+ ASSERT_NOT_REACHED("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_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:
+ group->is_read_only = value;
+ break;
+ default:
+ ASSERT_NOT_REACHED("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 index 0000000..26eee2f --- /dev/null +++ b/common/ctsvc_record_my_profile.c @@ -0,0 +1,595 @@ +/* + * 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, unsigned 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)); + my_profile->name->l_type = CTSVC_RECORD_NAME; + + my_profile->company = calloc(1, sizeof(ctsvc_list_s)); + my_profile->company->l_type = CTSVC_RECORD_COMPANY; + + my_profile->note = calloc(1, sizeof(ctsvc_list_s)); + my_profile->note->l_type = CTSVC_RECORD_NOTE; + + my_profile->numbers = calloc(1, sizeof(ctsvc_list_s)); + my_profile->numbers->l_type = CTSVC_RECORD_NUMBER; + + my_profile->emails = calloc(1, sizeof(ctsvc_list_s)); + my_profile->emails->l_type = CTSVC_RECORD_EMAIL; + + my_profile->events = calloc(1, sizeof(ctsvc_list_s)); + my_profile->events->l_type = CTSVC_RECORD_EVENT; + + my_profile->messengers = calloc(1, sizeof(ctsvc_list_s)); + my_profile->messengers->l_type = CTSVC_RECORD_MESSENGER; + + my_profile->postal_addrs = calloc(1, sizeof(ctsvc_list_s)); + my_profile->postal_addrs->l_type = CTSVC_RECORD_ADDRESS; + + my_profile->urls = calloc(1, sizeof(ctsvc_list_s)); + my_profile->urls->l_type = CTSVC_RECORD_URL; + + my_profile->nicknames = calloc(1, sizeof(ctsvc_list_s)); + my_profile->nicknames->l_type = CTSVC_RECORD_NICKNAME; + + my_profile->profiles = calloc(1, sizeof(ctsvc_list_s)); + my_profile->profiles->l_type = CTSVC_RECORD_PROFILE; + + my_profile->relationships = calloc(1, sizeof(ctsvc_list_s)); + my_profile->relationships->l_type = CTSVC_RECORD_RELATIONSHIP; + + my_profile->images = calloc(1, sizeof(ctsvc_list_s)); + my_profile->images->l_type = CTSVC_RECORD_IMAGE; + + my_profile->extensions = calloc(1, sizeof(ctsvc_list_s)); + 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->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_contact_s *contact = (ctsvc_contact_s *)record; + + switch(property_id) { + case CTSVC_PROPERTY_MY_PROFILE_ID: + *out = contact->id; + break; + case CTSVC_PROPERTY_MY_PROFILE_ADDRESSBOOK_ID: + *out = contact->addressbook_id; + break; + case CTSVC_PROPERTY_MY_PROFILE_CHANGED_TIME: + *out = contact->changed_time; + break; + default: + ASSERT_NOT_REACHED("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_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_contact_s *contact = (ctsvc_contact_s*)record; + switch(property_id) { + case CTSVC_PROPERTY_MY_PROFILE_DISPLAY_NAME: + *out_str = GET_STR(copy, contact->display_name); + break; + case CTSVC_PROPERTY_MY_PROFILE_IMAGE_THUMBNAIL: + *out_str = GET_STR(copy, contact->image_thumbnail_path); + break; + case CTSVC_PROPERTY_MY_PROFILE_UID: + *out_str = GET_STR(copy, contact->uid); + 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_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, unsigned 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; + unsigned 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; + unsigned 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_contact_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->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 index 0000000..86c18fa --- /dev/null +++ b/common/ctsvc_record_person.c @@ -0,0 +1,306 @@ +/* + * 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->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->name_contact_id_changed = src_data->name_contact_id_changed; + out_data->image_thumbnail_changed = src_data->image_thumbnail_changed; + out_data->ringtone_changed = src_data->ringtone_changed; + out_data->vibration_changed = src_data->vibration_changed; + out_data->is_favorite_changed = src_data->is_favorite_changed; + 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->account_id1 = src_data->account_id1; + out_data->account_id2 = src_data->account_id2; + out_data->account_id3 = src_data->account_id3; + 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->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; + case CTSVC_PROPERTY_PERSON_ACCOUNT_ID1: + *out = person->account_id1; + break; + case CTSVC_PROPERTY_PERSON_ACCOUNT_ID2: + *out = person->account_id2; + break; + case CTSVC_PROPERTY_PERSON_ACCOUNT_ID3: + *out = person->account_id3; + break; + default: + ASSERT_NOT_REACHED("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_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 : + ASSERT_NOT_REACHED("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: + ASSERT_NOT_REACHED("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; + person->name_contact_id_changed = true; + break; + case CTSVC_PROPERTY_PERSON_ID: + person->person_id = value; + break; + case CTSVC_PROPERTY_PERSON_LINK_COUNT: + person->link_count = value; + break; + case CTSVC_PROPERTY_PERSON_ACCOUNT_ID1: + person->account_id1 = value; + break; + case CTSVC_PROPERTY_PERSON_ACCOUNT_ID2: + person->account_id2 = value; + break; + case CTSVC_PROPERTY_PERSON_ACCOUNT_ID3: + person->account_id3 = value; + break; +/* + ASSERT_NOT_REACHED("The field(0x%0x) is a read-only value (person)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + default: + ASSERT_NOT_REACHED("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; +/* + ASSERT_NOT_REACHED("The field(%d) is a read-only value (contact)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + case CTSVC_PROPERTY_PERSON_RINGTONE: + FREEandSTRDUP(person->ringtone_path, str); + person->ringtone_changed = true; + break; + case CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL: + FREEandSTRDUP(person->image_thumbnail_path, str); + person->image_thumbnail_changed = true; + break; + case CTSVC_PROPERTY_PERSON_VIBRATION: + FREEandSTRDUP(person->vibration, str); + person->vibration_changed = true; + break; + default : + ASSERT_NOT_REACHED("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; + person->is_favorite_changed = true; + } + break; + default: + ASSERT_NOT_REACHED("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 index 0000000..6ee4f0e --- /dev/null +++ b/common/ctsvc_record_phonelog.c @@ -0,0 +1,225 @@ +/*
+ * 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->display_name);
+ free(phonelog->image_thumbnail_path);
+ 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->display_name = SAFE_STRDUP(src_data->display_name);
+ 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_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;
+ default:
+ ASSERT_NOT_REACHED("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 :
+ ASSERT_NOT_REACHED("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;
+/*
+ CTS_ERR("Invalid parameter : property_id(%d) is a read-only value (phonelog)", property_id);
+ return CONTACTS_ERROR_INVALID_PARAMETER;
+*/
+ 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:
+ phonelog->log_type = value;
+ 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;
+ default:
+ ASSERT_NOT_REACHED("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:
+ FREEandSTRDUP(phonelog->address, str);
+ break;
+ case CTSVC_PROPERTY_PHONELOG_EXTRA_DATA2:
+ FREEandSTRDUP(phonelog->extra_data2, str);
+ break;
+ default :
+ ASSERT_NOT_REACHED("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 index 0000000..7675d63 --- /dev/null +++ b/common/ctsvc_record_result.c @@ -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_record.h"
+#include "ctsvc_view.h"
+
+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));
+ 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 {
+ ASSERT_NOT_REACHED("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 {
+ ASSERT_NOT_REACHED("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) {
+ data->value.i = value;
+ return CONTACTS_ERROR_NONE;
+ }
+ else {
+ ASSERT_NOT_REACHED("use another get_type API, (type : %d)", data->type);
+ return CONTACTS_ERROR_INVALID_PARAMETER;
+ }
+ }
+ }
+
+ data = calloc(1, sizeof(ctsvc_result_value_s));
+ data->property_id = property_id;
+ data->type = CTSVC_VIEW_DATA_TYPE_INT;
+ 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 {
+ ASSERT_NOT_REACHED("use another get_type API, (type : %d)", data->type);
+ return CONTACTS_ERROR_INVALID_PARAMETER;
+ }
+ }
+ }
+
+ data = calloc(1, sizeof(ctsvc_result_value_s));
+ 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 {
+ ASSERT_NOT_REACHED("use another get_type API, (type : %d)", data->type);
+ return CONTACTS_ERROR_INVALID_PARAMETER;
+ }
+ }
+ }
+
+ data = calloc(1, sizeof(ctsvc_result_value_s));
+ 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 {
+ ASSERT_NOT_REACHED("use another get_type API, (type : %d)", data->type);
+ return CONTACTS_ERROR_INVALID_PARAMETER;
+ }
+ }
+ }
+
+ data = calloc(1, sizeof(ctsvc_result_value_s));
+ 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;
+
+ // 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) {
+ full_path = calloc(1, strlen(CTS_IMG_FULL_LOCATION) + strlen(str) + 2);
+ sprintf(full_path, "%s/%s", CTS_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 {
+ ASSERT_NOT_REACHED("use another get_type API, (type : %d)", data->type);
+ return CONTACTS_ERROR_INVALID_PARAMETER;
+ }
+ }
+ }
+
+ data = calloc(1, sizeof(ctsvc_result_value_s));
+ 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) {
+ full_path = calloc(1, strlen(CTS_IMG_FULL_LOCATION) + strlen(str) + 2);
+ sprintf(full_path, "%s/%s", CTS_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 {
+ ASSERT_NOT_REACHED("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 {
+ ASSERT_NOT_REACHED("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 {
+ ASSERT_NOT_REACHED("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 index 0000000..44b18ef --- /dev/null +++ b/common/ctsvc_record_sdn.c @@ -0,0 +1,185 @@ +/* + * 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); + + 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; + default: + ASSERT_NOT_REACHED("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 : + ASSERT_NOT_REACHED("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; +/* + ASSERT_NOT_REACHED("The field(%d) is a read-only value (sdn)", property_id); + return CONTACTS_ERROR_INVALID_PARAMETER; +*/ + default: + ASSERT_NOT_REACHED("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 : + ASSERT_NOT_REACHED("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 index 0000000..fc5e2f6 --- /dev/null +++ b/common/ctsvc_record_speeddial.c @@ -0,0 +1,223 @@ +/*
+ * 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->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:
+ ASSERT_NOT_REACHED("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 :
+ ASSERT_NOT_REACHED("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;
+/*
+ CTS_ERR("The field(%d) is a read-only value (speeddial)", property_id);
+ return CONTACTS_ERROR_INVALID_PARAMETER;
+*/
+ case CTSVC_PROPERTY_SPEEDDIAL_DIAL_NUMBER:
+ speeddial->dial_number = value;
+ break;
+ case CTSVC_PROPERTY_SPEEDDIAL_NUMBER_ID:
+ speeddial->number_id = value;
+ break;
+ default:
+ ASSERT_NOT_REACHED("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 :
+ ASSERT_NOT_REACHED("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 100644 index 0000000..07442a5 --- /dev/null +++ b/common/ctsvc_record_updated_info.c @@ -0,0 +1,144 @@ +/* + * 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); + +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 = NULL, + .get_lli = NULL, + .get_double = NULL, + .set_str = NULL, + .set_int = __ctsvc_updated_info_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_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; + default: + ASSERT_NOT_REACHED("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: + updated_info->changed_type = value; + break; + case CTSVC_PROPERTY_UPDATE_INFO_VERSION: + updated_info->changed_ver = value; + break; + default: + ASSERT_NOT_REACHED("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_setting.c b/common/ctsvc_setting.c new file mode 100644 index 0000000..b645ad8 --- /dev/null +++ b/common/ctsvc_setting.c @@ -0,0 +1,156 @@ +/* + * 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_setting.h" +#include "ctsvc_normalize.h" + +static int name_display_order = -1; +static int default_lang = -1; +static int secondary_lang = -1; + +static const char *CTSVC_VCONF_DISPLAY_ORDER = VCONFKEY_CONTACTS_SVC_NAME_DISPLAY_ORDER; + +const char* ctsvc_get_default_language_vconfkey(void) +{ + return "file/private/contacts-service/default_lang"; +} + +const char* ctsvc_get_secondary_language_vconfkey(void) +{ + return "file/private/contacts-service/secondary_lang"; +} + +API int contacts_setting_get_name_display_order(contacts_name_display_order_e *order) +{ + int ret; + if (name_display_order < 0) + { + ret = vconf_get_int(VCONFKEY_CONTACTS_SVC_NAME_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(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); + + ret = vconf_set_int(VCONFKEY_CONTACTS_SVC_NAME_DISPLAY_ORDER, order); + RETVM_IF(ret<0, CONTACTS_ERROR_SYSTEM, "System : vconf_set_int(%s) Failed(%d)", VCONFKEY_CONTACTS_SVC_NAME_DISPLAY_ORDER, ret); + + name_display_order = order; + + return CONTACTS_ERROR_NONE; +} + +static void ctsvc_vconf_diplay_order_cb(keynode_t *key, void *data) +{ + name_display_order = vconf_keynode_get_int(key); +} + +static void ctsvc_vconf_language_cb(keynode_t *key, void *data) +{ + default_lang = vconf_keynode_get_int(key); +} + +static void ctsvc_vconf_secondary_language_cb(keynode_t *key, void *data) +{ + secondary_lang = vconf_keynode_get_int(key); +} + +int ctsvc_register_vconf(void) +{ + int ret; + + 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_get_int(ctsvc_get_default_language_vconfkey(), &default_lang); + WARN_IF(ret < 0, "vconf_get_int() Failed(%d)", ret); + + ret = vconf_get_int(ctsvc_get_secondary_language_vconfkey(), &secondary_lang); + WARN_IF(ret < 0, "vconf_get_int() Failed(%d)", ret); + + ret = vconf_notify_key_changed(CTSVC_VCONF_DISPLAY_ORDER, + ctsvc_vconf_diplay_order_cb, NULL); + RETVM_IF(ret<0, CONTACTS_ERROR_SYSTEM, "vconf_notify_key_changed(%s) Failed(%d)", + CTSVC_VCONF_DISPLAY_ORDER, ret); + ret = vconf_notify_key_changed(ctsvc_get_default_language_vconfkey(), + ctsvc_vconf_language_cb, NULL); + RETVM_IF(ret<0, CONTACTS_ERROR_SYSTEM, "vconf_notify_key_changed(%s) Failed(%d)", + ctsvc_get_default_language_vconfkey(), ret); + + ret = vconf_notify_key_changed(ctsvc_get_secondary_language_vconfkey(), + ctsvc_vconf_secondary_language_cb, NULL); + RETVM_IF(ret<0, CONTACTS_ERROR_SYSTEM, "vconf_notify_key_changed(%s) Failed(%d)", + ctsvc_get_secondary_language_vconfkey(), ret); + + return CONTACTS_ERROR_NONE; +} + +void ctsvc_deregister_vconf(void) +{ + int ret; + + ret = vconf_ignore_key_changed(CTSVC_VCONF_DISPLAY_ORDER, ctsvc_vconf_diplay_order_cb); + RETM_IF(ret<0,"vconf_ignore_key_changed(%s) Failed(%d)",CTSVC_VCONF_DISPLAY_ORDER,ret); + ret = vconf_ignore_key_changed(ctsvc_get_default_language_vconfkey(), ctsvc_vconf_language_cb); + RETM_IF(ret<0,"vconf_ignore_key_changed(%s) Failed(%d)", ctsvc_get_default_language_vconfkey(),ret); + ret = vconf_ignore_key_changed(ctsvc_get_secondary_language_vconfkey(), ctsvc_vconf_secondary_language_cb); + RETM_IF(ret<0,"vconf_ignore_key_changed(%s) Failed(%d)", ctsvc_get_secondary_language_vconfkey(),ret); +} + +int ctsvc_get_default_language(void) +{ + if (default_lang < 0) { + int ret; + ret = vconf_get_int(ctsvc_get_default_language_vconfkey(), &default_lang); + WARN_IF(ret < 0, "vconf_get_int() Failed(%d)", ret); + } + return default_lang; +} + +int ctsvc_get_secondary_language(void) +{ + if (secondary_lang < 0) { + int ret; + ret = vconf_get_int(ctsvc_get_secondary_language_vconfkey(), &secondary_lang); + WARN_IF(ret < 0, "vconf_get_int() Failed(%d)", ret); + } + return secondary_lang; +} + diff --git a/common/ctsvc_setting.h b/common/ctsvc_setting.h new file mode 100644 index 0000000..424d4e6 --- /dev/null +++ b/common/ctsvc_setting.h @@ -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 __TIZEN_SOCIAL_CTSVC_SETTING_H__
+#define __TIZEN_SOCIAL_CTSVC_SETTING_H__
+ +int ctsvc_register_vconf(void);
+void ctsvc_deregister_vconf(void);
+int ctsvc_get_default_language(void);
+int ctsvc_get_secondary_language(void);
+const char *ctsvc_get_default_language_vconfkey(void);
+const char *ctsvc_get_secondary_language_vconfkey(void);
+
+#endif /* __TIZEN_SOCIAL_CTSVC_SETTING_H__ */
+
diff --git a/common/ctsvc_sim.c b/common/ctsvc_sim.c new file mode 100644 index 0000000..f517a7d --- /dev/null +++ b/common/ctsvc_sim.c @@ -0,0 +1,51 @@ +/* + * 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() +{ + int ret; + + ctsvc_mutex_lock(CTS_MUTEX_SOCKET_FD); + ret = ctsvc_request_sim_import(); + ctsvc_mutex_unlock(CTS_MUTEX_SOCKET_FD); + + return ret; +} + +API int contacts_sim_get_initialization_status(bool *completed) +{ + int ret; + + ctsvc_mutex_lock(CTS_MUTEX_SOCKET_FD); + ret = ctsvc_request_sim_get_initialization_status(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 index 0000000..72312e3 --- /dev/null +++ b/common/ctsvc_socket.c @@ -0,0 +1,196 @@ +/* + * 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 cts_csockfd = -1; + +int ctsvc_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", CTSVC_SOCKET_PATH); + + cts_csockfd = socket(PF_UNIX, SOCK_STREAM, 0); + RETVM_IF(-1 == cts_csockfd, CONTACTS_ERROR_IPC, + "socket() Failed(errno = %d)", errno); + + ret = connect(cts_csockfd, (struct sockaddr *)&caddr, sizeof(caddr)); + if (-1 == ret) { + CTS_ERR("connect() Failed(errno = %d)", errno); + close(cts_csockfd); + cts_csockfd = -1; + return CONTACTS_ERROR_IPC; + } + + return CONTACTS_ERROR_NONE; +} + +void ctsvc_socket_final(void) +{ + close(cts_csockfd); + cts_csockfd = -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; +} + +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(void) +{ + int i, ret; + ctsvc_socket_msg_s msg = {0}; + + RETVM_IF(-1 == cts_csockfd, CONTACTS_ERROR_IPC, "socket is not connected"); + + msg.type = CTSVC_SOCKET_MSG_TYPE_REQUEST_IMPORT_SIM; + ret = __ctsvc_safe_write(cts_csockfd, (char *)&msg, sizeof(msg)); + RETVM_IF(-1 == ret, CONTACTS_ERROR_IPC, "__ctsvc_safe_write() Failed(errno = %d)", errno); + + ret = __ctsvc_socket_handle_return(cts_csockfd, &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(cts_csockfd, msg.attach_sizes[i]); + + return msg.val; +} + +int ctsvc_request_sim_get_initialization_status(bool *completed) +{ + int ret =0; + ctsvc_socket_msg_s msg = {0}; + char dest[CTSVC_SOCKET_MSG_SIZE] = {0}; + + RETVM_IF(-1 == cts_csockfd, CONTACTS_ERROR_IPC, "socket is not connected"); + + msg.type = CTSVC_SOCKET_MSG_TYPE_REQUEST_SIM_INIT_COMPLETE; + ret = __ctsvc_safe_write(cts_csockfd, (char *)&msg, sizeof(msg)); + RETVM_IF(-1 == ret, CONTACTS_ERROR_IPC, "__ctsvc_safe_write() Failed(errno = %d)", errno); + + ret = __ctsvc_socket_handle_return(cts_csockfd, &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(cts_csockfd, 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; +} diff --git a/common/ctsvc_socket.h b/common/ctsvc_socket.h new file mode 100644 index 0000000..98d4105 --- /dev/null +++ b/common/ctsvc_socket.h @@ -0,0 +1,56 @@ +/*
+ * 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__
+
+#define CTSVC_SOCKET_PATH "/opt/usr/data/contacts-svc/.contacts-svc.sock" +#define CTSVC_SOCKET_MSG_SIZE 1024 +#define CTSVC_SIM_MAX_TEXT_LEN 40 +#define CTSVC_SIM_NUM_EMAIL_MAX_COUNT 4 + +// 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;
+
+int ctsvc_request_sim_import(void);
+int ctsvc_request_sim_get_initialization_status(bool* completed); +
+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 index 0000000..381300d --- /dev/null +++ b/common/ctsvc_struct.h @@ -0,0 +1,634 @@ +/* + * 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 +#define CTSVC_NUMBER_MAX_LEN 512 +#define CTS_IMG_FULL_LOCATION "/opt/usr/data/contacts-svc/img" + +#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 +}; + +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 enum { + TYPE_BOOL, + TYPE_INT, + TYPE_LLI, + TYPE_STR, + TYPE_DOUBLE, + TYPE_PTR, +}value_type_e; + +typedef enum { + PROPERTY_NONE, + PROPERTY_FILTER, + PROPERTY_PROJECTION, + PROPERTY_ALL, +}property_type_e; +*/ + +typedef struct{ + unsigned int property_id; + int type; + 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, unsigned 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; + bool deleted; + const ctsvc_record_plugin_cb_s *plugin_cbs; + const char* view_uri; + unsigned int property_max_count; + unsigned char* properties_flags; +}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; + bool image_thumbnail_changed; + int id; + int addressbook_id; + bool is_read_only; + char *name; + char *system_id; + char *ringtone_path; + char *vibration; + char *image_thumbnail_path; +}ctsvc_group_s; + +typedef struct { + ctsvc_record_s base; + bool name_contact_id_changed; + bool image_thumbnail_changed; + bool ringtone_changed; + bool vibration_changed; + bool is_favorite_changed; + 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 *status; + int link_count; + int account_id1; + int account_id2; + int account_id3; + char *addressbook_ids; +}ctsvc_person_s; + +typedef struct { + ctsvc_record_s base; + bool display_name_changed; + bool uid_changed; + bool image_thumbnail_changed; + bool ringtone_changed; + bool vibration_changed; + bool is_restricted; + 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 *display_name; + char *uid; + int display_source_type; +}ctsvc_simple_contact_s; + +typedef struct { + ctsvc_record_s base; + bool is_default; + bool is_changed; + 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 *lookup; // internally used +}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_lunar; + int lunar_date; +}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; + int type; + char *label; + char *uid; + char *text; + int order; + char *appsvc_operation; + char *data1; + char *data2; + char *data3; + char *data4; +}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_changed; + 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 *sync_data1; + char *sync_data2; + char *sync_data3; + char *sync_data4; +}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; + bool logo_changed; + int id; + int contact_id; + bool is_default; + 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*/ + char *display_name; // new + char *image_thumbnail_path; // new +}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 display_name_changed; + bool uid_changed; + bool image_thumbnail_changed; + bool ringtone_changed; + bool vibration_changed; + bool is_restricted; + bool is_favorite; + int id; + int person_id; + int changed_time; + int addressbook_id; + bool has_phonenumber; + bool has_email; + char *display_name; + char *reverse_display_name; + int display_source_type; + int display_name_language; + char *sortkey; + char *reverse_sortkey; + char *uid; + char *image_thumbnail_path; + char *ringtone_path; + char *vibration; + char *sync_data1; + char *sync_data2; + char *sync_data3; + char *sync_data4; + 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 *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; +}ctsvc_sdn_s; + +typedef struct { + ctsvc_record_s base; + int changed_type; + int id; + int changed_ver; + int addressbook_id; +}ctsvc_updated_info_s; + +typedef struct { + ctsvc_record_s base; + 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 index 0000000..2c19455 --- /dev/null +++ b/common/ctsvc_vcard.c @@ -0,0 +1,2793 @@ +/* + * 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 <iconv.h> + +#include "contacts.h" +#include "ctsvc_internal.h" +#include "ctsvc_list.h" +#include "ctsvc_vcard.h" + +#define SMART_STRDUP(src) (src && *src)?strdup(src):NULL +#define CTSVC_VCARD_FILE_MAX_SIZE 1024*1024 +#define CTSVC_VCARD_PHOTO_MAX_SIZE 1024*100 +#define CTSVC_VCARD_IMAGE_LOCATION "/opt/usr/data/contacts-svc/img/vcard" + +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_LAST_NAME, + CTSVC_VCARD_VALUE_NICKNAME, + CTSVC_VCARD_VALUE_PHOTO, + CTSVC_VCARD_VALUE_BDAY, + CTSVC_VCARD_VALUE_ADR, + CTSVC_VCARD_VALUE_LABEL, + 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_NOTE, + CTSVC_VCARD_VALUE_REV, + CTSVC_VCARD_VALUE_UID, + CTSVC_VCARD_VALUE_URL, + CTSVC_VCARD_VALUE_X_ANNIVERSARY, + 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, + CTSVC_VCARD_VALUE_X_QQ, + CTSVC_VCARD_VALUE_X_GOOGLE_TALK, + CTSVC_VCARD_VALUE_END, + CTSVC_VCARD_VALUE_MAX +}; + +enum{ + CTSVC_VCARD_IMG_NONE, + CTSVC_VCARD_IMG_JPEG, + CTSVC_VCARD_IMG_PNG, + CTSVC_VCARD_IMG_GIF, + CTSVC_VCARD_IMG_TIFF, +}; + +static int __ctsvc_tmp_image_id = 0; +static int __ctsvc_tmp_logo_id = 0; + +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_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_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_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_SOUND] = "SOUND"; /* 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_ANNIVERSARY] = "X-ANNIVERSARY"; + 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] = "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_CHILDREN] = "X-CHILDREN"; + content_name[CTSVC_VCARD_VALUE_END] = "END"; + } +}; + +#define CTS_VCARD_FOLDING_LIMIT 75 + +static inline int __ctsvc_vcard_add_folding(char *src) +{ + int len, result_len; + char result[CTSVC_VCARD_FILE_MAX_SIZE] = {0}; + 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, CONTACTS_ERROR_INVALID_PARAMETER, + "src is too long\n(%s)", src); + } + *r = '\0'; + + memcpy(src, result, result_len+1); + return CONTACTS_ERROR_NONE; +} + +static inline int __ctsvc_vcard_append_name(ctsvc_list_s *names, + char *dest, int dest_size) +{ + int ret_len; + char display[1024] = {0}; + GList *cursor = names->records; + ctsvc_name_s *name; + + RETV_IF(NULL == cursor, 0); + + name = (ctsvc_name_s *)cursor->data; + + ret_len = snprintf(dest, dest_size, "%s", content_name[CTSVC_VCARD_VALUE_N]); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ":%s", + SAFE_STR(name->last)); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", + SAFE_STR(name->first)); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", + SAFE_STR(name->addition)); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", + SAFE_STR(name->prefix)); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s%s", + SAFE_STR(name->suffix), CTSVC_CRLF); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + + 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 { +#if 0 // TODO : implement language set + int lang; + if (CTSVC_LANG_DEFAULT == name->language_type) + lang = ctsvc_get_default_language(); + else + lang = name->language_type; + + if (CTSVC_LANG_ENGLISH == lang) + snprintf(display, sizeof(display), "%s, %s", name->last, name->first); + else + snprintf(display, sizeof(display), "%s %s", name->last, name->first); +#endif + } + } + 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[CTSVC_VCARD_VALUE_FN], + display, CTSVC_CRLF); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + + if (name->phonetic_first) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s", + content_name[CTSVC_VCARD_VALUE_PHONETIC_FIRST_NAME], name->phonetic_first, CTSVC_CRLF); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + + if (name->phonetic_last) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s", + content_name[CTSVC_VCARD_VALUE_PHONETIC_LAST_NAME], name->phonetic_last, CTSVC_CRLF); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + + return ret_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_JPEG: + case CTSVC_VCARD_IMG_NONE: + default: + return "jpeg"; + } +} + +static inline int __ctsvc_vcard_get_image_type(char *val) +{ + char *temp, *result; + + 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; + + 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_JPEG: + default: + return "JPEG"; + } +} + +static inline int __ctsvc_vcard_put_company_logo(const char *path, char *dest, int dest_size) +{ + int ret, fd, type; + gsize read_len; + char *suffix; + gchar *buf; + guchar image[CTSVC_VCARD_PHOTO_MAX_SIZE] = {0}; + + suffix = strrchr(path, '.'); + RETVM_IF(NULL == suffix, 0, "Image Type(%s) is invalid", path); + + type = __ctsvc_vcard_get_image_type(suffix); + RETVM_IF(CTSVC_VCARD_IMG_NONE == type, 0, "Invalid parameter : Image Type(%s) is invalid", path); + + fd = open(path, O_RDONLY); + RETVM_IF(fd < 0, CONTACTS_ERROR_SYSTEM, "System : 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, CONTACTS_ERROR_SYSTEM, "System : 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[CTSVC_VCARD_VALUE_LOGO], + __ctsvc_get_image_type_str(type), buf, CTSVC_CRLF, CTSVC_CRLF); + g_free(buf); + } + + return ret; +} + +static inline int __ctsvc_vcard_append_company(ctsvc_list_s *company_list, + char *dest, int dest_size) +{ + int ret_len = 0; + GList *cursor = company_list->records; + ctsvc_company_s *company; + RETV_IF(NULL == cursor, 0); + + company = (ctsvc_company_s *)cursor->data; + + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s", + content_name[CTSVC_VCARD_VALUE_ORG], + SAFE_STR(company->name)); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + + if (company->department) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", + company->department); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s", CTSVC_CRLF); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + + if (company->job_title) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s", + content_name[CTSVC_VCARD_VALUE_TITLE], + company->job_title, CTSVC_CRLF); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + + if (company->role) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s", + content_name[CTSVC_VCARD_VALUE_ROLE], + company->role, CTSVC_CRLF); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + + if (company->logo) { + ret_len += __ctsvc_vcard_put_company_logo(company->logo, dest+ret_len, dest_size-ret_len); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + + return ret_len; +} + +static inline int __ctsvc_vcard_append_note(ctsvc_list_s *note_list, + char *dest, int dest_size) +{ + int ret_len = 0; + GList *cursor = note_list->records; + ctsvc_note_s *note; + + RETV_IF(NULL == cursor, 0); + + note = (ctsvc_note_s *)cursor->data; + + if (note->note) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s", + content_name[CTSVC_VCARD_VALUE_NOTE], + SAFE_STR(note->note), CTSVC_CRLF); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + + return ret_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 *dest, int dest_size) +{ + int ret_len = 0; + + if (type & CONTACTS_ADDRESS_TYPE_DOM) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "DOM"); + if (type & CONTACTS_ADDRESS_TYPE_INTL) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "INTL"); + if (type & CONTACTS_ADDRESS_TYPE_HOME) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "HOME"); + if (type & CONTACTS_ADDRESS_TYPE_WORK) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "WORK"); + if (type & CONTACTS_ADDRESS_TYPE_POSTAL) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "POSTAL"); + if (type & CONTACTS_ADDRESS_TYPE_PARCEL) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "PARCEL"); + if (type & CONTACTS_ADDRESS_TYPE_CUSTOM) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=X-%s", label); + + return ret_len; +} + +static inline int __ctsvc_vcard_append_postals(ctsvc_list_s *address_list, + char *dest, int dest_size) +{ + int ret_len = 0; + GList *cursor; + ctsvc_address_s *address; + + for (cursor = address_list->records;cursor;cursor=cursor->next) { + address = cursor->data; + if (address) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s", + content_name[CTSVC_VCARD_VALUE_ADR]); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + + ret_len += __ctsvc_vcard_put_postal_type(address->type, address->label, dest+ret_len, + dest_size-ret_len); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + + if (address->is_default) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "PREF"); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ":%s", + SAFE_STR(address->pobox)); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", + SAFE_STR(address->extended)); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", + SAFE_STR(address->street)); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", + SAFE_STR(address->locality)); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", + SAFE_STR(address->region)); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", + SAFE_STR(address->postalcode)); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s%s", + SAFE_STR(address->country), CTSVC_CRLF); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + } + + return ret_len; +} + +static inline int __ctsvc_vcard_append_nicknames(ctsvc_list_s *nickname_list, + char *dest, int dest_size) +{ + bool first; + int ret_len = 0; + 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) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:", + content_name[CTSVC_VCARD_VALUE_NICKNAME]); + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s", nickname->nickname); + first = false; + } + else { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ",%s", nickname->nickname); + } + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + } + + if (ret_len > 0) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s", CTSVC_CRLF); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + + return ret_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 *dest, int dest_size) +{ + int ret_len = 0; + if (type & CONTACTS_NUMBER_TYPE_HOME) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "HOME"); + if (type & CONTACTS_NUMBER_TYPE_MSG) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "MSG"); + if (type & CONTACTS_NUMBER_TYPE_WORK) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "WORK"); + if (type & CONTACTS_NUMBER_TYPE_VOICE) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "VOICE"); + if (type & CONTACTS_NUMBER_TYPE_FAX) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "FAX"); + if (type & CONTACTS_NUMBER_TYPE_VOICE) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "VOICE"); + if (type & CONTACTS_NUMBER_TYPE_CELL) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "CELL"); + if (type & CONTACTS_NUMBER_TYPE_VIDEO) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "VIDEO"); + if (type & CONTACTS_NUMBER_TYPE_PAGER) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "PAGER"); + if (type & CONTACTS_NUMBER_TYPE_BBS) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "BBS"); + if (type & CONTACTS_NUMBER_TYPE_MODEM) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "MODEM"); + if (type & CONTACTS_NUMBER_TYPE_CAR) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "CAR"); + if (type & CONTACTS_NUMBER_TYPE_ISDN) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "ISDN"); + if (type & CONTACTS_NUMBER_TYPE_PCS) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "PCS"); + if (type & CONTACTS_NUMBER_TYPE_ASSISTANT) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "X-ASSISTANT"); + if (type & CONTACTS_NUMBER_TYPE_CUSTOM) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=X-%s", label); + return ret_len; +} + + +static inline int __ctsvc_vcard_append_numbers(ctsvc_list_s *number_list, + char *dest, int dest_size) +{ + int ret_len = 0; + GList *cursor; + ctsvc_number_s *number; + + for (cursor=number_list->records;cursor;cursor=cursor->next) { + number = cursor->data; + if (number->number) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s", + content_name[CTSVC_VCARD_VALUE_TEL]); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + + ret_len += __ctsvc_vcard_put_number_type(number->type, number->label, dest+ret_len, dest_size-ret_len); + if (number->is_default) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "PREF"); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ":%s%s", + number->number, CTSVC_CRLF); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + } + + return ret_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 *dest, int dest_size) +{ + int ret_len = 0; + + if (CONTACTS_EMAIL_TYPE_HOME & type) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "HOME"); + if (CONTACTS_EMAIL_TYPE_WORK & type) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=%s", "WORK"); + if (CONTACTS_EMAIL_TYPE_CUSTOM & type) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";TYPE=X-%s", label); + + return ret_len; +} + +static inline int __ctsvc_vcard_append_emails(ctsvc_list_s *email_list, + char *dest, int dest_size) +{ + int ret_len = 0; + GList *cursor; + ctsvc_email_s *email; + + for (cursor=email_list->records;cursor;cursor=cursor->next) { + email = cursor->data; + if (email->email_addr) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s", + content_name[CTSVC_VCARD_VALUE_EMAIL]); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + + ret_len += __ctsvc_vcard_put_email_type(email->type, email->label, dest+ret_len, dest_size-ret_len); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + + if (email->is_default) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ";%s", "PREF"); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + + ret_len += snprintf(dest+ret_len, dest_size-ret_len, ":%s%s", + email->email_addr, CTSVC_CRLF); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + } + + return ret_len; +} + +static inline int __ctsvc_vcard_append_webs(ctsvc_list_s *url_list, + char *dest, int dest_size) +{ + int ret_len = 0; + GList *cursor; + ctsvc_url_s *url; + + for (cursor=url_list->records;cursor;cursor=cursor->next) { + url = cursor->data; + if (url->url && *url->url) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s", + content_name[CTSVC_VCARD_VALUE_URL], + url->url, CTSVC_CRLF); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + } + + return ret_len; +} + +static inline int __ctsvc_vcard_append_events(ctsvc_list_s *event_list, + char *dest, int dest_size) +{ + int ret_len = 0; + GList *cursor; + ctsvc_event_s *data; + + for (cursor=event_list->records;cursor;cursor=cursor->next) { + data = cursor->data; + if (!data->date) continue; + + if (CONTACTS_EVENT_TYPE_BIRTH == data->type) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%d-%02d-%d%s", + content_name[CTSVC_VCARD_VALUE_BDAY], + data->date/10000, (data->date%10000)/100, data->date%100, + CTSVC_CRLF); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + else if (CONTACTS_EVENT_TYPE_ANNIVERSARY == data->type) { + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%d-%02d-%d%s", + content_name[CTSVC_VCARD_VALUE_X_ANNIVERSARY], + data->date/10000, (data->date%10000)/100, data->date%100, + CTSVC_CRLF); + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + } + + return ret_len; +} + +static inline int __ctsvc_vcard_append_messengers(ctsvc_list_s *messenger_list, char *dest, int dest_size) +{ + int ret_len = 0; + GList *cursor; + ctsvc_messenger_s *messenger; + + for (cursor=messenger_list->records;cursor;cursor=cursor->next) { + messenger = cursor->data; + if (messenger->im_id && *messenger->im_id) { + switch (messenger->type) { + case CONTACTS_MESSENGER_TYPE_WLM: + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s", + content_name[CTSVC_VCARD_VALUE_X_MSN], messenger->im_id, CTSVC_CRLF); + break; + case CONTACTS_MESSENGER_TYPE_YAHOO: + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s", + content_name[CTSVC_VCARD_VALUE_X_YAHOO], messenger->im_id, CTSVC_CRLF); + break; + case CONTACTS_MESSENGER_TYPE_ICQ: + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s", + content_name[CTSVC_VCARD_VALUE_X_ICQ], messenger->im_id, CTSVC_CRLF); + break; + case CONTACTS_MESSENGER_TYPE_AIM: + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s", + content_name[CTSVC_VCARD_VALUE_X_AIM], messenger->im_id, CTSVC_CRLF); + break; + case CONTACTS_MESSENGER_TYPE_JABBER: + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s", + content_name[CTSVC_VCARD_VALUE_X_JABBER], messenger->im_id, CTSVC_CRLF); + break; + case CONTACTS_MESSENGER_TYPE_SKYPE: + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s", + content_name[CTSVC_VCARD_VALUE_X_SKYPE], messenger->im_id, CTSVC_CRLF); + break; + case CONTACTS_MESSENGER_TYPE_QQ: + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s", + content_name[CTSVC_VCARD_VALUE_X_QQ], messenger->im_id, CTSVC_CRLF); + break; + case CONTACTS_MESSENGER_TYPE_GOOGLE: + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s", + content_name[CTSVC_VCARD_VALUE_X_GOOGLE_TALK], messenger->im_id, CTSVC_CRLF); + break; + default: + break; + } + RETV_IF(dest_size <= ret_len, CONTACTS_ERROR_INTERNAL); + } + } + return ret_len; +} + +static inline int __ctsvc_vcard_put_photo(ctsvc_list_s *image_list, char *dest, int dest_size) +{ + int ret = 0, fd, type; + gsize read_len; + char *suffix; + gchar *buf; + guchar image[CTSVC_VCARD_PHOTO_MAX_SIZE] = {0}; + + 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, '.'); + RETVM_IF(NULL == suffix, CONTACTS_ERROR_INVALID_PARAMETER, + "Invalid parameter : Image Type(%s) is invalid", data->path); + + type = __ctsvc_vcard_get_image_type(suffix); + RETVM_IF(CTSVC_VCARD_IMG_NONE == type, 0, "Invalid parameter : Image Type(%s) is invalid", data->path); + + fd = open(data->path, O_RDONLY); + RETVM_IF(fd < 0, CONTACTS_ERROR_SYSTEM, "System : Open(%s) Failed(%d)", data->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, CONTACTS_ERROR_SYSTEM, "System : 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[CTSVC_VCARD_VALUE_PHOTO], + __ctsvc_get_image_type_str(type), buf, CTSVC_CRLF, CTSVC_CRLF); + g_free(buf); + RETV_IF(dest_size <= ret, CONTACTS_ERROR_INTERNAL); + } + } + + return ret; +} + +static inline int __ctsvc_vcard_append_contact(ctsvc_contact_s *contact, + char *dest, int dest_size) +{ + int ret_len = 0; + int ret; + + if (contact->name) { + ret = __ctsvc_vcard_append_name(contact->name, + dest+ret_len, dest_size-ret_len); + RETV_IF(ret < 0, ret); + ret_len += ret; + } + if (contact->company) { + ret = __ctsvc_vcard_append_company(contact->company, + dest+ret_len, dest_size-ret_len); + RETV_IF(ret < 0, ret); + ret_len += ret; + } + if (contact->note) { + ret = __ctsvc_vcard_append_note(contact->note, + dest+ret_len, dest_size-ret_len); + RETV_IF(ret < 0, ret); + ret_len += ret; + } + if (contact->postal_addrs) { + ret = __ctsvc_vcard_append_postals(contact->postal_addrs, + dest+ret_len, dest_size-ret_len); + RETV_IF(ret < 0, ret); + ret_len += ret; + } + if (contact->numbers) { + ret = __ctsvc_vcard_append_numbers(contact->numbers, + dest+ret_len, dest_size-ret_len); + RETV_IF(ret < 0, ret); + ret_len += ret; + } + if (contact->emails) { + ret = __ctsvc_vcard_append_emails(contact->emails, + dest+ret_len, dest_size-ret_len); + RETV_IF(ret < 0, ret); + ret_len += ret; + } + if (contact->nicknames) { + ret = __ctsvc_vcard_append_nicknames(contact->nicknames, + dest+ret_len, dest_size-ret_len); + RETV_IF(ret < 0, ret); + ret_len += ret; + } + if (contact->urls) { + ret = __ctsvc_vcard_append_webs(contact->urls, + dest+ret_len, dest_size-ret_len); + RETV_IF(ret < 0, ret); + ret_len += ret; + } + if (contact->events) { + ret = __ctsvc_vcard_append_events(contact->events, + dest+ret_len, dest_size-ret_len); + RETV_IF(ret < 0, ret); + ret_len += ret; + } + if (contact->images) { + ret = __ctsvc_vcard_put_photo(contact->images, + dest+ret_len, dest_size-ret_len); + RETV_IF(ret < 0, ret); + ret_len += ret; + } + if (contact->messengers) { + ret = __ctsvc_vcard_append_messengers(contact->messengers, dest+ret_len, dest_size-ret_len); + RETV_IF(ret < 0, ret); + ret_len += ret; + } + if (contact->uid) + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%s:%s%s", + content_name[CTSVC_VCARD_VALUE_UID], + contact->uid, CTSVC_CRLF); + if (contact->changed_time) { + struct tm ts; + gmtime_r((time_t *)&contact->changed_time, &ts); + ret_len += snprintf(dest+ret_len, dest_size-ret_len, "%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); + } +#if 0 + char *image_path; + ctsvc_list_s* grouprelations; + ctsvc_list_s* profile; + ctsvc_list_s* relationships; +#endif + return ret_len; +} + +static int __ctsvc_vcard_make(ctsvc_contact_s *contact, char **vcard_stream) +{ + int ret_len, ret; + char result[CTSVC_VCARD_FILE_MAX_SIZE] = {0}; + + __ctsvc_vcard_initial(); + + ret_len = snprintf(result, sizeof(result), "%s%s", "BEGIN:VCARD", CTSVC_CRLF); + ret_len += snprintf(result+ret_len, sizeof(result)-ret_len, + "%s%s%s", "VERSION:", "3.0", CTSVC_CRLF); + + ret = __ctsvc_vcard_append_contact(contact, + result+ret_len, sizeof(result)-ret_len); + RETVM_IF(ret < 0, CONTACTS_ERROR_INTERNAL, + "This contact has too many information"); + ret_len += ret; + RETVM_IF(sizeof(result)-ret_len <= 0, CONTACTS_ERROR_INTERNAL, + "This contact has too many information"); + + ret_len += snprintf(result+ret_len, sizeof(result)-ret_len, + "%s%s", "END:VCARD", CTSVC_CRLF); + + ret = __ctsvc_vcard_add_folding(result); + RETV_IF (CONTACTS_ERROR_NONE != ret, ret); + + *vcard_stream = strdup(result); + + 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); + + __ctsvc_vcard_make(contact, vcard_stream); + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_vcard_append_person(ctsvc_person_s *person, ctsvc_list_s *list_contacts, char *dest, int dest_size) +{ + int ret; + int ret_len = 0; + int total_len = 0; + int changed_time = 0; + ctsvc_contact_s *contact; + ctsvc_simple_contact_s *simple_contact; + GList *cursor = NULL; + + for(cursor=list_contacts->records;cursor;cursor=cursor->next) { + simple_contact = (ctsvc_simple_contact_s *)cursor->data; + ret = contacts_db_get_record(_contacts_contact._uri, simple_contact->contact_id, (contacts_record_h *)&contact); + if (CONTACTS_ERROR_NONE == ret && contact && contact->id == person->name_contact_id && contact->name) { + ret_len = __ctsvc_vcard_append_name(contact->name, dest+total_len, dest_size-total_len); + RETVM_IF(ret_len < 0, CONTACTS_ERROR_INTERNAL, "This person has too many information"); + total_len += ret_len; + break; + } + } + + for(cursor=list_contacts->records;cursor;cursor=cursor->next) { + simple_contact = (ctsvc_simple_contact_s *)cursor->data; + ret = contacts_db_get_record(_contacts_contact._uri, simple_contact->contact_id, (contacts_record_h *)&contact); + if (CONTACTS_ERROR_NONE == ret && contact && contact->company && contact->company->cursor) { + ret_len = __ctsvc_vcard_append_company(contact->company, dest+total_len, dest_size-total_len); + RETVM_IF(ret_len < 0, CONTACTS_ERROR_INTERNAL, "This person has too many information"); + total_len += ret_len; + } + } + for(cursor=list_contacts->records;cursor;cursor=cursor->next) { + simple_contact = (ctsvc_simple_contact_s *)cursor->data; + ret = contacts_db_get_record(_contacts_contact._uri, simple_contact->contact_id, (contacts_record_h *)&contact); + if (CONTACTS_ERROR_NONE == ret && contact && contact->note && contact->note->cursor) { + ret_len = __ctsvc_vcard_append_note(contact->note, dest+total_len, dest_size-total_len); + RETVM_IF(ret_len < 0, CONTACTS_ERROR_INTERNAL, "This person has too many information"); + total_len += ret_len; + } + } + for(cursor=list_contacts->records;cursor;cursor=cursor->next) { + simple_contact = (ctsvc_simple_contact_s *)cursor->data; + ret = contacts_db_get_record(_contacts_contact._uri, simple_contact->contact_id, (contacts_record_h *)&contact); + if (CONTACTS_ERROR_NONE == ret && contact && contact->postal_addrs && contact->postal_addrs->cursor) { + ret_len = __ctsvc_vcard_append_postals(contact->postal_addrs, dest+total_len, dest_size-total_len); + RETVM_IF(ret_len < 0, CONTACTS_ERROR_INTERNAL, "This person has too many information"); + total_len += ret_len; + } + } + for(cursor=list_contacts->records;cursor;cursor=cursor->next) { + simple_contact = (ctsvc_simple_contact_s *)cursor->data; + ret = contacts_db_get_record(_contacts_contact._uri, simple_contact->contact_id, (contacts_record_h *)&contact); + if (CONTACTS_ERROR_NONE == ret && contact && contact->numbers && contact->numbers->cursor) { + ret_len = __ctsvc_vcard_append_numbers(contact->numbers, dest+total_len, dest_size-total_len); + RETVM_IF(ret_len < 0, CONTACTS_ERROR_INTERNAL, "This person has too many information"); + total_len += ret_len; + } + } + for(cursor=list_contacts->records;cursor;cursor=cursor->next) { + simple_contact = (ctsvc_simple_contact_s *)cursor->data; + ret = contacts_db_get_record(_contacts_contact._uri, simple_contact->contact_id, (contacts_record_h *)&contact); + if (CONTACTS_ERROR_NONE == ret && contact && contact->emails && contact->emails->cursor) { + ret_len = __ctsvc_vcard_append_emails(contact->emails, dest+total_len, dest_size-total_len); + RETVM_IF(ret_len < 0, CONTACTS_ERROR_INTERNAL, "This person has too many information"); + total_len += ret_len; + } + } + for(cursor=list_contacts->records;cursor;cursor=cursor->next) { + simple_contact = (ctsvc_simple_contact_s *)cursor->data; + ret = contacts_db_get_record(_contacts_contact._uri, simple_contact->contact_id, (contacts_record_h *)&contact); + if (CONTACTS_ERROR_NONE == ret && contact && contact->nicknames && contact->nicknames->cursor) { + ret_len = __ctsvc_vcard_append_nicknames(contact->nicknames, dest+total_len, dest_size-total_len); + RETVM_IF(ret_len < 0, CONTACTS_ERROR_INTERNAL, "This person has too many information"); + total_len += ret_len; + } + } + for(cursor=list_contacts->records;cursor;cursor=cursor->next) { + simple_contact = (ctsvc_simple_contact_s *)cursor->data; + ret = contacts_db_get_record(_contacts_contact._uri, simple_contact->contact_id, (contacts_record_h *)&contact); + if (CONTACTS_ERROR_NONE == ret && contact && contact->urls && contact->urls->cursor) { + ret_len = __ctsvc_vcard_append_webs(contact->urls, dest+total_len, dest_size-total_len); + RETVM_IF(ret_len < 0, CONTACTS_ERROR_INTERNAL, "This person has too many information"); + total_len += ret_len; + } + } + for(cursor=list_contacts->records;cursor;cursor=cursor->next) { + simple_contact = (ctsvc_simple_contact_s *)cursor->data; + ret = contacts_db_get_record(_contacts_contact._uri, simple_contact->contact_id, (contacts_record_h *)&contact); + if (CONTACTS_ERROR_NONE == ret && contact && contact->events && contact->events->cursor) { + ret_len = __ctsvc_vcard_append_events(contact->events, dest+total_len, dest_size-total_len); + RETVM_IF(ret_len < 0, CONTACTS_ERROR_INTERNAL, "This person has too many information"); + total_len += ret_len; + } + } + for(cursor=list_contacts->records;cursor;cursor=cursor->next) { + simple_contact = (ctsvc_simple_contact_s *)cursor->data; + ret = contacts_db_get_record(_contacts_contact._uri, simple_contact->contact_id, (contacts_record_h *)&contact); + if (CONTACTS_ERROR_NONE == ret && contact && contact->images && contact->images->cursor) { + ret_len = __ctsvc_vcard_put_photo(contact->images, dest+total_len, dest_size-total_len); + RETVM_IF(ret_len < 0, CONTACTS_ERROR_INTERNAL, "This person has too many information"); + total_len += ret_len; + } + } + for(cursor=list_contacts->records;cursor;cursor=cursor->next) { + simple_contact = (ctsvc_simple_contact_s *)cursor->data; + ret = contacts_db_get_record(_contacts_contact._uri, simple_contact->contact_id, (contacts_record_h *)&contact); + if (CONTACTS_ERROR_NONE == ret && contact && contact->messengers && contact->messengers->cursor) { + ret_len = __ctsvc_vcard_append_messengers(contact->messengers, dest+total_len, dest_size-total_len); + RETVM_IF(ret_len < 0, CONTACTS_ERROR_INTERNAL, "This person has too many information"); + total_len += ret_len; + } + } + for(cursor=list_contacts->records;cursor;cursor=cursor->next) { + simple_contact = (ctsvc_simple_contact_s *)cursor->data; + ret = contacts_db_get_record(_contacts_contact._uri, simple_contact->contact_id, (contacts_record_h *)&contact); + if (CONTACTS_ERROR_NONE == ret && contact && contact->uid) { + ret_len = snprintf(dest+total_len, dest_size-total_len, "%s:%s%s", content_name[CTSVC_VCARD_VALUE_UID], contact->uid, CTSVC_CRLF); + RETVM_IF(ret_len < 0, CONTACTS_ERROR_INTERNAL, "This person has too many information"); + total_len += ret_len; + } + } + for(cursor=list_contacts->records;cursor;cursor=cursor->next) { + simple_contact = (ctsvc_simple_contact_s *)cursor->data; + ret = contacts_db_get_record(_contacts_contact._uri, simple_contact->contact_id, (contacts_record_h *)&contact); + if (CONTACTS_ERROR_NONE == ret && contact && changed_time < contact->changed_time) + changed_time = contact->changed_time; + } + if (changed_time) { + struct tm ts; + gmtime_r((time_t *)&changed_time, &ts); + ret_len = snprintf(dest+total_len, dest_size-total_len, "%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); + RETVM_IF(ret_len < 0, CONTACTS_ERROR_INTERNAL, "This person has too many information"); + total_len += ret_len; + } +#if 0 + char *image_path; + ctsvc_list_s* grouprelations; + ctsvc_list_s* profile; + ctsvc_list_s* relationships; +#endif + return total_len; +} + +static int __ctsvc_vcard_make_from_person(ctsvc_person_s *person, ctsvc_list_s *list_contacts, + char **vcard_stream) +{ + int ret_len, ret; + char *result = NULL; + + RETV_IF(NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER); + *vcard_stream = NULL; + + result = calloc(1, CTSVC_VCARD_FILE_MAX_SIZE); + RETVM_IF(NULL == result, CONTACTS_ERROR_OUT_OF_MEMORY, "Out of memory : calloc() Failed()"); + + __ctsvc_vcard_initial(); + + ret_len = snprintf(result, CTSVC_VCARD_FILE_MAX_SIZE, "%s%s", "BEGIN:VCARD", CTSVC_CRLF); + ret_len += snprintf(result+ret_len, CTSVC_VCARD_FILE_MAX_SIZE-ret_len, "%s%s%s", "VERSION:", "3.0", CTSVC_CRLF); + ret = __ctsvc_vcard_append_person(person, list_contacts, result+ret_len, CTSVC_VCARD_FILE_MAX_SIZE-ret_len); + if (ret < 0) { + free(result); + return ret; + } + + ret_len += ret; + if (CTSVC_VCARD_FILE_MAX_SIZE-ret_len <= 0) { + CTS_ERR("This person has too many information"); + free(result); + return CONTACTS_ERROR_INTERNAL; + } + + ret_len += snprintf(result+ret_len, CTSVC_VCARD_FILE_MAX_SIZE-ret_len, "%s%s", "END:VCARD", CTSVC_CRLF); + if (CTSVC_VCARD_FILE_MAX_SIZE-ret_len <= 0) { + CTS_ERR("This person has too many information"); + free(result); + return CONTACTS_ERROR_INTERNAL; + } + + ret = __ctsvc_vcard_add_folding(result); + if (CONTACTS_ERROR_NONE != ret) { + free(result); + return ret; + } + + *vcard_stream = strdup(result); + free(result); + + 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 paramter : The record is not conatct record (type : %d)", person->base.r_type); + + contacts_filter_create(_contacts_simple_contact._uri, &filter); + ret = contacts_filter_add_int(filter, _contacts_simple_contact.person_id, CONTACTS_MATCH_EQUAL, person->person_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("Invalid paramter : contacts_filter_add_int is failed", ret); + contacts_filter_destroy(filter); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + contacts_query_create(_contacts_simple_contact._uri, &query); + contacts_query_set_filter(query, filter); + ret = contacts_db_get_records_with_query(query, 0, 0, &list); + + if (ret == CONTACTS_ERROR_NONE) + __ctsvc_vcard_make_from_person(person, (ctsvc_list_s *)list, vcard_stream); + + contacts_query_destroy(query); + contacts_filter_destroy(filter); + contacts_list_destroy(list, true); + + return CONTACTS_ERROR_NONE; +} + +//////////////////////////////////////////////////////////////////////////// +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) +{ + while(*val) { + if(*val == c) { + *val = '\0'; + return (val+1); + } + val++; + } + return val; +} + +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(%s)", val); + + return temp; +} + +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) { + int src_len, dest_len, i = 0; + iconv_t ic; + 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++; + + 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; + } + CTS_ERR("iconv is Failed(errno = %d)", errno); + break; + } + } + dest[dest_len-out_byte] = '\0'; + break; + } + iconv_close(ic); + return dest; + } + + return NULL; +} + + +static char* __ctsvc_vcard_get_val(int ver, char *src, char **dest) +{ + int len, 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 ' ': + case ':': + src++; + break; + default: + start = true; + break; + } + if (start) break; + } + + quoted = FALSE; + cursor = src; + len = 0; + if(CTSVC_VCARD_VER_2_1 == ver) { + while (*cursor) { + if ('=' == *cursor && __ctsvc_vcard_check_quoted(src, cursor - src, "ed)) { + 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(CTSVC_VCARD_VER_2_1 != ver) + __ctsvc_vcard_remove_folding(*dest); + + if (__ctsvc_vcard_check_quoted(*dest, -1, "ed)) + 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 int __ctsvc_vcard_get_display_name(ctsvc_list_s *name_list, char *val) +{ + int ret; + unsigned 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(%s)", val); + + 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)) + contacts_record_set_str(name, _contacts_name.first, temp); + + return CONTACTS_ERROR_NONE; +} + +static inline int __ctsvc_vcard_get_name(ctsvc_list_s *name_list, char *val) +{ + int ret; + unsigned int count; + char *temp, *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); + } + + temp = __ctsvc_strtok(start, separator); + contacts_record_set_str(name, _contacts_name.last, start); + + start = temp; + temp = __ctsvc_strtok(start, separator); + contacts_record_set_str(name, _contacts_name.first, start); + + start = temp; + temp = __ctsvc_strtok(start, separator); + contacts_record_set_str(name, _contacts_name.addition, start); + + start = temp; + temp = __ctsvc_strtok(start, separator); + contacts_record_set_str(name, _contacts_name.prefix, start); + + start = temp; + __ctsvc_strtok(start, separator); + contacts_record_set_str(name, _contacts_name.suffix, start); + + return CONTACTS_ERROR_NONE; +} + +static inline int __ctsvc_vcard_get_phonetic_name(ctsvc_list_s *name_list, int type, char *val) +{ + int ret; + unsigned 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) + contacts_record_set_str(name, _contacts_name.phonetic_first, start); + else + contacts_record_set_str(name, _contacts_name.phonetic_last, start); + + return CONTACTS_ERROR_NONE; +} + +static inline int __ctsvc_vcard_get_phonetic_last_name(ctsvc_list_s *name_list, char *val) +{ + int ret; + unsigned 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); + contacts_record_set_str(name, _contacts_name.phonetic_last, start); + + return CONTACTS_ERROR_NONE; +} + + + +static inline int __ctsvc_vcard_get_nickname(ctsvc_list_s *nickname_list, char *val) +{ + int ret; + char *temp; + const char *separator = ","; + contacts_record_h nickname; + + ret = contacts_record_create(_contacts_nickname._uri, &nickname); + RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret); + + temp = strtok(val, separator); + while (temp) { + if ('\0' == *temp) continue; + + contacts_record_create(_contacts_nickname._uri, &nickname); + if (nickname) { + contacts_record_set_str(nickname, _contacts_nickname.name, temp); + 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 *val) +{ + int ret, type, fd; + gsize size; + guchar *buf; + char *temp; + char dest[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0}; + contacts_record_h image; + + temp = strchr(val , ':'); + RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : val is invalid(%s)", val); + + *temp = '\0'; + + type = __ctsvc_vcard_get_image_type(val); + + ret = snprintf(dest, sizeof(dest), "%s/vcard-image-%d.%s", + CTSVC_VCARD_IMAGE_LOCATION, __ctsvc_tmp_image_id++, __ctsvc_get_img_suffix(type)); + RETVM_IF(ret<=0, CONTACTS_ERROR_INTERNAL, "Destination file name was not created"); + + fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0660); + RETVM_IF(fd < 0, CONTACTS_ERROR_SYSTEM, "System : 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 { + CTS_ERR("write() Failed(%d)", errno); + close(fd); + if (ENOSPC == errno) + return CONTACTS_ERROR_SYSTEM; // 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); + + contacts_record_set_str(image, _contacts_image.path, dest); + contacts_list_add((contacts_list_h)image_list, image); + + contacts_record_set_str(contact, _contacts_contact.image_thumbnail_path, dest); + + return CONTACTS_ERROR_NONE; +} + +static inline int __ctsvc_vcard_get_event(ctsvc_list_s *event_list, int type, char *val) +{ + int ret; + contacts_record_h event; + char *dest, *src; + + dest = src = val; + while (*src) { + if ('0' <= *src && *src <= '9') { + *dest = *src; + dest++; + } + src++; + if (8 <= dest - val) + break; + } + *dest = '\0'; + + RETVM_IF('\0' == *val, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : val(%d)", val); + + ret = contacts_record_create(_contacts_event._uri, &event); + RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret); + + contacts_record_set_int(event, _contacts_event.date, atoi(val)); + contacts_record_set_int(event, _contacts_event.type, type); + contacts_list_add((contacts_list_h)event_list, event); + + return CONTACTS_ERROR_NONE; +} + +static inline int __ctsvc_vcard_get_company(ctsvc_list_s *company_list, unsigned int property_id, char *val) +{ + int ret; + unsigned int count; + char *temp, *start; + contacts_record_h company; + + contacts_list_get_count((contacts_list_h)company_list, &count); + if (count <= 0) { + 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); + } + else { + contacts_list_get_current_record_p((contacts_list_h)company_list, &company); + } + + if (property_id == _contacts_company.name) { + start = __ctsvc_get_content_value(val); + RETV_IF(NULL == start, CONTACTS_ERROR_NO_DATA); + + temp = strchr(start, ';'); + if (temp) { + *temp = '\0'; + contacts_record_set_str(company, property_id, start); + contacts_record_set_str(company, _contacts_company.department, temp+1); + } + else + contacts_record_set_str(company, property_id, start); + } + else if (property_id == _contacts_company.job_title + || property_id == _contacts_company.role) { + contacts_record_set_str(company, property_id, val); + } + else + return CONTACTS_ERROR_INVALID_PARAMETER; + + return CONTACTS_ERROR_NONE; +} + +static inline int __ctsvc_vcard_get_company_logo(ctsvc_list_s *company_list, char *val) +{ + int ret, type, fd; + unsigned int count; + gsize size; + guchar *buf; + char dest[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0}; + char *temp; + contacts_record_h company; + + contacts_list_get_count((contacts_list_h)company_list, &count); + if (count <= 0) { + 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); + } + else { + contacts_list_get_current_record_p((contacts_list_h)company_list, &company); + } + + temp = strchr(val , ':'); + RETVM_IF(NULL == temp, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : val is invalid(%s)", val); + + *temp = '\0'; + type = __ctsvc_vcard_get_image_type(val); + + ret = snprintf(dest, sizeof(dest), "%s/%d-%d-logo.%s", CTSVC_VCARD_IMAGE_LOCATION, + getpid(), __ctsvc_tmp_logo_id++, __ctsvc_get_img_suffix(type)); + RETVM_IF(ret<=0, CONTACTS_ERROR_SYSTEM, "Destination file name was not created"); + + fd = open(dest, O_WRONLY|O_CREAT|O_TRUNC, 0660); + RETVM_IF(fd < 0, CONTACTS_ERROR_INTERNAL, "System : 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 { + CTS_ERR("write() Failed(%d)", errno); + close(fd); + if (ENOSPC == errno) + return CONTACTS_ERROR_SYSTEM; // No space + else + return CONTACTS_ERROR_SYSTEM; // IO error + } + } + size -= ret; + } + + close(fd); + g_free(buf); + + 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; + unsigned int count; + char *temp; + contacts_record_h note; + + contacts_list_get_count((contacts_list_h)note_list, &count); + if (count <= 0) { + ret = contacts_record_create(_contacts_note._uri, ¬e); + RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret); + contacts_list_add((contacts_list_h)note_list, note); + } + else { + contacts_list_get_current_record_p((contacts_list_h)note_list, ¬e); + } + + temp = __ctsvc_get_content_value(val); + RETV_IF(NULL == temp, CONTACTS_ERROR_NO_DATA); + contacts_record_set_str(note, _contacts_note.note, g_strcompress(temp)); + + 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 int __ctsvc_vcard_get_url(ctsvc_list_s* url_list, 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(%s)", val); + + ret = contacts_record_create(_contacts_url._uri, &url); + RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret); + + contacts_record_set_str(url, _contacts_url.url, temp); + if (val != temp) { + *(temp-1) = '\0'; + temp = val; + while (*temp) { + *temp = tolower(*temp); + temp++; + } + + temp = strchr(val, ';'); + if (temp) { + if (strstr(val, "home")) + contacts_record_set_int(url, _contacts_url.type, CONTACTS_URL_TYPE_HOME); + else if (strstr(val, "work")) + contacts_record_set_int(url, _contacts_url.type, CONTACTS_URL_TYPE_WORK); + } + } + 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); + 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 { + type = CONTACTS_NUMBER_TYPE_CUSTOM; + contacts_record_set_str(number, _contacts_number.label, temp+(result-lower)+2); + } + } + + free(lower); + temp = strtok_r(NULL, ";", &last); + } + contacts_record_set_int(number, _contacts_number.type, type); + + return pref; +} + +static inline int __ctsvc_vcard_get_number(ctsvc_list_s *numbers, char *val) +{ + 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(%s)", val); + + ret = contacts_record_create(_contacts_number._uri, &number); + RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret); + + contacts_record_set_str(number, _contacts_number.number, temp); + if (val != temp) { + *(temp-1) = '\0'; + contacts_record_set_bool(number, _contacts_number.is_default, __ctsvc_vcard_get_number_type(number, val)); + } + 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); + lower_temp = lower; + while (*lower_temp) { + *lower_temp = tolower(*lower_temp); + lower_temp++; + } + result = strstr(lower, "home"); + if (result) type = CONTACTS_EMAIL_TYPE_HOME; + result = strstr(lower, "work"); + if (result) type = CONTACTS_EMAIL_TYPE_WORK; + result = strstr(lower, "pref"); + if (result) pref = true; + result = strstr(lower, "x-"); + if (result) { + type = CONTACTS_EMAIL_TYPE_CUSTOM; + contacts_record_set_str(email, _contacts_email.label, temp+(result-lower)+2); + } + + 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 *val) +{ + 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(%s)", val); + + ret = contacts_record_create(_contacts_email._uri, &email); + RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret); + + contacts_record_set_str(email, _contacts_email.email, temp); + if (val != temp) { + *(temp-1) = '\0'; + contacts_record_set_bool(email, _contacts_email.is_default, __ctsvc_vcard_get_email_type(email, val)); + } + 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); + 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) { + type = CONTACTS_ADDRESS_TYPE_CUSTOM; + contacts_record_set_str(address, _contacts_address.label, temp+(result-lower)+2); + } + 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; +} + +#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 int __ctsvc_vcard_get_address(ctsvc_list_s *address_list, char *val) +{ + char *text; + contacts_record_h address; + + contacts_record_create(_contacts_address._uri, &address); + if (address) { + + text = strrchr(val , ':'); + if (text) { + text++; + *(text-1) = '\0'; + } + else + text = val; + + while (true) { + char *temp; + + CTS_GET_ADDR_COMPONENT(((ctsvc_address_s*)address)->pobox, text, temp); + CTS_GET_ADDR_COMPONENT(((ctsvc_address_s*)address)->extended, text, temp); + CTS_GET_ADDR_COMPONENT(((ctsvc_address_s*)address)->street, text, temp); + CTS_GET_ADDR_COMPONENT(((ctsvc_address_s*)address)->locality, text, temp); + CTS_GET_ADDR_COMPONENT(((ctsvc_address_s*)address)->region, text, temp); + CTS_GET_ADDR_COMPONENT(((ctsvc_address_s*)address)->postalcode, text, temp); + CTS_GET_ADDR_COMPONENT(((ctsvc_address_s*)address)->country, text, temp); + + CTS_ERR("invalid ADR type(%s)", temp); + 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, val)); + } else { + CTS_ERR("Invalid vcard(%s)", val); + 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 int __ctsvc_vcard_get_messenger(ctsvc_list_s* messenger_list, int type, 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(%s)", val); + + ret = contacts_record_create(_contacts_messenger._uri, &messenger); + RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "contacts_record_create is failed(%d)", ret); + + contacts_record_set_str(messenger, _contacts_messenger.im_id, temp); + + 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: + 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; + } + contacts_list_add((contacts_list_h)messenger_list, messenger); + + return CONTACTS_ERROR_NONE; +} + +static inline int __ctsvc_vcard_get_contact(int ver, char *vcard, contacts_record_h *record) +{ + int type; + char *cursor, *new_start, *val; + ctsvc_contact_s *contact = (ctsvc_contact_s*)*record; + + cursor = vcard; + while (cursor) { + 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; + } + + new_start = __ctsvc_vcard_get_val(ver, cursor, &val); + if (NULL == new_start) + continue; + + if (NULL == val) { + cursor = new_start; + continue; + } + + switch (type) { + case CTSVC_VCARD_VALUE_FN: + __ctsvc_vcard_get_display_name(contact->name, val); + free(val); + break; + case CTSVC_VCARD_VALUE_N: + __ctsvc_vcard_get_name(contact->name, val); + free(val); + break; + case CTSVC_VCARD_VALUE_PHONETIC_FIRST_NAME: + case CTSVC_VCARD_VALUE_PHONETIC_LAST_NAME: + __ctsvc_vcard_get_phonetic_name(contact->name, type, val); + free(val); + break; + case CTSVC_VCARD_VALUE_NICKNAME: + __ctsvc_vcard_get_nickname(contact->nicknames, val); + free(val); + break; + case CTSVC_VCARD_VALUE_PHOTO: + __ctsvc_vcard_get_photo(*record, contact->images, val); + free(val); + break; + case CTSVC_VCARD_VALUE_BDAY: + __ctsvc_vcard_get_event(contact->events, CONTACTS_EVENT_TYPE_BIRTH, val); + free(val); + break; + case CTSVC_VCARD_VALUE_ADR: + case CTSVC_VCARD_VALUE_LABEL: + __ctsvc_vcard_get_address(contact->postal_addrs, val); + free(val); + break; + case CTSVC_VCARD_VALUE_TEL: + __ctsvc_vcard_get_number(contact->numbers, val); + free(val); + break; + case CTSVC_VCARD_VALUE_EMAIL: + __ctsvc_vcard_get_email(contact->emails, val); + free(val); + break; + case CTSVC_VCARD_VALUE_TITLE: + __ctsvc_vcard_get_company(contact->company, _contacts_company.job_title, val); + free(val); + break; + case CTSVC_VCARD_VALUE_ROLE: + __ctsvc_vcard_get_company(contact->company, _contacts_company.role, val); + free(val); + break; + case CTSVC_VCARD_VALUE_LOGO: + __ctsvc_vcard_get_company_logo(contact->company, val); + free(val); + break; + case CTSVC_VCARD_VALUE_ORG: + __ctsvc_vcard_get_company(contact->company, _contacts_company.name, val); + free(val); + break; + case CTSVC_VCARD_VALUE_NOTE: + __ctsvc_vcard_get_note(contact->note, val); + free(val); + break; + case CTSVC_VCARD_VALUE_REV: + if (*val) + contact->changed_time = __ctsvc_vcard_get_time(val); + free(val); + break; + case CTSVC_VCARD_VALUE_UID: + contacts_record_set_str((contacts_record_h)contact, _contacts_contact.uid, val); + free(val); + break; + case CTSVC_VCARD_VALUE_URL: + __ctsvc_vcard_get_url(contact->urls, val); + free(val); + break; + case CTSVC_VCARD_VALUE_X_ANNIVERSARY: + __ctsvc_vcard_get_event(contact->events, CONTACTS_EVENT_TYPE_ANNIVERSARY, val); + free(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: + case CTSVC_VCARD_VALUE_X_QQ: + case CTSVC_VCARD_VALUE_X_GOOGLE_TALK: + __ctsvc_vcard_get_messenger(contact->messengers, type, val); + free(val); + break; + case CTSVC_VCARD_VALUE_END: + free(val); + return CONTACTS_ERROR_NONE; + default: + CTS_ERR("Invalid parameter : __ctsvc_vcard_check_content_type() Failed(%d)", type); + free(val); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + cursor = new_start; + } + + CTS_ERR("Invalid vcard(%s)", 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) +{ + GList *cur; + + ctsvc_name_s *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) ) { + if (name->first && name->last) { + char display[strlen(name->first) + strlen(name->last) + 3]; + snprintf(display, sizeof(display),"%s %s",name->first,name->last); + contact->display_name = strdup(display); + snprintf(display, sizeof(display),"%s, %s",name->last, name->first); + contact->reverse_display_name = strdup(display); + } + else if (name->first) { + contact->display_name = strdup(name->first); + contact->reverse_display_name = strdup(name->first); + } + else { + contact->display_name = strdup(name->last); + contact->reverse_display_name = strdup(name->last); + } + + contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME; + } + else { + 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) { + contact->display_name = SAFE_STRDUP(company->name); + contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_COMPANY; + break; + } + } + } + + if (NULL == contact->display_name && 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) { + contact->display_name = SAFE_STRDUP(nickname->nickname); + contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NICKNAME; + break; + } + } + } + + if (NULL == contact->display_name && 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) { + contact->display_name = SAFE_STRDUP(number->number); + contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NUMBER; + break; + } + } + } + + if (NULL == contact->display_name && 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) { + contact->display_name = SAFE_STRDUP(email->email_addr); + contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL; + break; + } + } + } + } +} + +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, &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)\n %s \n", ret, vcard); + else + CTS_ERR("cts_vcard_get_contact() Failed(%d)", ret); + + return ret; + } + __ctsvc_vcard_make_contact_display_name(contact); + *record = (contacts_record_h)contact; + return CONTACTS_ERROR_NONE; +} + +#define CTSVC_VCARD_MAX_SIZE 1024*1024 + +API int contacts_vcard_parse_to_contacts(const char *vcard_stream, contacts_list_h *out_contacts) +{ + contacts_record_h record; + contacts_list_h list = NULL; + int len; + int ret; + int pos = 0; + int begin_pos; + char *stream; + char *temp; + char *vcard; + const char* sep = "END:VCARD"; + const char* begin_sep = "BEGIN:VCARD"; + + RETV_IF(NULL == out_contacts, CONTACTS_ERROR_INVALID_PARAMETER); + *out_contacts = NULL; + + RETV_IF(NULL == vcard_stream, CONTACTS_ERROR_INVALID_PARAMETER); + + temp = strstr(vcard_stream, begin_sep); + if(NULL == temp) + return CONTACTS_ERROR_INVALID_PARAMETER; + begin_pos = temp - vcard_stream; + vcard = strstr(temp, sep); + if(NULL == vcard) + return CONTACTS_ERROR_INVALID_PARAMETER; + pos = vcard - vcard_stream + strlen(sep); + len = vcard - temp + strlen(sep); + while (temp) { + stream = malloc(len+1); + snprintf(stream, len, "%s", vcard_stream+begin_pos); + stream[len] = '\0'; + + ret = __ctsvc_vcard_parse(stream, &record); + if (ret < CONTACTS_ERROR_NONE) { + CTS_ERR("Invalid parameter : vcard stream parsing error"); + free(stream); + contacts_list_destroy(list, true); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + if (NULL == list) + contacts_list_create(&list); + contacts_list_add(list, record); + free(stream); + vcard = (char*)(vcard_stream + pos); + temp = strstr(vcard, begin_sep); + if(NULL == temp) + break; + begin_pos = temp - vcard_stream; + vcard = strstr(temp, sep); + if (NULL == vcard) + break; + pos = vcard - vcard_stream + strlen(sep); + len = vcard - temp + strlen(sep); + } + + *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; + 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)) { + ret = __ctsvc_vcard_parse(stream, &record); + if (ret < CONTACTS_ERROR_NONE) { + CTS_ERR("Invalid parameter : vcard stream parsing error"); + free(stream); + fclose(file); + return CONTACTS_ERROR_NO_DATA; + } + + if (!cb(record, data)) { + free(stream); + fclose(file); + contacts_record_destroy(record, true); + return CONTACTS_ERROR_NO_DATA; + } + contacts_record_destroy(record, true); + len = 0; + } + } + + 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 index 0000000..d06e400 --- /dev/null +++ b/common/ctsvc_vcard.h @@ -0,0 +1,27 @@ +/*
+ * 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_VCARD_H__
+#define __TIZEN_SOCIAL_CTSVC_VCARD_H__
+
+#endif /* __TIZEN_SOCIAL_CTSVC_VCARD_H__ */
diff --git a/common/ctsvc_view.c b/common/ctsvc_view.c new file mode 100644 index 0000000..a8c08fa --- /dev/null +++ b/common/ctsvc_view.c @@ -0,0 +1,1287 @@ +/* + * 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, + .system_id = CTSVC_PROPERTY_GROUP_SYSTEM_ID, + .is_read_only = CTSVC_PROPERTY_GROUP_IS_READ_ONLY +}; + +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, + .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, + .account_id1 = CTSVC_PROPERTY_PERSON_ACCOUNT_ID1, + .account_id2 = CTSVC_PROPERTY_PERSON_ACCOUNT_ID2, + .account_id3 = CTSVC_PROPERTY_PERSON_ACCOUNT_ID3, + .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, + .changed_time = CTSVC_PROPERTY_CONTACT_CHANGED_TIME, + .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, + .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 +}; + +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_lunar = CTSVC_PROPERTY_EVENT_IS_LUNAR, + .lunar_date = CTSVC_PROPERTY_EVENT_LUNAR_DATE +}; + +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, + .type = CTSVC_PROPERTY_PROFILE_TYPE, + .label = CTSVC_PROPERTY_PROFILE_LABEL, + .uid = CTSVC_PROPERTY_PROFILE_UID, + .text = CTSVC_PROPERTY_PROFILE_TEXT, + .order = CTSVC_PROPERTY_PROFILE_ORDER, + .appsvc_operation = CTSVC_PROPERTY_PROFILE_APPSVC_OPERATION, + .data1 = CTSVC_PROPERTY_PROFILE_DATA1, + .data2 = CTSVC_PROPERTY_PROFILE_DATA2, + .data3 = CTSVC_PROPERTY_PROFILE_DATA3, + .data4 = CTSVC_PROPERTY_PROFILE_DATA4, + .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, +}; + +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, +}; + +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, +}; + +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, +}; + +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, + .sync_data1 = CTSVC_PROPERTY_ACTIVITY_SYNC_DATA1, + .sync_data2 = CTSVC_PROPERTY_ACTIVITY_SYNC_DATA2, + .sync_data3 = CTSVC_PROPERTY_ACTIVITY_SYNC_DATA3, + .sync_data4 = CTSVC_PROPERTY_ACTIVITY_SYNC_DATA4, + .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, +}; + +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, +}; + +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, + .status = CTSVC_PROPERTY_PERSON_STATUS, + .is_favorite = CTSVC_PROPERTY_PERSON_IS_FAVORITE, + .link_count = CTSVC_PROPERTY_PERSON_LINK_COUNT, + .account_id1 = CTSVC_PROPERTY_PERSON_ACCOUNT_ID1, + .account_id2 = CTSVC_PROPERTY_PERSON_ACCOUNT_ID2, + .account_id3 = CTSVC_PROPERTY_PERSON_ACCOUNT_ID3, + .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, + .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, +}; + +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, + .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, + .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, + .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, + .account_id1 = CTSVC_PROPERTY_PERSON_ACCOUNT_ID1, + .account_id2 = CTSVC_PROPERTY_PERSON_ACCOUNT_ID2, + .account_id3 = CTSVC_PROPERTY_PERSON_ACCOUNT_ID3, + .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_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, +}; + +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, +}; + +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, + .sync_data1 = CTSVC_PROPERTY_ACTIVITY_SYNC_DATA1, + .sync_data2 = CTSVC_PROPERTY_ACTIVITY_SYNC_DATA2, + .sync_data3 = CTSVC_PROPERTY_ACTIVITY_SYNC_DATA3, + .sync_data4 = CTSVC_PROPERTY_ACTIVITY_SYNC_DATA4, + .account_id = CTSVC_PROPERTY_ADDRESSBOOK_ACCOUNT_ID, +}; + +API const _contacts_phone_log_number_property_ids _contacts_phone_log_number = { + ._uri = CTSVC_VIEW_URI_READ_ONLY_PHONELOG_NUMBER, + .number = CTSVC_PROPERTY_PHONELOG_ADDRESS, +}; + +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, +}; + +const property_info_s __property_addressbook[] = { + {CTSVC_PROPERTY_ADDRESSBOOK_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_id"}, + {CTSVC_PROPERTY_ADDRESSBOOK_ACCOUNT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "account_id"}, + {CTSVC_PROPERTY_ADDRESSBOOK_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_name"}, + {CTSVC_PROPERTY_ADDRESSBOOK_MODE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "mode"}, +}; + +const property_info_s __property_snd[] = { + {CTSVC_PROPERTY_SDN_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_SDN_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "name"}, + {CTSVC_PROPERTY_SDN_NUMBER, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "number"}, +}; + +const property_info_s __property_group[] = { + {CTSVC_PROPERTY_GROUP_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "group_id"}, + {CTSVC_PROPERTY_GROUP_ADDRESSBOOK_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_id"}, + {CTSVC_PROPERTY_GROUP_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "group_name"}, + {CTSVC_PROPERTY_GROUP_RINGTONE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "ringtone_path"}, + {CTSVC_PROPERTY_GROUP_IMAGE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "image_thumbnail_path"}, + {CTSVC_PROPERTY_GROUP_VIBRATION, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "vibration"}, + {CTSVC_PROPERTY_GROUP_SYSTEM_ID, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "system_id"}, + {CTSVC_PROPERTY_GROUP_IS_READ_ONLY, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "is_read_only"}, +}; + +const property_info_s __property_person[] = { + {CTSVC_PROPERTY_PERSON_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "person_id"}, + {CTSVC_PROPERTY_PERSON_DISPLAY_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "name_contact_id"}, + {CTSVC_PROPERTY_PERSON_RINGTONE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "ringtone_path"}, + {CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "image_thumbnail_path"}, + {CTSVC_PROPERTY_PERSON_VIBRATION, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "vibration"}, + {CTSVC_PROPERTY_PERSON_STATUS, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "status"}, + {CTSVC_PROPERTY_PERSON_IS_FAVORITE, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "is_favorite"}, + {CTSVC_PROPERTY_PERSON_FAVORITE_PRIORITY, CTSVC_VIEW_DATA_TYPE_DOUBLE,CTSVC_SEARCH_PROPERTY_FILTER, "favorite_prio"}, + {CTSVC_PROPERTY_PERSON_LINK_COUNT, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "link_count"}, + {CTSVC_PROPERTY_PERSON_ACCOUNT_ID1, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "account_id1"}, + {CTSVC_PROPERTY_PERSON_ACCOUNT_ID2, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "account_id2"}, + {CTSVC_PROPERTY_PERSON_ACCOUNT_ID3, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "account_id3"}, + {CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "addressbook_ids"}, + {CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "has_phonenumber"}, + {CTSVC_PROPERTY_PERSON_HAS_EMAIL, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "has_email"}, +}; + +const property_info_s __property_simple_contact[] = { + {CTSVC_PROPERTY_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_CONTACT_DISPLAY_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "display_name_source"}, + {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_id"}, + {CTSVC_PROPERTY_CONTACT_RINGTONE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "ringtone_path"}, + {CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL,CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "image_thumbnail_path"}, + {CTSVC_PROPERTY_CONTACT_IS_FAVORITE, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "is_favorite"}, + {CTSVC_PROPERTY_CONTACT_HAS_PHONENUMBER,CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "has_phonenumber"}, + {CTSVC_PROPERTY_CONTACT_HAS_EMAIL, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "has_email"}, + {CTSVC_PROPERTY_CONTACT_PERSON_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "person_id"}, + {CTSVC_PROPERTY_CONTACT_UID, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "uid"}, + {CTSVC_PROPERTY_CONTACT_VIBRATION, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "vibration"}, + {CTSVC_PROPERTY_CONTACT_CHANGED_TIME, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "changed_time"}, +}; + +const property_info_s __property_name[] = { + {CTSVC_PROPERTY_NAME_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_NAME_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_NAME_FIRST, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "first"}, + {CTSVC_PROPERTY_NAME_LAST, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "last"}, + {CTSVC_PROPERTY_NAME_ADDITION, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "addition"}, + {CTSVC_PROPERTY_NAME_PREFIX, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "prefix"}, + {CTSVC_PROPERTY_NAME_SUFFIX, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "suffix"}, + {CTSVC_PROPERTY_NAME_PHONETIC_FIRST, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "phonetic_first"}, + {CTSVC_PROPERTY_NAME_PHONETIC_MIDDLE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "phonetic_middle"}, + {CTSVC_PROPERTY_NAME_PHONETIC_LAST, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "phonetic_last"}, +}; + +const property_info_s __property_number[] = { + {CTSVC_PROPERTY_NUMBER_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_NUMBER_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_NUMBER_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "type"}, + {CTSVC_PROPERTY_NUMBER_LABEL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "label"}, + {CTSVC_PROPERTY_NUMBER_IS_DEFAULT, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "is_default"}, + {CTSVC_PROPERTY_NUMBER_NUMBER, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "number"}, +}; + +const property_info_s __property_email[] = { + {CTSVC_PROPERTY_EMAIL_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_EMAIL_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_EMAIL_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "type"}, + {CTSVC_PROPERTY_EMAIL_LABEL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "label"}, + {CTSVC_PROPERTY_EMAIL_IS_DEFAULT, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "is_default"}, + {CTSVC_PROPERTY_EMAIL_EMAIL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "email"}, +}; + +const property_info_s __property_address[] = { + {CTSVC_PROPERTY_ADDRESS_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_ADDRESS_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_ADDRESS_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "type"}, + {CTSVC_PROPERTY_ADDRESS_LABEL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "label"}, + {CTSVC_PROPERTY_ADDRESS_POSTBOX, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "postbox"}, + {CTSVC_PROPERTY_ADDRESS_POSTAL_CODE,CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "postal_code"}, + {CTSVC_PROPERTY_ADDRESS_REGION, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "region"}, + {CTSVC_PROPERTY_ADDRESS_LOCALITY, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "locality"}, + {CTSVC_PROPERTY_ADDRESS_STREET, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "street"}, + {CTSVC_PROPERTY_ADDRESS_COUNTRY, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "country"}, + {CTSVC_PROPERTY_ADDRESS_EXTENDED, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "extend"}, + {CTSVC_PROPERTY_ADDRESS_IS_DEFAULT, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "is_default"}, +}; + +const property_info_s __property_url[] = { + {CTSVC_PROPERTY_URL_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_URL_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_URL_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "type"}, + {CTSVC_PROPERTY_URL_LABEL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "label"}, + {CTSVC_PROPERTY_URL_URL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "url"}, +}; + +const property_info_s __property_event[] = { + {CTSVC_PROPERTY_EVENT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_EVENT_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_EVENT_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "type"}, + {CTSVC_PROPERTY_EVENT_LABEL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "label"}, + {CTSVC_PROPERTY_EVENT_DATE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "date"}, + {CTSVC_PROPERTY_EVENT_IS_LUNAR, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "is_lunar"}, + {CTSVC_PROPERTY_EVENT_LUNAR_DATE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "lunar_date"}, +}; + +const property_info_s __property_group_relation[] = { +// {CTSVC_PROPERTY_GROUP_RELATION_ID, CTSVC_VIEW_DATA_TYPE_INT, "id"}, + {CTSVC_PROPERTY_GROUP_RELATION_GROUP_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "group_id"}, + {CTSVC_PROPERTY_GROUP_RELATION_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_GROUP_RELATION_GROUP_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "group_name"}, +}; + +const property_info_s __property_relationship[] = { + {CTSVC_PROPERTY_RELATIONSHIP_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_RELATIONSHIP_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_RELATIONSHIP_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "type"}, + {CTSVC_PROPERTY_RELATIONSHIP_LABEL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "label"}, + {CTSVC_PROPERTY_RELATIONSHIP_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "name"}, +}; + +const property_info_s __property_image[] = { + {CTSVC_PROPERTY_IMAGE_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_IMAGE_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_IMAGE_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "type"}, + {CTSVC_PROPERTY_IMAGE_LABEL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "label"}, + {CTSVC_PROPERTY_IMAGE_PATH, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "path"}, + {CTSVC_PROPERTY_IMAGE_IS_DEFAULT, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "is_default"}, +}; + +const property_info_s __property_company[] = { + {CTSVC_PROPERTY_COMPANY_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_COMPANY_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_COMPANY_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "type"}, + {CTSVC_PROPERTY_COMPANY_LABEL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "label"}, + {CTSVC_PROPERTY_COMPANY_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "name"}, + {CTSVC_PROPERTY_COMPANY_DEPARTMENT, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "department"}, + {CTSVC_PROPERTY_COMPANY_JOB_TITLE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "job_title"}, + {CTSVC_PROPERTY_COMPANY_ASSISTANT_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "assistant"}, + {CTSVC_PROPERTY_COMPANY_ROLE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "role"}, + {CTSVC_PROPERTY_COMPANY_LOGO, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "logo"}, + {CTSVC_PROPERTY_COMPANY_LOCATION, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "location"}, + {CTSVC_PROPERTY_COMPANY_DESCRIPTION, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "description"}, + {CTSVC_PROPERTY_COMPANY_PHONETIC_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "phonetic_name"}, +}; + +const property_info_s __property_nickname[] = { + {CTSVC_PROPERTY_NICKNAME_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id",}, + {CTSVC_PROPERTY_NICKNAME_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_NICKNAME_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "nickname"}, +}; + +const property_info_s __property_messenger[] = { + {CTSVC_PROPERTY_MESSENGER_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_MESSENGER_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_MESSENGER_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "type"}, + {CTSVC_PROPERTY_MESSENGER_LABEL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "label"}, + {CTSVC_PROPERTY_MESSENGER_IM_ID, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "im_id"}, +}; + +const property_info_s __property_note[] = { + {CTSVC_PROPERTY_NOTE_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_NOTE_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_NOTE_NOTE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "note"}, +}; + +const property_info_s __property_profile[] = { + {CTSVC_PROPERTY_PROFILE_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_PROFILE_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_PROFILE_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "type"}, + {CTSVC_PROPERTY_PROFILE_LABEL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "label"}, + {CTSVC_PROPERTY_PROFILE_UID, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "uid"}, + {CTSVC_PROPERTY_PROFILE_TEXT, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "text"}, + {CTSVC_PROPERTY_PROFILE_ORDER, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "profile_order"}, + {CTSVC_PROPERTY_PROFILE_APPSVC_OPERATION, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "appsvc_op"}, + {CTSVC_PROPERTY_PROFILE_DATA1, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "data1"}, + {CTSVC_PROPERTY_PROFILE_DATA2, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "data2"}, + {CTSVC_PROPERTY_PROFILE_DATA3, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "data3"}, + {CTSVC_PROPERTY_PROFILE_DATA4, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "data4"}, +}; + +const property_info_s __property_activity_photo[] = { + {CTSVC_PROPERTY_ACTIVITY_PHOTO_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_ACTIVITY_PHOTO_ACTIVITY_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "activity_id"}, + {CTSVC_PROPERTY_ACTIVITY_PHOTO_URL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "photo_url"}, + {CTSVC_PROPERTY_ACTIVITY_PHOTO_SORT_INDEX, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "sort_index"}, +}; + +const property_info_s __property_activity[] = { + {CTSVC_PROPERTY_ACTIVITY_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_ACTIVITY_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_ACTIVITY_SOURCE_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "source_name"}, + {CTSVC_PROPERTY_ACTIVITY_STATUS, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "status"}, + {CTSVC_PROPERTY_ACTIVITY_TIMESTAMP, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "timestamp"}, + {CTSVC_PROPERTY_ACTIVITY_SYNC_DATA1, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "sync_data1"}, + {CTSVC_PROPERTY_ACTIVITY_SYNC_DATA2, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "sync_data2"}, + {CTSVC_PROPERTY_ACTIVITY_SYNC_DATA3, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "sync_data3"}, + {CTSVC_PROPERTY_ACTIVITY_SYNC_DATA4, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "sync_data4"}, + {CTSVC_PROPERTY_ACTIVITY_ACTIVITY_PHOTO,CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE, (void*)__property_activity_photo}, +}; + +const property_info_s __property_extension[] = { + {CTSVC_PROPERTY_EXTENSION_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_EXTENSION_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_EXTENSION_DATA1, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "data1"}, + {CTSVC_PROPERTY_EXTENSION_DATA2, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "data2"}, + {CTSVC_PROPERTY_EXTENSION_DATA3, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "data3"}, + {CTSVC_PROPERTY_EXTENSION_DATA4, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "data4"}, + {CTSVC_PROPERTY_EXTENSION_DATA5, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "data5"}, + {CTSVC_PROPERTY_EXTENSION_DATA6, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "data6"}, + {CTSVC_PROPERTY_EXTENSION_DATA7, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "data7"}, + {CTSVC_PROPERTY_EXTENSION_DATA8, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "data8"}, + {CTSVC_PROPERTY_EXTENSION_DATA9, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "data9"}, + {CTSVC_PROPERTY_EXTENSION_DATA10, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "data10"}, + {CTSVC_PROPERTY_EXTENSION_DATA11, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "data11"}, + {CTSVC_PROPERTY_EXTENSION_DATA12, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "data12"}, +}; + +const property_info_s __property_contact[] = { + {CTSVC_PROPERTY_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_CONTACT_DISPLAY_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, NULL}, //dispaly_name, reverse_display_name + {CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "display_name_source"}, + {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_id"}, + {CTSVC_PROPERTY_CONTACT_RINGTONE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "ringtone_path"}, + {CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "image_thumbnail_path"}, + {CTSVC_PROPERTY_CONTACT_IS_FAVORITE, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "is_favorite"}, + {CTSVC_PROPERTY_CONTACT_HAS_PHONENUMBER, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "has_phonenumber"}, + {CTSVC_PROPERTY_CONTACT_HAS_EMAIL, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "has_email"}, + {CTSVC_PROPERTY_CONTACT_PERSON_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "person_id"}, + {CTSVC_PROPERTY_CONTACT_UID, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "uid"}, + {CTSVC_PROPERTY_CONTACT_VIBRATION, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "vibration"}, + {CTSVC_PROPERTY_CONTACT_CHANGED_TIME, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "changed_time"}, + {CTSVC_PROPERTY_CONTACT_NAME, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE, (void*)__property_name}, + {CTSVC_PROPERTY_CONTACT_COMPANY, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_company}, + {CTSVC_PROPERTY_CONTACT_NOTE, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_note}, + {CTSVC_PROPERTY_CONTACT_NUMBER, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_number}, + {CTSVC_PROPERTY_CONTACT_EMAIL, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_email}, + {CTSVC_PROPERTY_CONTACT_EVENT, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_event}, + {CTSVC_PROPERTY_CONTACT_MESSENGER, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_messenger}, + {CTSVC_PROPERTY_CONTACT_ADDRESS, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_address}, + {CTSVC_PROPERTY_CONTACT_URL, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_url}, + {CTSVC_PROPERTY_CONTACT_NICKNAME, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_nickname}, + {CTSVC_PROPERTY_CONTACT_PROFILE, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_profile}, + {CTSVC_PROPERTY_CONTACT_RELATIONSHIP, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_relationship}, + {CTSVC_PROPERTY_CONTACT_IMAGE, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_image}, + {CTSVC_PROPERTY_CONTACT_GROUP_RELATION, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_group_relation}, + {CTSVC_PROPERTY_CONTACT_EXTENSION, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_extension}, +}; + +const property_info_s __property_my_profile[] = { + {CTSVC_PROPERTY_MY_PROFILE_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "my_profile_id"}, + {CTSVC_PROPERTY_MY_PROFILE_DISPLAY_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, NULL}, //dispaly_name, reverse_display_name + {CTSVC_PROPERTY_MY_PROFILE_ADDRESSBOOK_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_id"}, + {CTSVC_PROPERTY_MY_PROFILE_IMAGE_THUMBNAIL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "image_thumbnail_path"}, + {CTSVC_PROPERTY_MY_PROFILE_UID, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "uid"}, + {CTSVC_PROPERTY_MY_PROFILE_CHANGED_TIME, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "changed_time"}, + {CTSVC_PROPERTY_MY_PROFILE_NAME, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE, (void*)__property_name}, + {CTSVC_PROPERTY_MY_PROFILE_COMPANY, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_company}, + {CTSVC_PROPERTY_MY_PROFILE_NOTE, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_note}, + {CTSVC_PROPERTY_MY_PROFILE_NUMBER, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_number}, + {CTSVC_PROPERTY_MY_PROFILE_EMAIL, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_email}, + {CTSVC_PROPERTY_MY_PROFILE_EVENT, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_event}, + {CTSVC_PROPERTY_MY_PROFILE_MESSENGER, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_messenger}, + {CTSVC_PROPERTY_MY_PROFILE_ADDRESS, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_address}, + {CTSVC_PROPERTY_MY_PROFILE_URL, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_url}, + {CTSVC_PROPERTY_MY_PROFILE_NICKNAME, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_nickname}, + {CTSVC_PROPERTY_MY_PROFILE_PROFILE, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_profile}, + {CTSVC_PROPERTY_MY_PROFILE_RELATIONSHIP, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_relationship}, + {CTSVC_PROPERTY_MY_PROFILE_IMAGE, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_image}, + {CTSVC_PROPERTY_MY_PROFILE_EXTENSION, CTSVC_VIEW_DATA_TYPE_REC, CTSVC_SEARCH_PROPERTY_NONE,(void*)__property_extension}, +}; + + +const property_info_s __property_speeddial[] = { + {CTSVC_PROPERTY_SPEEDDIAL_DIAL_NUMBER, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "speed_number"}, + {CTSVC_PROPERTY_SPEEDDIAL_NUMBER_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "number_id"}, + {CTSVC_PROPERTY_SPEEDDIAL_NUMBER, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "number"}, + {CTSVC_PROPERTY_SPEEDDIAL_NUMBER_LABEL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "label"}, + {CTSVC_PROPERTY_SPEEDDIAL_NUMBER_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "type"}, + {CTSVC_PROPERTY_SPEEDDIAL_PERSON_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "person_id"}, + {CTSVC_PROPERTY_SPEEDDIAL_DISPLAY_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, NULL}, // display_name or reverse_display_name + {CTSVC_PROPERTY_SPEEDDIAL_IMAGE_THUMBNAIL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "image_thumbnail_path"}, +}; + +const property_info_s __property_phonelog[] = { + {CTSVC_PROPERTY_PHONELOG_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_PHONELOG_PERSON_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "person_id"}, + {CTSVC_PROPERTY_PHONELOG_ADDRESS, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "number"}, + {CTSVC_PROPERTY_PHONELOG_LOG_TIME, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "log_time"}, + {CTSVC_PROPERTY_PHONELOG_LOG_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "log_type"}, + {CTSVC_PROPERTY_PHONELOG_EXTRA_DATA1, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "data1"}, // duration + {CTSVC_PROPERTY_PHONELOG_EXTRA_DATA2, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "data2"}, // short message, email subject +}; + +const property_info_s __property_updated_info[] = { + {CTSVC_PROPERTY_UPDATE_INFO_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_UPDATE_INFO_ADDRESSBOOK_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_id"}, + {CTSVC_PROPERTY_UPDATE_INFO_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "type"}, + {CTSVC_PROPERTY_UPDATE_INFO_VERSION, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "version"}, +}; + +const property_info_s __property_grouprel_updated_info[] = { + {CTSVC_PROPERTY_GROUP_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "group_id"}, + {CTSVC_PROPERTY_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_ADDRESSBOOK_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_id"}, + {CTSVC_PROPERTY_UPDATE_INFO_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "type"}, + {CTSVC_PROPERTY_UPDATE_INFO_VERSION, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "version"}, +}; + +// search properties /////////////////////////////////////////////////////////////////////////////////////////////////// +const property_info_s __property_person_contact[] = { // _contacts_person_contact + {CTSVC_PROPERTY_PERSON_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "person_id"}, + {CTSVC_PROPERTY_PERSON_DISPLAY_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_PROJECTION, "name_contact_id"}, + {CTSVC_PROPERTY_PERSON_RINGTONE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "ringtone_path"}, + {CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "image_thumbnail_path"}, + {CTSVC_PROPERTY_PERSON_VIBRATION, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "vibration"}, + {CTSVC_PROPERTY_PERSON_STATUS, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "status"}, + {CTSVC_PROPERTY_PERSON_IS_FAVORITE, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "is_favorite"}, + {CTSVC_PROPERTY_PERSON_LINK_COUNT, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "link_count"}, + {CTSVC_PROPERTY_PERSON_ACCOUNT_ID1, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "account_id1"}, + {CTSVC_PROPERTY_PERSON_ACCOUNT_ID2, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "account_id2"}, + {CTSVC_PROPERTY_PERSON_ACCOUNT_ID3, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "account_id3"}, + {CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "addressbook_ids"}, + {CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "has_phonenumber"}, + {CTSVC_PROPERTY_PERSON_HAS_EMAIL, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "has_email"}, + // contact + {CTSVC_PROPERTY_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_id"}, + // addressbook + {CTSVC_PROPERTY_ADDRESSBOOK_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_name"}, + {CTSVC_PROPERTY_ADDRESSBOOK_MODE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_mode"}, +}; + +const property_info_s __property_person_number[] = { // _contacts_person_number + {CTSVC_PROPERTY_PERSON_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "person_id"}, + {CTSVC_PROPERTY_PERSON_DISPLAY_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_PROJECTION, "name_contact_id"}, + {CTSVC_PROPERTY_PERSON_RINGTONE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "ringtone_path"}, + {CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "image_thumbnail_path"}, + {CTSVC_PROPERTY_PERSON_VIBRATION, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "vibration"}, + {CTSVC_PROPERTY_PERSON_IS_FAVORITE, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "is_favorite"}, + {CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "has_phonenumber"}, + {CTSVC_PROPERTY_PERSON_HAS_EMAIL, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "has_email"}, + // number + {CTSVC_PROPERTY_NUMBER_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "number_id"}, + {CTSVC_PROPERTY_DATA_IS_PRIMARY_DEFAULT, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "is_primary_default"}, + {CTSVC_PROPERTY_NUMBER_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_PROJECTION, "type"}, + {CTSVC_PROPERTY_NUMBER_LABEL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "label"}, + {CTSVC_PROPERTY_NUMBER_NUMBER, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "number"}, + {CTSVC_PROPERTY_NUMBER_NUMBER_FILTER, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_FILTER, "normalized_number"}, +}; + +const property_info_s __property_person_email[] = { // _contacts_person_email + {CTSVC_PROPERTY_PERSON_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "person_id"}, + {CTSVC_PROPERTY_PERSON_DISPLAY_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_PROJECTION, "name_contact_id"}, + {CTSVC_PROPERTY_PERSON_RINGTONE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "ringtone_path"}, + {CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "image_thumbnail_path"}, + {CTSVC_PROPERTY_PERSON_VIBRATION, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "vibration"}, + {CTSVC_PROPERTY_PERSON_IS_FAVORITE, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "is_favorite"}, + {CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "has_phonenumber"}, + {CTSVC_PROPERTY_PERSON_HAS_EMAIL, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "has_email"}, + // email + {CTSVC_PROPERTY_EMAIL_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "email_id"}, + {CTSVC_PROPERTY_EMAIL_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_PROJECTION, "type"}, + {CTSVC_PROPERTY_EMAIL_LABEL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "label"}, + {CTSVC_PROPERTY_DATA_IS_PRIMARY_DEFAULT, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "is_primary_default"}, + {CTSVC_PROPERTY_EMAIL_EMAIL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "email"}, +}; + +const property_info_s __property_person_grouprel[] = { // _contacts_person_grouprel + {CTSVC_PROPERTY_PERSON_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "person_id"}, + {CTSVC_PROPERTY_PERSON_DISPLAY_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_PROJECTION, "name_contact_id"}, + {CTSVC_PROPERTY_PERSON_RINGTONE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "ringtone_path"}, + {CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "image_thumbnail_path"}, + {CTSVC_PROPERTY_PERSON_VIBRATION, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "vibration"}, + {CTSVC_PROPERTY_PERSON_STATUS, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "status"}, + {CTSVC_PROPERTY_PERSON_IS_FAVORITE, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "is_favorite"}, + {CTSVC_PROPERTY_PERSON_LINK_COUNT, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "link_count"}, + {CTSVC_PROPERTY_PERSON_ACCOUNT_ID1, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "account_id1"}, + {CTSVC_PROPERTY_PERSON_ACCOUNT_ID2, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "account_id2"}, + {CTSVC_PROPERTY_PERSON_ACCOUNT_ID3, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "account_id3"}, + {CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "addressbook_ids"}, + {CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "has_phonenumber"}, + {CTSVC_PROPERTY_PERSON_HAS_EMAIL, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "has_email"}, + // contacts + {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_id"}, + // group relation + {CTSVC_PROPERTY_GROUP_RELATION_GROUP_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "group_id"}, + // addressbook + {CTSVC_PROPERTY_ADDRESSBOOK_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_name"}, + {CTSVC_PROPERTY_ADDRESSBOOK_MODE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_mode"}, + {CTSVC_PROPERTY_GROUP_RELATION_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_PROJECTION, "contact_id"}, +}; + +const property_info_s __property_person_phonelog[] = { // _contacts_person_phone_log + {CTSVC_PROPERTY_PERSON_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "id"}, + {CTSVC_PROPERTY_PERSON_DISPLAY_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "image_thumbnail_path"}, + // phonelog + {CTSVC_PROPERTY_PHONELOG_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "phonelog_id"}, + {CTSVC_PROPERTY_PHONELOG_ADDRESS, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "address"}, + {CTSVC_PROPERTY_DATA_DATA1, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_PROJECTION, "address_type"}, + {CTSVC_PROPERTY_PHONELOG_LOG_TIME, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "log_time"}, + {CTSVC_PROPERTY_PHONELOG_LOG_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "log_type"}, + {CTSVC_PROPERTY_PHONELOG_EXTRA_DATA1, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_PROJECTION, "data1"}, // duration + {CTSVC_PROPERTY_PHONELOG_EXTRA_DATA2, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "data2"}, // message_id +}; + +const property_info_s __property_person_usage[] = { // _contacts_person_usage + {CTSVC_PROPERTY_PERSON_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "person_id"}, + {CTSVC_PROPERTY_PERSON_DISPLAY_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_PERSON_DISPLAY_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_PROJECTION, "name_contact_id"}, + {CTSVC_PROPERTY_PERSON_RINGTONE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "ringtone_path"}, + {CTSVC_PROPERTY_PERSON_IMAGE_THUMBNAIL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "image_thumbnail_path"}, + {CTSVC_PROPERTY_PERSON_VIBRATION, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "vibration"}, + {CTSVC_PROPERTY_PERSON_IS_FAVORITE, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "is_favorite"}, + {CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "has_phonenumber"}, + {CTSVC_PROPERTY_PERSON_HAS_EMAIL, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "has_email"}, + // contact_stat + {CTSVC_PROPERTY_PERSON_USAGE_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "usage_type"}, + {CTSVC_PROPERTY_PERSON_TIMES_USED, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "times_used"}, +}; + +const property_info_s __property_contact_number[] = { // _contacts_contact_number + {CTSVC_PROPERTY_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_CONTACT_DISPLAY_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_PROJECTION, "display_name_source"}, + {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_id"}, + {CTSVC_PROPERTY_CONTACT_PERSON_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "person_id"}, + {CTSVC_PROPERTY_CONTACT_RINGTONE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "ringtone_path"}, + {CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL,CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "image_thumbnail_path"}, + // number + {CTSVC_PROPERTY_NUMBER_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "number_id"}, + {CTSVC_PROPERTY_NUMBER_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_PROJECTION, "type"}, + {CTSVC_PROPERTY_NUMBER_LABEL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "label"}, + {CTSVC_PROPERTY_NUMBER_IS_DEFAULT, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "is_default"}, + {CTSVC_PROPERTY_NUMBER_NUMBER, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "number"}, + {CTSVC_PROPERTY_NUMBER_NUMBER_FILTER, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_FILTER, "normalized_number"}, +}; + +const property_info_s __property_contact_email[] = { // _contacts_contact_email + {CTSVC_PROPERTY_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_CONTACT_DISPLAY_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "display_name_source"}, + {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_id"}, + {CTSVC_PROPERTY_CONTACT_PERSON_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "person_id"}, + {CTSVC_PROPERTY_CONTACT_RINGTONE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "ringtone_path"}, + {CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "image_thumbnail_path"}, + // email + {CTSVC_PROPERTY_EMAIL_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "email_id"}, + {CTSVC_PROPERTY_EMAIL_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_PROJECTION, "type"}, + {CTSVC_PROPERTY_EMAIL_LABEL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "label"}, + {CTSVC_PROPERTY_EMAIL_IS_DEFAULT, CTSVC_VIEW_DATA_TYPE_BOOL, CTSVC_SEARCH_PROPERTY_ALL, "is_default"}, + {CTSVC_PROPERTY_EMAIL_EMAIL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "email"}, +}; + +const property_info_s __property_contact_grouprel[] = { // _contacts_contact_grouprel + {CTSVC_PROPERTY_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_CONTACT_DISPLAY_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_PROJECTION, "display_name_source"}, + {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_id"}, + {CTSVC_PROPERTY_CONTACT_PERSON_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "person_id"}, + {CTSVC_PROPERTY_CONTACT_RINGTONE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "ringtone_path"}, + {CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "image_thumbnail_path"}, + // group relation + {CTSVC_PROPERTY_GROUP_RELATION_GROUP_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "group_id"}, + {CTSVC_PROPERTY_GROUP_RELATION_GROUP_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "group_name"}, +}; + +const property_info_s __property_contact_activity[] = { // _contacts_contact_activity + {CTSVC_PROPERTY_CONTACT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "contact_id"}, + {CTSVC_PROPERTY_CONTACT_DISPLAY_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, NULL}, // "dispaly_name" or "reverse_dispaly_name" + {CTSVC_PROPERTY_CONTACT_DISPLAY_SOURCE_DATA_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_PROJECTION, "display_name_source"}, + {CTSVC_PROPERTY_CONTACT_ADDRESSBOOK_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "addressbook_id"}, + {CTSVC_PROPERTY_CONTACT_PERSON_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "person_id"}, + {CTSVC_PROPERTY_CONTACT_RINGTONE, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "ringtone_path"}, + {CTSVC_PROPERTY_CONTACT_IMAGE_THUMBNAIL, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "image_thumbnail_path"}, + {CTSVC_PROPERTY_ACTIVITY_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "activity_id"}, + {CTSVC_PROPERTY_ACTIVITY_SOURCE_NAME, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "source_name"}, + {CTSVC_PROPERTY_ACTIVITY_STATUS, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "status"}, + {CTSVC_PROPERTY_ACTIVITY_TIMESTAMP, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "timestamp"}, + {CTSVC_PROPERTY_ACTIVITY_SYNC_DATA1, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "sync_data1"}, + {CTSVC_PROPERTY_ACTIVITY_SYNC_DATA2, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "sync_data2"}, + {CTSVC_PROPERTY_ACTIVITY_SYNC_DATA3, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "sync_data3"}, + {CTSVC_PROPERTY_ACTIVITY_SYNC_DATA4, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_PROJECTION, "sync_data4"}, + {CTSVC_PROPERTY_ADDRESSBOOK_ACCOUNT_ID, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "account_id"}, +}; + +const property_info_s __property_phonelog_number[] = { //_contacts_phone_log_number + {CTSVC_PROPERTY_PHONELOG_ADDRESS, CTSVC_VIEW_DATA_TYPE_STR, CTSVC_SEARCH_PROPERTY_ALL, "number"}, +}; + +const property_info_s __property_phonelog_stat[] = { //_contacts_phone_log_stat + {CTSVC_PROPERTY_PHONELOG_STAT_LOG_COUNT, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_PROJECTION, "log_count"}, + {CTSVC_PROPERTY_PHONELOG_STAT_LOG_TYPE, CTSVC_VIEW_DATA_TYPE_INT, CTSVC_SEARCH_PROPERTY_ALL, "log_type"}, +}; + +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)}, + {CTSVC_VIEW_URI_PHONELOG, CTSVC_RECORD_PHONELOG, PTR_COUNT(__property_phonelog)}, + {CTSVC_VIEW_URI_SPEEDDIAL, CTSVC_RECORD_SPEEDDIAL, PTR_COUNT(__property_speeddial)}, + {CTSVC_VIEW_URI_SDN, CTSVC_RECORD_SDN, PTR_COUNT(__property_snd)}, + + {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, PTR_COUNT(__property_updated_info)}, + {CTSVC_VIEW_URI_GROUPS_MEMBER_UPDATED_INFO, CTSVC_RECORD_UPDATED_INFO, PTR_COUNT(__property_updated_info)}, + {CTSVC_VIEW_URI_CONTACTS_UPDATED_INFO, CTSVC_RECORD_UPDATED_INFO, PTR_COUNT(__property_updated_info)}, + {CTSVC_VIEW_URI_GROUPRELS_UPDATED_INFO, CTSVC_RECORD_RESULT, PTR_COUNT(__property_grouprel_updated_info)}, + + {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_PHONELOG, CTSVC_RECORD_RESULT, PTR_COUNT(__property_person_phonelog)}, + {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)}, + {CTSVC_VIEW_URI_READ_ONLY_PHONELOG_NUMBER, CTSVC_RECORD_RESULT, PTR_COUNT(__property_phonelog_number)}, + {CTSVC_VIEW_URI_READ_ONLY_PHONELOG_STAT, CTSVC_RECORD_RESULT, PTR_COUNT(__property_phonelog_stat)}, +}; + +static GHashTable *__ctsvc_view_uri_hash = NULL; + +void ctsvc_view_uri_init() +{ + int i; + if (__ctsvc_view_uri_hash) + return; + + __ctsvc_view_uri_hash = g_hash_table_new(g_str_hash, g_str_equal); + + i = 0; + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_ADDRESSBOOK, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_GROUP, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_PERSON, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_SIMPLE_CONTACT, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_CONTACT, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_MY_PROFILE, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_ACTIVITY, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_ACTIVITY_PHOTO, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_PHONELOG, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_SPEEDDIAL, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_SDN, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_NAME, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_COMPANY, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_NUMBER, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_EMAIL, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_URL, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_ADDRESS, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_PROFILE, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_RELATIONSHIP, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_IMAGE, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_NOTE, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_NICKNAME, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_EVENT, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_MESSENGER, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_GROUP_RELATION, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_EXTENSION, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_GROUPS_UPDATED_INFO, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_GROUPS_MEMBER_UPDATED_INFO, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_CONTACTS_UPDATED_INFO, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_GROUPRELS_UPDATED_INFO, GINT_TO_POINTER(&__tables[i++])); + + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_READ_ONLY_PERSON_CONTACT, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_READ_ONLY_PERSON_NUMBER, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_READ_ONLY_PERSON_EMAIL, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_READ_ONLY_PERSON_PHONELOG, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_READ_ONLY_PERSON_USAGE, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_READ_ONLY_CONTACT_NUMBER, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_READ_ONLY_CONTACT_EMAIL, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_READ_ONLY_CONTACT_GROUP, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_READ_ONLY_CONTACT_ACTIVITY, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_READ_ONLY_PHONELOG_NUMBER, GINT_TO_POINTER(&__tables[i++])); + g_hash_table_insert(__ctsvc_view_uri_hash, CTSVC_VIEW_URI_READ_ONLY_PHONELOG_STAT, GINT_TO_POINTER(&__tables[i++])); +} + +void ctsvc_view_uri_deinit() +{ +#if 0 + if (NULL == __ctsvc_view_uri_hash) + ASSERT_NOT_REACHED("__ctsvc_view_uri_hash is NULL"); + + 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) { + ASSERT_NOT_REACHED("__ctsvc_view_uri_hash is NULL"); + } + + 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) { + ASSERT_NOT_REACHED("__ctsvc_view_uri_hash is 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) { + ASSERT_NOT_REACHED("__ctsvc_view_uri_hash is 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 index 0000000..7dd1fd8 --- /dev/null +++ b/common/ctsvc_view.h @@ -0,0 +1,461 @@ +/* + * 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_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_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_NUMBER "tizen.contacts_view.phonelog/number" +#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_WRIET_ONCE_PROPERTY 0x00002000 + +#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_SYSTEM_ID = (CTSVC_PROPERTY_GROUP | CTSVC_VIEW_DATA_TYPE_STR) +6, + CTSVC_PROPERTY_GROUP_IS_READ_ONLY = (CTSVC_PROPERTY_GROUP | CTSVC_VIEW_DATA_TYPE_BOOL | CTSVC_READ_ONLY_PROPERTY) +7, + + // 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) +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_ACCOUNT_ID1 = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY) +9, + CTSVC_PROPERTY_PERSON_ACCOUNT_ID2 = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY) +10, + CTSVC_PROPERTY_PERSON_ACCOUNT_ID3 = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY) +11, + CTSVC_PROPERTY_PERSON_ADDRESSBOOK_IDS = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +12, + CTSVC_PROPERTY_PERSON_HAS_PHONENUMBER = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_BOOL | CTSVC_READ_ONLY_PROPERTY) +13, + CTSVC_PROPERTY_PERSON_HAS_EMAIL = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_BOOL | CTSVC_READ_ONLY_PROPERTY) +14, + CTSVC_PROPERTY_PERSON_DISPLAY_NAME_INDEX = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +15, + CTSVC_PROPERTY_PERSON_STATUS = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_STR | CTSVC_READ_ONLY_PROPERTY) +16, + // person-stat + CTSVC_PROPERTY_PERSON_USAGE_TYPE = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_INT) +17, + CTSVC_PROPERTY_PERSON_TIMES_USED = (CTSVC_PROPERTY_PERSON | CTSVC_VIEW_DATA_TYPE_INT) +18, + + // 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) +6, + CTSVC_PROPERTY_CONTACT_IS_FAVORITE = (CTSVC_PROPERTY_CONTACT | CTSVC_VIEW_DATA_TYPE_BOOL | CTSVC_READ_ONLY_PROPERTY) +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 | CTSVC_READ_ONLY_PROPERTY) +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, + + // 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) +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, + + // 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_STR) +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_IS_LUNAR = (CTSVC_PROPERTY_EVENT | CTSVC_VIEW_DATA_TYPE_BOOL) +5, + CTSVC_PROPERTY_EVENT_LUNAR_DATE = (CTSVC_PROPERTY_EVENT | CTSVC_VIEW_DATA_TYPE_INT) +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_ASSISTANT_NAME = (CTSVC_PROPERTY_COMPANY | CTSVC_VIEW_DATA_TYPE_STR) +7, + CTSVC_PROPERTY_COMPANY_ROLE = (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_TYPE = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_INT) +2, + CTSVC_PROPERTY_PROFILE_LABEL = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +3, + CTSVC_PROPERTY_PROFILE_UID = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +4, + CTSVC_PROPERTY_PROFILE_TEXT = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +5, + CTSVC_PROPERTY_PROFILE_ORDER = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_INT) +6, + CTSVC_PROPERTY_PROFILE_APPSVC_OPERATION = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +7, + CTSVC_PROPERTY_PROFILE_DATA1 = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +8, + CTSVC_PROPERTY_PROFILE_DATA2 = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +9, + CTSVC_PROPERTY_PROFILE_DATA3 = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +10, + CTSVC_PROPERTY_PROFILE_DATA4 = (CTSVC_PROPERTY_PROFILE | CTSVC_VIEW_DATA_TYPE_STR) +11, + + // 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_SYNC_DATA1 = (CTSVC_PROPERTY_ACTIVITY | CTSVC_VIEW_DATA_TYPE_STR) +5, + CTSVC_PROPERTY_ACTIVITY_SYNC_DATA2 = (CTSVC_PROPERTY_ACTIVITY | CTSVC_VIEW_DATA_TYPE_STR) +6, + CTSVC_PROPERTY_ACTIVITY_SYNC_DATA3 = (CTSVC_PROPERTY_ACTIVITY | CTSVC_VIEW_DATA_TYPE_STR) +7, + CTSVC_PROPERTY_ACTIVITY_SYNC_DATA4 = (CTSVC_PROPERTY_ACTIVITY | CTSVC_VIEW_DATA_TYPE_STR) +8, + CTSVC_PROPERTY_ACTIVITY_ACTIVITY_PHOTO = (CTSVC_PROPERTY_ACTIVITY | CTSVC_VIEW_DATA_TYPE_REC) +9, + + // 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_INT | CTSVC_READ_ONLY_PROPERTY) +2, + CTSVC_PROPERTY_SPEEDDIAL_NUMBER_LABEL = (CTSVC_PROPERTY_SPEEDDIAL | CTSVC_VIEW_DATA_TYPE_INT | 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_INT | CTSVC_READ_ONLY_PROPERTY) +6, + CTSVC_PROPERTY_SPEEDDIAL_IMAGE_THUMBNAIL = (CTSVC_PROPERTY_SPEEDDIAL | CTSVC_VIEW_DATA_TYPE_INT | CTSVC_READ_ONLY_PROPERTY) +7, + + // 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 + + // contact_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, + + // 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) +1, + CTSVC_PROPERTY_SDN_NUMBER = (CTSVC_PROPERTY_SDN | CTSVC_VIEW_DATA_TYPE_STR) +2, + + // 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, + +}cts_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 index 0000000..7f9a708 --- /dev/null +++ b/common/ipc/ctsvc_ipc_activity.c @@ -0,0 +1,79 @@ +#include "ctsvc_ipc_macros.h" + +#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_NO_DATA); + RETV_IF(record==NULL,CONTACTS_ERROR_NO_DATA); + + 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->sync_data1) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_string(ipc_data, &activity_p->sync_data2) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_string(ipc_data, &activity_p->sync_data3) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_string(ipc_data, &activity_p->sync_data4) != CONTACTS_ERROR_NONE) break; + + if (ctsvc_ipc_unmarshal_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->sync_data1),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_string((activity_p->sync_data2),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_string((activity_p->sync_data3),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_string((activity_p->sync_data4),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 index 0000000..cec4264 --- /dev/null +++ b/common/ipc/ctsvc_ipc_activity_photo.c @@ -0,0 +1,65 @@ +#include "ctsvc_ipc_macros.h" + +#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 index 0000000..4acdd9a --- /dev/null +++ b/common/ipc/ctsvc_ipc_address.c @@ -0,0 +1,80 @@ +#include "ctsvc_ipc_macros.h" + +#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 index 0000000..30bbab2 --- /dev/null +++ b/common/ipc/ctsvc_ipc_addressbook.c @@ -0,0 +1,63 @@ +#include "ctsvc_ipc_macros.h" + +#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 index 0000000..622068b --- /dev/null +++ b/common/ipc/ctsvc_ipc_company.c @@ -0,0 +1,85 @@ +#include "ctsvc_ipc_macros.h" + + +#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_bool(ipc_data, &company_p->logo_changed) != CONTACTS_ERROR_NONE) break; + 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_bool((company_p->logo_changed),ipc_data) != CONTACTS_ERROR_NONE) break; + 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 index 0000000..1b1b71b --- /dev/null +++ b/common/ipc/ctsvc_ipc_contact.c @@ -0,0 +1,140 @@ +#include "ctsvc_ipc_macros.h" + + +#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->display_name_changed) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_bool(ipc_data, &pcontact->uid_changed) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_bool(ipc_data, &pcontact->image_thumbnail_changed) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_bool(ipc_data, &pcontact->ringtone_changed) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_bool(ipc_data, &pcontact->vibration_changed) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_bool(ipc_data, &pcontact->is_restricted) != CONTACTS_ERROR_NONE) break; + 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->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_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->sync_data1) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->sync_data2) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->sync_data3) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_string(ipc_data, &pcontact->sync_data4) != CONTACTS_ERROR_NONE) break; + + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pcontact->name) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pcontact->note) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pcontact->company) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pcontact->numbers) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pcontact->emails) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pcontact->grouprelations) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pcontact->events) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pcontact->messengers) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pcontact->postal_addrs) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pcontact->urls) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pcontact->nicknames) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pcontact->profiles) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pcontact->relationships) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pcontact->images) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_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->display_name_changed),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_bool((pcontact->uid_changed),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_bool((pcontact->image_thumbnail_changed),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_bool((pcontact->ringtone_changed),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_bool((pcontact->vibration_changed),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_bool((pcontact->is_restricted),ipc_data) != CONTACTS_ERROR_NONE) break; + 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->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_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->sync_data1),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_string((pcontact->sync_data2),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_string((pcontact->sync_data3),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_string((pcontact->sync_data4),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 index 0000000..84b0d54 --- /dev/null +++ b/common/ipc/ctsvc_ipc_define.h @@ -0,0 +1,81 @@ +/* + * Calendar 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 "/opt/usr/data/contacts-svc/."CTSVC_IPC_SERVICE + +#define CTSVC_IPC_SOCKET_PATH_FOR_CHANGE_SUBSCRIPTION "/opt/usr/data/contacts-svc/."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_SERVER_CONNECT "connect" +#define CTSVC_IPC_SERVER_DISCONNECT "disconnect" + +#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_QUERY "search_records_with_query" + +#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_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_SIM_IMPORT_ALL_CONTACTS "sim_import_all_contacts" +#define CTSVC_IPC_SERVER_SIM_EXPORT_PERSON "sim_export_person" +#define CTSVC_IPC_SERVER_SIM_INSERT_CONTACT "sim_insert_contact" +#define CTSVC_IPC_SERVER_SIM_UPDATE_CONTACT "sim_update_contact" +#define CTSVC_IPC_SERVER_SIM_DELETE_CONTACT "sim_delete_contact" + +#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 index 0000000..d6a3517 --- /dev/null +++ b/common/ipc/ctsvc_ipc_email.c @@ -0,0 +1,68 @@ +#include "ctsvc_ipc_macros.h" + + +#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 index 0000000..acf76fc --- /dev/null +++ b/common/ipc/ctsvc_ipc_event.c @@ -0,0 +1,64 @@ +#include "ctsvc_ipc_macros.h" + + +#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; + + 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; + + 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 index 0000000..c69c163 --- /dev/null +++ b/common/ipc/ctsvc_ipc_extension.c @@ -0,0 +1,86 @@ +#include "ctsvc_ipc_macros.h" + + + +#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 index 0000000..35efe16 --- /dev/null +++ b/common/ipc/ctsvc_ipc_group.c @@ -0,0 +1,72 @@ +#include "ctsvc_ipc_macros.h" + +#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->system_id) != 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->image_thumbnail_path) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_bool(ipc_data, &group_p->image_thumbnail_changed) != 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->system_id),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->image_thumbnail_path),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_bool((group_p->image_thumbnail_changed),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 index 0000000..a7ac312 --- /dev/null +++ b/common/ipc/ctsvc_ipc_grouprelation.c @@ -0,0 +1,64 @@ +#include "ctsvc_ipc_macros.h" + + +#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 index 0000000..96b605e --- /dev/null +++ b/common/ipc/ctsvc_ipc_image.c @@ -0,0 +1,68 @@ +#include "ctsvc_ipc_macros.h" + + +#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_bool(ipc_data, &image_p->is_changed) != CONTACTS_ERROR_NONE) break; + 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_bool((image_p->is_changed),ipc_data) != CONTACTS_ERROR_NONE) break; + 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_macros.h b/common/ipc/ctsvc_ipc_macros.h new file mode 100644 index 0000000..8673a22 --- /dev/null +++ b/common/ipc/ctsvc_ipc_macros.h @@ -0,0 +1,173 @@ +#ifndef __CTSVC_IPC_MACROS_H__ +#define __CTSVC_IPC_MACROS_H__ + +#include <pims-ipc.h> +#include <pims-ipc-data.h> +#include <stdbool.h> + +#define CTSVC_IPC_PREPARE() \ + char __handle_str[1024] = {0, }; \ + snprintf(__handle_str, sizeof(__handle_str), \ + "/opt/CONTACT_SVC_IPC_HANDLE/handle_%d", \ + getpid()); + +#define CTSVC_IPC_SETUP(type) \ + pims_ipc_h __IPC_HANDLE__ = pims_ipc_create(__handle_str); \ + pims_ipc_data_h __IPC_DATA_IN_HANDLE__ = pims_ipc_data_create(type); \ + pims_ipc_data_h __IPC_DATA_OUT_HANDLE__ = NULL; + +#define CTSVC_IPC_CALL(MODULE, FUNCTION) \ + pims_ipc_call(__IPC_HANDLE__, MODULE, FUNCTION, __IPC_DATA_IN_HANDLE__, &(__IPC_DATA_OUT_HANDLE__) ); + +#define CTSVC_IPC_ASYNC_CALL(MODULE, FUNCTION, CALLBACK, USERPARAM) \ + pims_ipc_call(__IPC_HANDLE__, MODULE, FUNCTION, __IPC_DATA_IN_HANDLE__, CALLBACK, USERPARAM ); + +#define CTSVC_IPC_DATA_IN_WITH_TYPE(type, in_param) \ + pims_ipc_data_put_with_type_##type(__IPC_DATA_IN_HANDLE__, in_param); + +#define CTSVC_IPC_DATA_OUT_WITH_TYPE(type, out_param) \ + pims_ipc_data_get_with_type_##type(__IPC_DATA_OUT_HANDLE__, &out_param); + +#define CTSVC_IPC_DATA_OUT_DUP_WITH_TYPE(type, out_param) \ + pims_ipc_data_get_with_type_##type_dup(__IPC_DATA_OUT_HANDLE__, &out_param); + +#define CTSVC_IPC_CALL_INSERT(RECORD_TYPE) CTSVC_IPC_CALL("INSERT", RECORD_TYPE) +#define CTSVC_IPC_CALL_UPDATE(RECORD_TYPE) CTSVC_IPC_CALL("UPDATE", RECORD_TYPE) +#define CTSVC_IPC_CALL_DELETE(RECORD_TYPE) CTSVC_IPC_CALL("DELETE", RECORD_TYPE) +#define CTSVC_IPC_CALL_GET(RECORD_TYPE) CTSVC_IPC_CALL("GET_RECORD", RECORD_TYPE) +#define CTSVC_IPC_CALL_GET_ALL(RECORD_TYPE) CTSVC_IPC_CALL("GET_ALL_RECORDS", RECORD_TYPE) +#define CTSVC_IPC_CALL_GET_RECORDS_QUERY(RECORD_TYPE) CTSVC_IPC_CALL("GET_RECORDS_QUERY", RECORD_TYPE) +#define CTSVC_IPC_CALL_INSERT_RECORDS(RECORD_TYPE) CTSVC_IPC_CALL("INSERT_RECORDS", RECORD_TYPE) +#define CTSVC_IPC_CALL_UPDATE_RECORDS(RECORD_TYPE) CTSVC_IPC_CALL("UPDATE_RECORDS", RECORD_TYPE) +#define CTSVC_IPC_CALL_DELETE_RECORDS(RECORD_TYPE) CTSVC_IPC_CALL("DELETE_RECORDS", RECORD_TYPE) + +#define CTSVC_IPC_TEARDOWN() \ + pims_ipc_data_destroy(__IPC_DATA_OUT_HANDLE__); \ + pims_ipc_data_destroy(__IPC_DATA_IN_HANDLE__); \ + pims_ipc_destroy(__IPC_HANDLE__); + + +#define pims_ipc_data_put_with_type_char(data, buf) \ + do { char __tmp = buf; \ + pims_ipc_data_put_with_type(data, PIMS_IPC_DATA_TYPE_CHAR, (void*)&__tmp, 0); } while(0) +#define pims_ipc_data_put_with_type_bool(data, buf) \ + do { bool __tmp = buf; \ + pims_ipc_data_put_with_type(data, PIMS_IPC_DATA_TYPE_INT, (void*)&__tmp, 0); }while(0) +#define pims_ipc_data_put_with_type_int(data, buf) \ + do { int __tmp = buf; \ + pims_ipc_data_put_with_type(data, PIMS_IPC_DATA_TYPE_INT, (void*)&__tmp, 0); } while(0) +#define pims_ipc_data_put_with_type_uint(data, buf) \ + do { unsigned int __tmp = buf; \ + pims_ipc_data_put_with_type(data, PIMS_IPC_DATA_TYPE_UINT, (void*)&__tmp, 0); } while(0) +#define pims_ipc_data_put_with_type_long(data, buf) \ + do { long __tmp = buf; \ + pims_ipc_data_put_with_type(data, PIMS_IPC_DATA_TYPE_LONG, (void*)&__tmp, 0); } while(0) +#define pims_ipc_data_put_with_type_ulong(data, buf) \ + do { unsigned long __tmp = buf; \ + pims_ipc_data_put_with_type(data, PIMS_IPC_DATA_TYPE_ULONG, (void*)&__tmp, 0); } while(0) +#define pims_ipc_data_put_with_type_double(data, buf) \ + do { double __tmp = buf; \ + pims_ipc_data_put_with_type(data, PIMS_IPC_DATA_TYPE_DOUBLE, (void*)&__tmp, 0); } while(0) +#define pims_ipc_data_put_with_type_string(data, buf) \ + pims_ipc_data_put_with_type(data, PIMS_IPC_DATA_TYPE_STRING, (void*)buf, 0) +#define pims_ipc_data_put_with_type_memory(data, buf, size) \ + pims_ipc_data_put_with_type(data, PIMS_IPC_DATA_TYPE_MEMORY, (void*)buf, size) + + +#define pims_ipc_data_put_bool(data, buf) \ + do { bool __tmp = buf; \ + pims_ipc_data_put(data, (void*)&__tmp, sizeof(int)); }while(0) +#define pims_ipc_data_put_int(data, buf) \ + do { int __tmp = buf; \ + pims_ipc_data_put(data, (void*)&__tmp, sizeof(int)); } while(0) +#define pims_ipc_data_put_string(data, buf) \ + do { \ + if( buf ) \ + pims_ipc_data_put(data, (void*)buf, strlen(buf)+1); \ + else \ + pims_ipc_data_put(data, (void*)"", 0); } while(0) + +static inline void pims_ipc_data_get_with_type_int(pims_ipc_data_h data, int* result) +{ + pims_ipc_data_type_e ipc_dtype = PIMS_IPC_DATA_TYPE_INVALID; + unsigned int ipc_dsize = 0; + + *result = *((int*)pims_ipc_data_get_with_type(data, &ipc_dtype, &ipc_dsize)); +} + +static inline void pims_ipc_data_get_dup_with_type_int(pims_ipc_data_h data, int* result) +{ + pims_ipc_data_type_e ipc_dtype = PIMS_IPC_DATA_TYPE_INVALID; + unsigned int ipc_dsize = 0; + + *result = *((int*) pims_ipc_data_get_dup_with_type(data, &ipc_dtype, &ipc_dsize)); +} + +static inline void pims_ipc_data_get_with_type_bool(pims_ipc_data_h data, bool* result) +{ + pims_ipc_data_type_e ipc_dtype = PIMS_IPC_DATA_TYPE_INVALID; + unsigned int ipc_dsize = 0; + + *result = (bool)(*((int*)pims_ipc_data_get_with_type(data, &ipc_dtype, &ipc_dsize))); +} + +static inline void pims_ipc_data_get_dup_with_type_bool(pims_ipc_data_h data, bool* result) +{ + pims_ipc_data_type_e ipc_dtype = PIMS_IPC_DATA_TYPE_INVALID; + unsigned int ipc_dsize = 0; + + *result = (bool)(*((int*) pims_ipc_data_get_dup_with_type(data, &ipc_dtype, &ipc_dsize))); +} +static inline void pims_ipc_data_get_with_type_string(pims_ipc_data_h data, char** result) +{ + pims_ipc_data_type_e ipc_dtype = PIMS_IPC_DATA_TYPE_INVALID; + unsigned int ipc_dsize = 0; + + *result = (char*)pims_ipc_data_get_with_type(data, &ipc_dtype, &ipc_dsize); +} + +static inline void pims_ipc_data_get_dup_with_type_string(pims_ipc_data_h data, char** result) +{ + pims_ipc_data_type_e ipc_dtype = PIMS_IPC_DATA_TYPE_INVALID; + unsigned int ipc_dsize = 0; + + *result = (char*)pims_ipc_data_get_dup_with_type(data, &ipc_dtype, &ipc_dsize); +} + +static inline void pims_ipc_data_get_int(pims_ipc_data_h data, int* result) +{ + unsigned int ipc_dsize = 0; + *result = *((int*) pims_ipc_data_get(data, &ipc_dsize)); +} + +static inline void pims_ipc_data_get_dup_int(pims_ipc_data_h data, int* result) +{ + unsigned int ipc_dsize = 0; + *result = *((int*) pims_ipc_data_get_dup(data, &ipc_dsize)); +} + +static inline void pims_ipc_data_get_bool(pims_ipc_data_h data, bool* result) +{ + unsigned int ipc_dsize = 0; + *result = (bool)(*((int*)pims_ipc_data_get(data, &ipc_dsize))); +} + +static inline void pims_ipc_data_get_dup_bool(pims_ipc_data_h data, bool* result) +{ + unsigned int ipc_dsize = 0; + *result = (bool)(*((int*)pims_ipc_data_get_dup(data, &ipc_dsize))); +} +static inline void pims_ipc_data_get_string(pims_ipc_data_h data, char** result) +{ + unsigned int ipc_dsize = 0; + *result = (char*)pims_ipc_data_get(data, &ipc_dsize); +} + +static inline void pims_ipc_data_get_dup_string(pims_ipc_data_h data, char** result) +{ + unsigned int ipc_dsize = 0; + *result = (char*)pims_ipc_data_get_dup(data, &ipc_dsize); +} + +#endif /*__CTSVC_IPC_MACROS_H__*/ + diff --git a/common/ipc/ctsvc_ipc_marshal.c b/common/ipc/ctsvc_ipc_marshal.c new file mode 100644 index 0000000..bfbf3f1 --- /dev/null +++ b/common/ipc/ctsvc_ipc_marshal.c @@ -0,0 +1,1237 @@ +/* + * Calendar 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; +extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_phonelog_plugin_cb; +extern ctsvc_ipc_marshal_record_plugin_cb_s _ctsvc_ipc_record_result_plugin_cb; +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; +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); + case CTSVC_RECORD_PHONELOG: + return (&_ctsvc_ipc_record_phonelog_plugin_cb); + case CTSVC_RECORD_SPEEDDIAL: + return (&_ctsvc_ipc_record_speeddial_plugin_cb); + case CTSVC_RECORD_SDN: + return (&_ctsvc_ipc_record_sdn_plugin_cb); + 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("malloc 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("malloc 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,}; + + if (ctsvc_ipc_unmarshal_record_common(ipc_data, &common) != CONTACTS_ERROR_NONE) + { + CTS_ERR("ctsvc_ipc_unmarshal_common fail"); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + RETVM_IF( NULL == precord || NULL == ipc_data, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter"); + + ret = contacts_record_create(common.view_uri, precord); + RETVM_IF(ret != CONTACTS_ERROR_NONE, ret, "create activity record fail"); + + 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->unmarshal_record, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter"); + + 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); + } + CTS_VERBOSE("string set %s",*ppbufchar); + + 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); + common->property_max_count = *(unsigned int*)pims_ipc_data_get(ipc_data,&size); + + tmp = pims_ipc_data_get(ipc_data,&size); + if ( tmp == NULL ){ + CTS_ERR("pims_ipc_data unmarshal fail"); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + int length = *(int*)tmp; + if(length == -1) + { + CTS_VERBOSE("properties_flags is null"); + } + else { + tmp = (unsigned char*)pims_ipc_data_get(ipc_data,&size); + { + common->properties_flags = calloc(common->property_max_count, sizeof(unsigned char)); + if (common->properties_flags == NULL) + { + CTS_ERR("calloc fail"); + return CONTACTS_ERROR_OUT_OF_MEMORY; + } + memcpy(common->properties_flags, tmp, sizeof(unsigned char)*(common->property_max_count)); + } + } + 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 (common->properties_flags != NULL) + { + int length = common->property_max_count; + if (pims_ipc_data_put(ipc_data,(void*)&length,sizeof(int)) != 0) + { + CTS_ERR("_ctsvc_ipc_marshal fail"); + return CONTACTS_ERROR_OUT_OF_MEMORY; + } + 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; + } + } + else + { + int length = -1; + if (pims_ipc_data_put(ipc_data,(void*)&length,sizeof(int)) != 0) + { + CTS_ERR("_ctsvc_ipc_marshal fail"); + return CONTACTS_ERROR_OUT_OF_MEMORY; + } + } + + 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 + { + contacts_filter_h filter = (contacts_filter_h)que->filter; + if (contacts_filter_create(que->view_uri,&filter) != CONTACTS_ERROR_NONE) + { + CTS_ERR("contacts_filter_create fail"); + ret = CONTACTS_ERROR_OUT_OF_MEMORY; + goto ERROR_RETURN; + } + que->filter = (ctsvc_composite_filter_s*)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) +{ + unsigned 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_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++) + { + 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"); + 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 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_marshal_list(const contacts_list_h list, pims_ipc_data_h ipc_data) +{ + unsigned 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 index 0000000..f619a2d --- /dev/null +++ b/common/ipc/ctsvc_ipc_marshal.h @@ -0,0 +1,86 @@ +/* + * Calendar 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_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 index 0000000..4130a88 --- /dev/null +++ b/common/ipc/ctsvc_ipc_messenger.c @@ -0,0 +1,65 @@ +#include "ctsvc_ipc_macros.h" + + +#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 index 0000000..e91f9fc --- /dev/null +++ b/common/ipc/ctsvc_ipc_my_profile.c @@ -0,0 +1,98 @@ +#include "ctsvc_ipc_macros.h" + + +#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->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_list(ipc_data, (contacts_list_h*)&pmy_profile->name) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pmy_profile->note) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pmy_profile->company) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pmy_profile->numbers) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pmy_profile->emails) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pmy_profile->events) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pmy_profile->messengers) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pmy_profile->postal_addrs) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pmy_profile->urls) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pmy_profile->nicknames) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pmy_profile->profiles) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pmy_profile->relationships) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_list(ipc_data, (contacts_list_h*)&pmy_profile->images) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_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->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 index 0000000..22578c1 --- /dev/null +++ b/common/ipc/ctsvc_ipc_name.c @@ -0,0 +1,86 @@ +#include "ctsvc_ipc_macros.h" + + +#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_bool(ipc_data, &name_p->is_changed) != 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_bool((name_p->is_changed),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 index 0000000..80b2c3c --- /dev/null +++ b/common/ipc/ctsvc_ipc_nickname.c @@ -0,0 +1,65 @@ +#include "ctsvc_ipc_macros.h" + + +#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 index 0000000..273df03 --- /dev/null +++ b/common/ipc/ctsvc_ipc_note.c @@ -0,0 +1,61 @@ +#include "ctsvc_ipc_macros.h" + + +#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, ¬e_p->id) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_int(ipc_data, ¬e_p->contact_id) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_string(ipc_data, ¬e_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 index 0000000..89b21d3 --- /dev/null +++ b/common/ipc/ctsvc_ipc_number.c @@ -0,0 +1,66 @@ +#include "ctsvc_ipc_macros.h" + + +#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_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; + if (ctsvc_ipc_unmarshal_string(ipc_data, &number_p->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_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_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; + if (ctsvc_ipc_marshal_string((number_p->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_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 index 0000000..382f904 --- /dev/null +++ b/common/ipc/ctsvc_ipc_person.c @@ -0,0 +1,97 @@ +#include "ctsvc_ipc_macros.h" + +#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->name_contact_id_changed) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_bool(ipc_data, &person_p->image_thumbnail_changed) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_bool(ipc_data, &person_p->ringtone_changed) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_bool(ipc_data, &person_p->vibration_changed) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_bool(ipc_data, &person_p->is_favorite_changed) != CONTACTS_ERROR_NONE) break; + 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->status) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_int(ipc_data, &person_p->link_count) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_int(ipc_data, &person_p->account_id1) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_int(ipc_data, &person_p->account_id2) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_int(ipc_data, &person_p->account_id3) != 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->name_contact_id_changed),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_bool((person_p->image_thumbnail_changed),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_bool((person_p->ringtone_changed),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_bool((person_p->vibration_changed),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_bool((person_p->is_favorite_changed),ipc_data) != CONTACTS_ERROR_NONE) break; + 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->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_int((person_p->account_id1),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_int((person_p->account_id2),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_int((person_p->account_id3),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 index 0000000..c367e66 --- /dev/null +++ b/common/ipc/ctsvc_ipc_phonelog.c @@ -0,0 +1,72 @@ +#include "ctsvc_ipc_macros.h" + +#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_string(ipc_data, &phonelog_p->display_name) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_string(ipc_data, &phonelog_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_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_string((phonelog_p->display_name),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_string((phonelog_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_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 index 0000000..190c83d --- /dev/null +++ b/common/ipc/ctsvc_ipc_profile.c @@ -0,0 +1,78 @@ +#include "ctsvc_ipc_macros.h" + +#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_int(ipc_data, &profile_p->type) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_string(ipc_data, &profile_p->label) != 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->appsvc_operation) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_string(ipc_data, &profile_p->data1) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_string(ipc_data, &profile_p->data2) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_string(ipc_data, &profile_p->data3) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_unmarshal_string(ipc_data, &profile_p->data4) != 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_int((profile_p->type),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_string((profile_p->label),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->appsvc_operation),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_string((profile_p->data1),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_string((profile_p->data2),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_string((profile_p->data3),ipc_data) != CONTACTS_ERROR_NONE) break; + if (ctsvc_ipc_marshal_string((profile_p->data4),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 index 0000000..e65c9c2 --- /dev/null +++ b/common/ipc/ctsvc_ipc_relationship.c @@ -0,0 +1,64 @@ +#include "ctsvc_ipc_macros.h" + + +#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 index 0000000..61b1d96 --- /dev/null +++ b/common/ipc/ctsvc_ipc_result.c @@ -0,0 +1,223 @@ +#include "ctsvc_ipc_macros.h" + +#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 index 0000000..7ecc6c2 --- /dev/null +++ b/common/ipc/ctsvc_ipc_sdn.c @@ -0,0 +1,57 @@ +#include "ctsvc_ipc_macros.h" + +#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; + + 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; + + 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 index 0000000..aaab788 --- /dev/null +++ b/common/ipc/ctsvc_ipc_simple_contact.c @@ -0,0 +1,78 @@ +#include "ctsvc_ipc_macros.h" + +#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_restricted) != CONTACTS_ERROR_NONE) break; + 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->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_restricted),ipc_data) != CONTACTS_ERROR_NONE) break; + 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->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 index 0000000..770ac63 --- /dev/null +++ b/common/ipc/ctsvc_ipc_speeddial.c @@ -0,0 +1,61 @@ +#include "ctsvc_ipc_macros.h" + +#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->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->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 index 0000000..6398128 --- /dev/null +++ b/common/ipc/ctsvc_ipc_updated_info.c @@ -0,0 +1,55 @@ +#include "ctsvc_ipc_macros.h" + +#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; + + 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; + + 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 index 0000000..b2a17d6 --- /dev/null +++ b/common/ipc/ctsvc_ipc_url.c @@ -0,0 +1,64 @@ +#include "ctsvc_ipc_macros.h" + +#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 index 0000000..6c867d6 --- /dev/null +++ b/contacts-service2.manifest @@ -0,0 +1,20 @@ +<manifest> + <define> + <domain name="contacts-service" /> + <provide> + <label name="contacts-service::db"/> + </provide> + </define> + <assign> + <filesystem path="/usr/lib/libcontacts-service2.so.0.9.24.8" label="_"/> + <filesystem path="/usr/lib/libcontacts-service2.so.0" label="_"/> + <filesystem path="/usr/lib/libcontacts-service3.so.0.9.24.8" label="_"/> + <filesystem path="/usr/lib/libcontacts-service3.so.0" label="_"/> + <filesystem path="/etc/rc.d/init.d/contacts-service-ipcd.sh" label="_" exec_label="none"/> + <filesystem path="/etc/rc.d/rc3.d/S50contacts-svc-helper" label="_" exec_label="none"/> + <filesystem path="/etc/rc.d/rc5.d/S50contacts-svc-helper" label="_" exec_label="none"/> + </assign> + <request> + <domain name="contacts-service" /> + </request> +</manifest> diff --git a/debian_NOT_USED/changelog b/debian_NOT_USED/changelog new file mode 100755 index 0000000..c35c3be --- /dev/null +++ b/debian_NOT_USED/changelog @@ -0,0 +1,2240 @@ +contacts-service (0.9.10) unstable; urgency=low + + * Fix bugs, Change view_uri + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.9.10 + + -- Donghee Ye <donghee.ye@samsung.com> Thu, 27 Dec 2012 11:25:45 +0900 + +contacts-service (0.9.6) unstable; urgency=low + + * Fix bugs, Add new notification mechanishm + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.9.6 + + -- Donghee Ye <donghee.ye@samsung.com> Fri, 7 Dec 2012 11:25:45 +0900 + +contacts-service (0.8.27) unstable; urgency=low + + * Apply IPC version + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.8.27 + + -- Donghee Ye <donghee.ye@samsung.com> Tue, 27 Nov 2012 11:25:45 +0900 + +contacts-service (0.8.5.1-1) unstable; urgency=low + + * Add manifest file + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.8.5.1-1 + + -- Donghee Ye <donghee.ye@samsung.com> Fri, 2 Nov 2012 11:25:45 +0900 + +contacts-service (0.8.5-1) unstable; urgency=low + + * Add new managed API + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.8.5-1 + + -- Donghee Ye <donghee.ye@samsung.com> Wed, 17 Oct 2012 11:25:45 +0900 + +contacts-service (0.7.33-1) unstable; urgency=low + + * fix Fix timeout crash problem + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.32-1 + + -- DoHyung Jin <dh.jin@samsung.com> Wed, 19 Sep 2012 11:25:45 +0900 + +contacts-service (0.7.32-1) unstable; urgency=low + + * fix query of CTS_LIST_PLOG_OF_PERSON_ID + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.32-1 + + -- DoHyung Jin <dh.jin@samsung.com> Wed, 19 Sep 2012 11:25:45 +0900 + +contacts-service (0.7.31-1) unstable; urgency=low + + * when language changed, update display_name_language + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.31-1 + + -- DoHyung Jin <dh.jin@samsung.com> Wed, 19 Sep 2012 11:25:45 +0900 + +contacts-service (0.7.30-1) unstable; urgency=low + + * fix seg_falut when callback from tapi sim + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.30-1 + + -- DoHyung Jin <dh.jin@samsung.com> Wed, 19 Sep 2012 11:25:45 +0900 + +contacts-service (0.7.29-1) unstable; urgency=low + + * version update error fix + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.29-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Wed, 19 Sep 2012 11:25:45 +0900 + +contacts-service (0.7.28-1) unstable; urgency=low + + * version update error fix + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.28-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Wed, 19 Sep 2012 11:25:45 +0900 + +contacts-service (0.7.26-1) unstable; urgency=low + + * add manifest file + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.26-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Wed, 19 Sep 2012 11:25:45 +0900 + +contacts-service (0.7.25-1) unstable; urgency=low + + * Fix search by number failure + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.25-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Wed, 19 Sep 2012 11:25:45 +0900 + +contacts-service (0.7.24-1) unstable; urgency=low + + * Fix add resize image / fix CTS_FILTERED_ALL_CONTACT problem + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.24-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Wed, 19 Sep 2012 11:25:45 +0900 + +contacts-service (0.7.23-1) unstable; urgency=low + + * Fix build error : make display name for vcard contact + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.23-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Fri, 14 Sep 2012 19:10:03 +0900 + +contacts-service (0.7.22-1) unstable; urgency=low + + * Fix build error : changed systemd header file path + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.22-1 + + -- DongHee Ye <donghee.ye@samsung.com> Fri, 14 Sep 2012 11:02:26 +0900 + +contacts-service (0.7.21-1) unstable; urgency=low + + * fix Disable auto link + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.21-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Thu, 13 Sep 2012 22:10:00 +0900 + +contacts-service (0.7.20-1) unstable; urgency=low + + * fix add phonelog statistic functions + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.20-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Wed, 12 Sep 2012 17:49:00 +0900 + +contacts-service (0.7.19-1) unstable; urgency=low + + * fix remove C/S communication while normalizing name or string / add contacts_svc_get_vcard_from_person + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.19-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Tue, 11 Sep 2012 19:22:00 +0900 + +contacts-service (0.7.18-1) unstable; urgency=low + + * fix Auto Link + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.18-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Mon, 10 Sep 2012 20:24:00 +0900 + +contacts-service (0.7.17-1) unstable; urgency=low + + * fix set has_phonenumber, has_email when update contact + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.17-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Mon, 10 Sep 2012 11:21:00 +0900 + +contacts-service (0.7.16-1) unstable; urgency=low + + * fix set has_phonenumber, has_email when update contact + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.16-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Fri, 7 Sep 2012 18:21:00 +0900 + +contacts-service (0.7.15-1) unstable; urgency=low + + * fix add activity delete function + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.15-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Tue, 4 Sep 2012 19:50:01 +0900 + +contacts-service (0.7.14-1) unstable; urgency=low + + * fix fix list members of group_id + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.14-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Tue, 4 Sep 2012 16:04:02 +0900 + +contacts-service (0.7.13-1) unstable; urgency=low + + * fix fix emailinfo list / fix label of number,email,web,postal + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.13-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Tue, 4 Sep 2012 13:45:24 +0900 + +contacts-service (0.7.12-1) unstable; urgency=low + + * fix fix smartsearch list / fix account delete + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.12-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Mon, 3 Sep 2012 17:05:03 +0900 + +contacts-service (0.7.10-1) unstable; urgency=low + + * fix fix person link + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.10-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Fri, 31 Aug 2012 21:25:01 +0900 + +contacts-service (0.7.9-1) unstable; urgency=low + + * fix change number normalization style / set phone default number, email/ fix plog problem + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.9-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Thu, 30 Aug 2012 19:57:32 +0900 + +contacts-service (0.7.8-1) unstable; urgency=low + + * fix group thumbnail path problem/search by name problem/add is_primary_default to data table / activity is deleted when contact is deleted + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.8-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Thu, 30 Aug 2012 14:27:53 +0900 + +contacts-service (0.7.7-1) unstable; urgency=low + + * fix Fix contact struct duplicate problem + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.7-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Tue, 28 Aug 2012 19:40:21 +0900 + +contacts-service (0.7.6-1) unstable; urgency=low + + * fix Person Notification/ contact struct duplicate + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.6-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Mon, 27 Aug 2012 11:11:23 +0900 + +contacts-service (0.7.5-1) unstable; urgency=low + + * fix fix default number, email problems/ fix speed_number column in speeddials table + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.5-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Fri, 24 Aug 2012 19:21:52 +0900 + +contacts-service (0.7.4-1) unstable; urgency=low + + * fix change sortkey collation / remove contact unnecessary trigger + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.4-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Wed, 22 Aug 2012 19:22:23 +0900 + +contacts-service (0.7.3-1) unstable; urgency=low + + * fix fix person notification / add vibration + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.3-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Tue, 21 Aug 2012 17:02:23 +0900 + +contacts-service (0.7.2-1) unstable; urgency=low + + * fix the mis-implementaion about deleting group & writing deleted_group + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.2-1 + + -- DoHyung Jin <dh.jin@samsung.com> Tue, 21 Aug 2012 15:02:21 +0900 + +contacts-service (0.7.1-1) unstable; urgency=low + + * Apply new db schema + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.7.1-1 + + -- JongWon Lee <gogosing.lee@samsung.com> Mon, 20 Aug 2012 13:48:04 +0900 + +contacts-service (0.6.15-1) unstable; urgency=low + + * removal of dlogutil script + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.6.15-1 + + -- DoHyung Jin <dh.jin@samsung.com> Mon, 20 Aug 2012 09:58:04 +0900 + +contacts-service (0.6.14-1) unstable; urgency=low + + * Fix get empty_pb_count + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.6.14-1 + + -- DongHee Ye <donghee.ye@samsung.com> Fri, 17 Aug 2012 19:54:37 +0900 + +contacts-service (0.6.13-1) unstable; urgency=low + + * Add API to get sim empty slot count + * Git: framework/pim/contacts-service + * Tag: contacts-service_0.6.13-1 + + -- DongHee Ye <donghee.ye@samsung.com> Mon, 13 Aug 2012 17:13:22 +0900 + +contacts-service (0.6.12-1) unstable; urgency=low + + * Apply new TAPI + * Git: slp/pkgs/c/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.11-1) unstable; urgency=low + + * Add CTS_LIST_CHANGE_ADDRESSBOOK_ID_INT + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.11-1 + + -- DoHyung Jin <dh.jin@samsung.com> Tue, 07 Aug 2012 10:48:57 +0900 + +contacts-service (0.6.10-1) unstable; urgency=low + + * change hard code "20000 -> CTS_GET_COUNT_GROUPS_IN_ADDRESSBOOK" + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.10-1 + + -- DoHyung Jin <dh.jin@samsung.com> Wed, 25 Jul 2012 18:23:34 +0900 + +contacts-service (0.6.9-1) unstable; urgency=low + + * for OSP - permission of making transparent filter + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.9-1 + + -- DoHyung Jin <dh.jin@samsung.com> Mon, 23 Jul 2012 16:42:55 +0900 + +contacts-service (0.6.8-1) unstable; urgency=low + + * Add enum to get count of incoming/outgoing call + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.8-1 + + -- DongHee Ye <donghee.ye@samsung.com> Wed, 18 Jul 2012 21:57:53 +0900 + +contacts-service (0.6.7-1) unstable; urgency=low + + * Update version for submit request + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.7-1 + + -- Donghee Ye <donghee.ye@samsung.com> Thu, 12 Jul 2012 22:28:47 +0900 + +contacts-service (0.6.6-1) unstable; urgency=low + + * Add log create + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.6-1 + + -- Donghee Ye <donghee.ye@samsung.com> Thu, 12 Jul 2012 21:54:24 +0900 + +contacts-service (0.6.5-1) unstable; urgency=low + + * Fix : update cts_version when changing group + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.5-1 + + -- Donghee Ye <donghee.ye@samsung.com> Fri, 06 Jul 2012 14:48:43 +0900 + +contacts-service (0.6.4-1) unstable; urgency=low + + * Fix filter bugs + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.4-1 + + -- DongHee Ye <donghee.ye@samsung.com> Tue, 03 Jul 2012 18:03:20 +0900 + +contacts-service (0.6.3-1) unstable; urgency=low + + * Enable to add/delete email logs + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.3-1 + + -- Donghee Ye <donghee.ye@samsung.com> Tue, 26 Jun 2012 17:36:15 +0900 + +contacts-service (0.6.2-1) unstable; urgency=low + + * Fix group relation + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.2-1 + + -- Donghee Ye <donghee.ye@samsung.com> Wed, 13 Jun 2012 23:26:06 +0900 + +contacts-service (0.6.1-19) unstable; urgency=low + + * Add feature for OSP : group ringtone return, group relation change + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-19 + + -- Donghee Ye <donghee.ye@samsung.com> Thu, 07 Jun 2012 23:29:08 +0900 + +contacts-service (0.6.1-18) unstable; urgency=low + + * Add feature for OSP : group count, default number of contact list + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-18 + + -- Donghee Ye <donghee.ye@samsung.com> Wed, 30 May 2012 20:52:08 +0900 + +contacts-service (0.6.1-17) unstable; urgency=low + + * Change vconf key name + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-17 + + -- Donghee Ye <donghee.ye@samsung.com> Fri, 25 May 2012 15:00:00 +0900 + +contacts-service (0.6.1-16) unstable; urgency=low + + * Add feature : to get phonelogs of person (history) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-16 + + -- Donghee Ye <donghee.ye@samsung.com> Fri, 25 May 2012 09:42:39 +0900 + +contacts-service (0.6.1-15) unstable; urgency=low + + * Add feature : myprofile + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-15 + + -- Donghee Ye <donghee.ye@samsung.com> Thu, 24 May 2012 09:06:24 +0900 + +contacts-service (0.6.1-14) unstable; urgency=low + + * Add feature : set group image + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-14 + + -- Donghee Ye <donghee.ye@samsung.com> Fri, 11 May 2012 13:50:27 +0900 + +contacts-service (0.6.1-13) unstable; urgency=low + + * fix bugs(chang language) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-13 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 30 Apr 2012 16:45:13 +0900 + +contacts-service (0.6.1-12) unstable; urgency=low + + * fix bugs(socket and outgoing count). + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-12 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 27 Apr 2012 10:56:30 +0900 + +contacts-service (0.6.1-11) unstable; urgency=low + + * Add CTS_LIST_ALL_UNSEEN_MISSED_CALL + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-11 + + -- Donghee Ye <donghee.ye@samsung.com> Tue, 10 Apr 2012 16:55:49 +0900 + +contacts-service (0.6.1-10) unstable; urgency=low + + * fix bug on emulator + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-10 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 09 Apr 2012 11:51:00 +0900 + +contacts-service (0.6.1-9) unstable; urgency=low + + * fix bug(image handling) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-9 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 05 Apr 2012 10:22:33 +0900 + +contacts-service (0.6.1-8) unstable; urgency=low + + * fix bug(vcard parser) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-8 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 03 Apr 2012 20:09:09 +0900 + +contacts-service (0.6.1-7) unstable; urgency=low + + * Fix smartsearch query in case of searching by number + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-7 + + -- Donghee Ye <donghee.ye@samsung.com> Fri, 30 Mar 2012 11:08:19 +0900 + +contacts-service (0.6.1-6) unstable; urgency=low + + * fix bug(image handling) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-6 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 29 Mar 2012 08:38:20 +0900 + +contacts-service (0.6.1-5) unstable; urgency=low + + * Fix smartsearch query + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-5 + + -- Donghee Ye <donghee.ye@samsung.com> Wed, 28 Mar 2012 19:55:12 +0900 + +contacts-service (0.6.1-4) unstable; urgency=low + + * fix memory leak + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 26 Mar 2012 11:42:11 +0900 + +contacts-service (0.6.1-3) unstable; urgency=low + + * fix bug + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 21 Mar 2012 10:13:44 +0900 + +contacts-service (0.6.1-2) unstable; urgency=low + + * apply revised telephony + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 19 Mar 2012 21:20:46 +0900 + +contacts-service (0.6.1-1) unstable; urgency=low + + * handling restricted data AND quoted printable + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.1-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 03 Mar 2012 15:23:35 +0900 + +contacts-service (0.6.0-2) unstable; urgency=low + + * make strong in thread for transaction functions + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.0-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 27 Feb 2012 20:56:07 +0900 + +contacts-service (0.6.0-1) unstable; urgency=low + + * added link mechanism + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.6.0-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 27 Feb 2012 14:25:42 +0900 + +contacts-service (0.5.2-37) unstable; urgency=low + + * fix bug(group relation while inserting contact) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-37 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 21 Feb 2012 18:36:56 +0900 + +contacts-service (0.5.2-36) unstable; urgency=low + + * revise doxygen + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-36 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 10 Feb 2012 14:42:34 +0900 + +contacts-service (0.5.2-35) unstable; urgency=low + + * fix bug(normalize and missed call noti) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-35 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 08 Feb 2012 21:23:06 +0900 + +contacts-service (0.5.2-34) unstable; urgency=low + + * fix bug(normalize overflow) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-34 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 31 Jan 2012 18:15:29 +0900 + +contacts-service (0.5.2-33) unstable; urgency=low + + * fix bugs + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-33 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 28 Jan 2012 11:54:30 +0900 + +contacts-service (0.5.2-32) unstable; urgency=low + + * fix bug(uid updating) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-32 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 19 Jan 2012 15:25:29 +0900 + +contacts-service (0.5.2-31) unstable; urgency=low + + * fix bugs(vcard note) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-31 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 13 Jan 2012 14:34:53 +0900 + +contacts-service (0.5.2-30) unstable; urgency=low + + * fix busg and revise doxygen + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-30 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 06 Jan 2012 17:33:07 +0900 + +contacts-service (0.5.2-29) unstable; urgency=low + + * fix bugs + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-29 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 02 Jan 2012 13:35:53 +0900 + +contacts-service (0.5.2-28) unstable; urgency=low + + * line up cts_str_filter_op + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-28 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 28 Dec 2011 19:34:34 +0900 + +contacts-service (0.5.2-27) unstable; urgency=low + + * change function name + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-27 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 28 Dec 2011 14:44:02 +0900 + +contacts-service (0.5.2-26) unstable; urgency=low + + * change type from cts_find_contact_op to cts_find_op + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-26 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 21 Dec 2011 11:06:00 +0900 + +contacts-service (0.5.2-25) unstable; urgency=low + + * fix errata + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-25 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 20 Dec 2011 20:40:33 +0900 + +contacts-service (0.5.2-24) unstable; urgency=low + + * fix helper socket ipc + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-24 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 14 Dec 2011 16:38:02 +0900 + +contacts-service (0.5.2-23) unstable; urgency=low + + * cleanup + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-23 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 08 Dec 2011 17:06:54 +0900 + +contacts-service (0.5.2-22) unstable; urgency=low + + * revise handling photo + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-22 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 06 Dec 2011 18:09:35 +0900 + +contacts-service (0.5.2-21) unstable; urgency=low + + * fix bug + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-21 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 01 Dec 2011 12:48:38 +0900 + +contacts-service (0.5.2-20) unstable; urgency=low + + * debugging vcard parser + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-20 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 29 Nov 2011 11:06:43 +0900 + +contacts-service (0.5.2-19) unstable; urgency=low + + * debug contacts_svc_smartsearch_excl() + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-19 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 22 Nov 2011 17:07:18 +0900 + +contacts-service (0.5.2-18) unstable; urgency=low + + * revise contacts_svc_phonelog_set_seen() + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-18 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 21 Nov 2011 16:14:48 +0900 + +contacts-service (0.5.2-17) unstable; urgency=low + + * Remove unused code, add normalized_strstr + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-17 + + -- Donghee Ye <donghee.ye@samsung.com> Thu, 17 Nov 2011 15:53:14 +0900 + +contacts-service (0.5.2-16) unstable; urgency=low + + * remove duplicated data when insert and update + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-16 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 14 Nov 2011 10:09:39 +0900 + +contacts-service (0.5.2-15) unstable; urgency=low + + * fix bug(number and email list) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-15 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 08 Nov 2011 15:04:49 +0900 + +contacts-service (0.5.2-14) unstable; urgency=low + + * fix BS(handling no_name) and add type for contacts_svc_get_list + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-14 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 07 Nov 2011 14:44:34 +0900 + +contacts-service (0.5.2-13) unstable; urgency=low + + * revise + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-13 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 05 Nov 2011 19:21:12 +0900 + +contacts-service (0.5.2-12) unstable; urgency=low + + * fix BS + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-12 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 03 Nov 2011 09:47:47 +0900 + +contacts-service (0.5.2-11) unstable; urgency=low + + * revise no name and fix bug(email searched list) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-11 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 02 Nov 2011 21:34:11 +0900 + +contacts-service (0.5.2-10) unstable; urgency=low + + * revise numer handling(support 'P' and 'w' and remove invalid speeddial) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-10 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 31 Oct 2011 16:12:45 +0900 + +contacts-service (0.5.2-9) unstable; urgency=low + + * fix bug(defult number and email) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-9 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 29 Oct 2011 17:42:50 +0900 + +contacts-service (0.5.2-8) unstable; urgency=low + + * fix BS and revise vcard parsing + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-8 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 28 Oct 2011 17:29:11 +0900 + +contacts-service (0.5.2-7) unstable; urgency=low + + * fix bug(update number and email) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-7 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 27 Oct 2011 08:31:23 +0900 + +contacts-service (0.5.2-6) unstable; urgency=low + + * fix memory leak + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-6 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 26 Oct 2011 16:24:35 +0900 + +contacts-service (0.5.2-5) unstable; urgency=low + + * Fix build error + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-5 + + -- Donghee Ye <donghee.ye@samsung.com> Fri, 21 Oct 2011 21:51:09 +0900 + +contacts-service (0.5.2-4) unstable; urgency=low + + * change vconf key of system language + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 21 Oct 2011 17:49:16 +0900 + +contacts-service (0.5.2-3) unstable; urgency=low + + * update icu + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 20 Oct 2011 20:54:52 +0900 + +contacts-service (0.5.2-2) unstable; urgency=low + + * fix bug(ordering) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 19 Oct 2011 21:02:07 +0900 + +contacts-service (0.5.2-1) unstable; urgency=low + + * revise vcard encoding + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.2-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 17 Oct 2011 21:58:09 +0900 + +contacts-service (0.5.1-5) unstable; urgency=low + + * fix bug(speeddial) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.1-5 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 11 Oct 2011 15:37:59 +0900 + +contacts-service (0.5.1-4) unstable; urgency=low + + * revise vcard handling + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.1-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 08 Oct 2011 07:16:20 +0900 + +contacts-service (0.5.1-3) unstable; urgency=low + + * fix bug(update number and email) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.1-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 07 Oct 2011 13:43:00 +0900 + +contacts-service (0.5.1-2) unstable; urgency=low + + * fix bug + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.1-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 06 Oct 2011 20:14:15 +0900 + +contacts-service (0.5.1-1) unstable; urgency=low + + * change schema + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.5.1-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 06 Oct 2011 10:49:29 +0900 + +contacts-service (0.4.2-7) unstable; urgency=low + + * revise missed call handling + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.4.2-7 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 05 Oct 2011 14:28:59 +0900 + +contacts-service (0.4.2-6) unstable; urgency=low + + * fix bug + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.4.2-6 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 04 Oct 2011 19:49:45 +0900 + +contacts-service (0.4.2-5) unstable; urgency=low + + * change address type + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.4.2-5 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 03 Oct 2011 13:28:47 +0900 + +contacts-service (0.4.2-4) unstable; urgency=low + + * fix bug + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.4.2-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 29 Sep 2011 17:19:09 +0900 + +contacts-service (0.4.2-3) unstable; urgency=low + + * revise contacts-service + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.4.2-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 29 Sep 2011 15:00:50 +0900 + +contacts-service (0.4.2-2) unstable; urgency=low + + * fix errata + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.4.2-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 28 Sep 2011 10:40:01 +0900 + +contacts-service (0.4.2-1) unstable; urgency=low + + * revise updated_contacts and support bada + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.4.2-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 27 Sep 2011 13:20:36 +0900 + +contacts-service (0.4.1-2) unstable; urgency=low + + * fix bug of phonelog + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.4.1-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 26 Sep 2011 13:23:41 +0900 + +contacts-service (0.4.1-1) unstable; urgency=low + + * revise iterator + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.4.1-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 23 Sep 2011 17:59:57 +0900 + +contacts-service (0.3.4-4) unstable; urgency=low + + * add list of all phonelog + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.4-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 07 Sep 2011 20:49:43 +0900 + +contacts-service (0.3.4-3) unstable; urgency=low + + * revise image handling + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.4-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 05 Sep 2011 10:44:15 +0900 + +contacts-service (0.3.4-2) unstable; urgency=low + + * revise + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.4-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 01 Sep 2011 22:24:11 +0900 + +contacts-service (0.3.4-1) unstable; urgency=low + + * revise vcard + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.4-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 31 Aug 2011 17:43:51 +0900 + +contacts-service (0.3.3-1) unstable; urgency=low + + * add struct handling functions + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.3-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 27 Aug 2011 15:35:36 +0900 + +contacts-service (0.3.2-7) unstable; urgency=low + + * modify by prevent comment + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.2-7 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 23 Aug 2011 11:24:06 +0900 + +contacts-service (0.3.2-6) unstable; urgency=low + + * revise vcard parser + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.2-6 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 18 Aug 2011 08:20:47 +0900 + +contacts-service (0.3.2-5) unstable; urgency=low + + * revise to handle write() + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.2-5 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 17 Aug 2011 16:34:05 +0900 + +contacts-service (0.3.2-4) unstable; urgency=low + + * revise to handle sqlite errors + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.2-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 16 Aug 2011 18:22:18 +0900 + +contacts-service (0.3.2-3) unstable; urgency=low + + * revise vcard parsing + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.2-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 10 Aug 2011 15:38:41 +0900 + +contacts-service (0.3.2-2) unstable; urgency=low + + * revise version mechanism + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.2-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 10 Aug 2011 10:45:06 +0900 + +contacts-service (0.3.2-1) unstable; urgency=low + + * apply version + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.2-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 09 Aug 2011 20:24:14 +0900 + +contacts-service (0.3.1-9) unstable; urgency=low + + * fix errata + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.1-9 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 05 Aug 2011 10:02:08 +0900 + +contacts-service (0.3.1-8) unstable; urgency=low + + * revise contacts-service + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.1-8 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 03 Aug 2011 18:56:18 +0900 + +contacts-service (0.3.1-7) unstable; urgency=low + + * add display name handling code + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.1-7 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 26 Jul 2011 19:38:25 +0900 + +contacts-service (0.3.1-6) unstable; urgency=low + + * revise contacts-service + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.1-6 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 25 Jul 2011 21:37:40 +0900 + +contacts-service (0.3.1-5) unstable; urgency=low + + * revise vcard parsing + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.1-5 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 23 Jul 2011 17:20:42 +0900 + +contacts-service (0.3.1-4) unstable; urgency=low + + * fix bug for making vcard + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.1-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 23 Jul 2011 11:59:01 +0900 + +contacts-service (0.3.1-3) unstable; urgency=low + + * check duplicated contacts for importing sim + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.1-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 23 Jul 2011 10:48:25 +0900 + +contacts-service (0.3.1-2) unstable; urgency=low + + * revise error handling code for inotify + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.1-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 21 Jul 2011 10:59:52 +0900 + +contacts-service (0.3.1-1) unstable; urgency=low + + * remove the dependeny with vobject service + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.1-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 19 Jul 2011 10:17:59 +0900 + +contacts-service (0.3.0-5) unstable; urgency=low + + * fix bug + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.0-5 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 14 Jul 2011 18:33:16 +0900 + +contacts-service (0.3.0-4) unstable; urgency=low + + * revise contacts-service + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.0-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 13 Jul 2011 13:23:28 +0900 + +contacts-service (0.3.0-3) unstable; urgency=low + + * fix prevent bug + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.0-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 08 Jul 2011 18:35:20 +0900 + +contacts-service (0.3.0-2) unstable; urgency=low + + * add noti for modifing addressbook + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.0-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 07 Jul 2011 15:21:36 +0900 + +contacts-service (0.3.0-1) unstable; urgency=low + + * add concepts of addressbook + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.3.0-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 04 Jul 2011 21:25:36 +0900 + +contacts-service (0.2.14-2) unstable; urgency=low + + * fix errata + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.14-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 30 Jun 2011 09:06:43 +0900 + +contacts-service (0.2.14-1) unstable; urgency=low + + * add contacts_svc_unsubscribe_change_with_data() + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.14-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 29 Jun 2011 17:31:03 +0900 + +contacts-service (0.2.13-2) unstable; urgency=low + + * add doxygen about contacts_svc_get_phonelog() + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.13-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 27 Jun 2011 15:19:27 +0900 + +contacts-service (0.2.13-1) unstable; urgency=low + + * change favorite and speeddial functions + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.13-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 22 Jun 2011 21:07:31 +0900 + +contacts-service (0.2.12-15) unstable; urgency=low + + * fix bugs + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.12-15 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 14 Jun 2011 18:32:28 +0900 + +contacts-service (0.2.12-14) unstable; urgency=low + + * check invalid string + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.12-14 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 13 Jun 2011 19:54:33 +0900 + +contacts-service (0.2.12-13) unstable; urgency=low + + * add a operation of contacts_svc_get_contact_value + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.12-13 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 13 Jun 2011 11:23:21 +0900 + +contacts-service (0.2.12-12) unstable; urgency=low + + * revise name ordering + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.12-12 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 09 Jun 2011 14:37:02 +0900 + +contacts-service (0.2.12-11) unstable; urgency=low + + * change the policy for name ordering + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.12-11 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 08 Jun 2011 14:21:52 +0900 + +contacts-service (0.2.12-10) unstable; urgency=low + + * fix socket handling + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.12-10 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 08 Jun 2011 07:54:17 +0900 + +contacts-service (0.2.12-9) unstable; urgency=low + + * fix BS + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.12-9 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 03 Jun 2011 15:41:10 +0900 + +contacts-service (0.2.12-8) unstable; urgency=low + + * fix errta + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.12-8 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 26 May 2011 15:56:41 +0900 + +contacts-service (0.2.12-7) unstable; urgency=low + + * revise + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.12-7 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 19 May 2011 15:01:31 +0900 + +contacts-service (0.2.12-6) unstable; urgency=low + + * sort group list + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.12-6 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 17 May 2011 17:02:57 +0900 + +contacts-service (0.2.12-5) unstable; urgency=low + + * update icu + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.12-5 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 16 May 2011 11:08:58 +0900 + +contacts-service (0.2.12-4) unstable; urgency=low + + * revise insert_contact(guarantee atomic) + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.12-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 13 May 2011 20:25:44 +0900 + +contacts-service (0.2.12-3) unstable; urgency=low + + * add debugging code + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.12-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 09 May 2011 18:35:41 +0900 + +contacts-service (0.2.12-2) unstable; urgency=low + + * debugging normalization + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.12-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 05 May 2011 11:29:13 +0900 + +contacts-service (0.2.12-1) unstable; urgency=low + + * revise normalization and phonelog + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.12-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 30 Apr 2011 16:45:38 +0900 + +contacts-service (0.2.11-4) unstable; urgency=low + + * change retry term + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.11-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 15 Apr 2011 16:10:35 +0900 + +contacts-service (0.2.11-3) unstable; urgency=low + + * revise group api + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.11-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 11 Apr 2011 11:46:47 +0900 + +contacts-service (0.2.11-2) unstable; urgency=low + + * fix TC + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.11-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 04 Apr 2011 14:50:45 +0900 + +contacts-service (0.2.11-1) unstable; urgency=low + + * add normalization for number + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.11-1 + + -- Youngjae <yj99.shin@samsung.com> Sat, 26 Mar 2011 11:17:53 +0900 + +contacts-service (0.2.10-5) unstable; urgency=low + + * add contacts_svc_delete_group_with_members() + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.10-5 + + -- Youngjae <yj99.shin@samsung.com> Thu, 17 Mar 2011 17:43:29 +0900 + +contacts-service (0.2.10-4) unstable; urgency=low + + * fix bug + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.10-4 + + -- Youngjae <yj99.shin@samsung.com> Wed, 09 Mar 2011 20:55:38 +0900 + +contacts-service (0.2.10-3) unstable; urgency=low + + * add group notification + * Git: slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.10-3 + + -- Youngjae <yj99.shin@samsung.com> Wed, 09 Mar 2011 16:08:50 +0900 + +contacts-service (0.2.10-2) unstable; urgency=low + + * revise handling empty string and Unkown log + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.10-2 + + -- Youngjae <yj99.shin@samsung.com> Tue, 08 Mar 2011 11:06:57 +0900 + +contacts-service (0.2.10-1) unstable; urgency=low + + * change the policy of number types + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.10-1 + + -- Youngjae <yj99.shin@samsung.com> Tue, 01 Mar 2011 11:05:39 +0900 + +contacts-service (0.2.9-10) unstable; urgency=low + + * fix phonelog error + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.9-10 + + -- Youngjae <yj99.shin@samsung.com> Sat, 26 Feb 2011 11:17:32 +0900 + +contacts-service (0.2.9-9) unstable; urgency=low + + * fix errata + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.9-9 + + -- Youngjae <yj99.shin@samsung.com> Fri, 25 Feb 2011 15:44:30 +0900 + +contacts-service (0.2.9-8) unstable; urgency=low + + * fix bug + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.9-8 + + -- Youngjae <yj99.shin@samsung.com> Thu, 24 Feb 2011 15:19:29 +0900 + +contacts-service (0.2.9-7) unstable; urgency=low + + * fix some bug and revise retry mechanism + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.9-7 + + -- Youngjae <yj99.shin@samsung.com> Thu, 24 Feb 2011 13:44:54 +0900 + +contacts-service (0.2.9-6) unstable; urgency=low + + * revise lock mechanism and check constraint for handling group + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.9-6 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 23 Feb 2011 17:56:47 +0900 + +contacts-service (0.2.9-5) unstable; urgency=low + + * fix prevent bug + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.9-5 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 22 Feb 2011 13:44:54 +0900 + +contacts-service (0.2.9-4) unstable; urgency=low + + * support full image in a contact + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.9-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 21 Feb 2011 17:59:20 +0900 + +contacts-service (0.2.9-3) unstable; urgency=low + + * remove MWC code in source. + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.9-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 16 Feb 2011 19:36:17 +0900 + +contacts-service (0.2.9-2) unstable; urgency=low + + * handling contact struct which have no name and no id + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.9-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 16 Feb 2011 12:08:48 +0900 + +contacts-service (0.2.9-1) unstable; urgency=low + + * remove MWC code + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.9-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 14 Feb 2011 11:19:19 +0900 + +contacts-service (0.2.8-9MWC2011) unstable; urgency=low + + * revise handling invalid name + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.8-9MWC2011 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 10 Feb 2011 09:36:32 +0900 + +contacts-service (0.2.8-8MWC2011) unstable; urgency=low + + * revise MWC code + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.8-8MWC2011 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 31 Jan 2011 17:20:04 +0900 + +contacts-service (0.2.8-7MWC2011) unstable; urgency=low + + * add contacts_svc_value_get_type() + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.8-7MWC2011 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 31 Jan 2011 09:23:25 +0900 + +contacts-service (0.2.8-6MWC2011) unstable; urgency=low + + * fix prevent errors + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.8-6MWC2011 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 29 Jan 2011 15:34:17 +0900 + +contacts-service (0.2.8-5MWC2011) unstable; urgency=low + + * add options for contacts_svc_get_contact_value() + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.8-5MWC2011 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 25 Jan 2011 19:41:50 +0900 + +contacts-service (0.2.8-4MWC2011) unstable; urgency=low + + * fix prevent errors + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.8-4MWC2011 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 22 Jan 2011 14:11:58 +0900 + +contacts-service (0.2.8-3MWC2011) unstable; urgency=low + + * handle NULL pointer + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.8-3MWC2011 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 20 Jan 2011 08:49:36 +0900 + +contacts-service (0.2.8-2MWC2011) unstable; urgency=low + + * add UID for MWC2011 + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.8-2MWC2011 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 18 Jan 2011 11:02:03 +0900 + +contacts-service (0.2.8-1MWC2011) unstable; urgency=low + + * debugging MWC code + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.8-1MWC2011 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 13 Jan 2011 20:58:41 +0900 + +contacts-service (0.2.7.MWC2011-3) unstable; urgency=low + + * rebuild + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.7.MWC2011-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 13 Jan 2011 14:29:44 +0900 + +contacts-service (0.2.7.MWC2011-2) unstable; urgency=low + + * revise postinst + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.7.MWC2011-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 13 Jan 2011 11:17:47 +0900 + +contacts-service (0.2.7.MWC2011-1) unstable; urgency=low + + * for MWC2011 + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.7.MWC2011-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 13 Jan 2011 09:34:33 +0900 + +contacts-service (0.2.7-2) unstable; urgency=low + + * modify enum + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.7-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 06 Jan 2011 15:09:33 +0900 + +contacts-service (0.2.7-1) unstable; urgency=low + + * change enum(MESSENGERVALUE) + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.7-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 04 Jan 2011 08:37:02 +0900 + +contacts-service (0.2.6-1) unstable; urgency=low + + * change enum and minor debugging + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.6-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 28 Dec 2010 13:52:52 +0900 + +contacts-service (0.2.5-2) unstable; urgency=low + + * fix socket handling + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.5-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 15 Dec 2010 14:05:35 +0900 + +contacts-service (0.2.5-1) unstable; urgency=low + + * remove contacts_svc_get_count and update vobject_servcie + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.5-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 13 Dec 2010 11:34:09 +0900 + +contacts-service (0.2.4-4) unstable; urgency=low + + * debugging compare function + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.4-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 09 Dec 2010 13:35:29 +0900 + +contacts-service (0.2.4-3) unstable; urgency=low + + * remove old files + * Git: slp-source.sec.samsung.net:slp/pkgs/c/contacts-service + * Tag: contacts-service_0.2.4-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 08 Dec 2010 13:16:58 +0900 + +contacts-service (0.2.4-2) unstable; urgency=low + + * debugging contacts_svc_nomalize_str() + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.4-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 02 Dec 2010 09:51:45 +0900 + +contacts-service (0.2.4-1) unstable; urgency=low + + * deprecate contacts_svc_get_count and add contacts_svc_count, + contacts_svc_count_with_int + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.4-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 01 Dec 2010 21:26:20 +0900 + +contacts-service (0.2.3-14) unstable; urgency=low + + * change libicu from 36 to 40 + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.3-14 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 30 Nov 2010 21:44:00 +0900 + +contacts-service (0.2.3-13) unstable; urgency=low + + * debugging + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.3-13 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 29 Nov 2010 08:45:27 +0900 + +contacts-service (0.2.3-12) unstable; urgency=low + + * optimize query for favorite + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.3-12 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 17 Nov 2010 14:22:14 +0900 + +contacts-service (0.2.3-11) unstable; urgency=low + + * debugging extend value + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.3-11 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 16 Nov 2010 20:10:58 +0900 + +contacts-service (0.2.3-10) unstable; urgency=low + + * debugging + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.3-10 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 16 Nov 2010 09:36:50 +0900 + +contacts-service (0.2.3-9) unstable; urgency=low + + * debugging + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.3-9 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 15 Nov 2010 15:23:49 +0900 + +contacts-service (0.2.3-8) unstable; urgency=low + + * remove db file in package + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.3-8 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 15 Nov 2010 10:51:34 +0900 + +contacts-service (0.2.3-7) unstable; urgency=low + + * debugging count function + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.3-7 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 12 Nov 2010 08:09:49 +0900 + +contacts-service (0.2.3-6) unstable; urgency=low + + * revise normalization + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.3-6 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 10 Nov 2010 20:51:04 +0900 + +contacts-service (0.2.3-5) unstable; urgency=low + + * change policy of group + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.3-5 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 09 Nov 2010 09:35:13 +0900 + +contacts-service (0.2.3-4) unstable; urgency=low + + * change policy of SDN + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.3-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 08 Nov 2010 11:44:02 +0900 + +contacts-service (0.2.3-3) unstable; urgency=low + + * change vobject-service + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.3-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 03 Nov 2010 21:29:52 +0900 + +contacts-service (0.2.3-2) unstable; urgency=low + + * revise socket msg + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.3-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 30 Oct 2010 15:37:54 +0900 + +contacts-service (0.2.3-1) unstable; urgency=low + + * add normalization + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.3-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 29 Oct 2010 11:58:20 +0900 + +contacts-service (0.2.2-2) unstable; urgency=low + + * debugging get_updated_contacts() + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.2-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 28 Oct 2010 14:41:57 +0900 + +contacts-service (0.2.2-1) unstable; urgency=low + + * revise get_updated_contacts() + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.2-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 27 Oct 2010 21:22:31 +0900 + +contacts-service (0.2.1-9) unstable; urgency=low + + * debugging about cpu share and handling delete_bool + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.1-9 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 27 Oct 2010 09:39:22 +0900 + +contacts-service (0.2.1-8) unstable; urgency=low + + * add import_sim function and debugging + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.1-8 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 26 Oct 2010 14:08:49 +0900 + +contacts-service (0.2.1-7) unstable; urgency=low + + * revise image functions + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.1-7 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 22 Oct 2010 20:37:12 +0900 + +contacts-service (0.2.1-6) unstable; urgency=low + + * debugging group list + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.1-6 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 21 Oct 2010 17:24:53 +0900 + +contacts-service (0.2.1-5) unstable; urgency=low + + * debugging transaction rule + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.1-5 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 20 Oct 2010 20:57:18 +0900 + +contacts-service (0.2.1-4) unstable; urgency=low + + * update vcard converting functions + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.1-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 18 Oct 2010 21:14:33 +0900 + +contacts-service (0.2.1-3) unstable; urgency=low + + * fix errata + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.1-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 18 Oct 2010 09:39:47 +0900 + +contacts-service (0.2.1-2) unstable; urgency=low + + * change phonelog schema + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.1-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 15 Oct 2010 12:22:04 +0900 + +contacts-service (0.2.1-1) unstable; urgency=low + + * change update_list method and add vcard function + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.1-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 13 Oct 2010 10:08:00 +0900 + +contacts-service (0.2.0-12) unstable; urgency=low + + * add recovery mechanism + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.0-12 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 11 Oct 2010 17:01:20 +0900 + +contacts-service (0.2.0-11) unstable; urgency=low + + * debugging group functions + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.0-11 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 11 Oct 2010 15:18:39 +0900 + +contacts-service (0.2.0-10) unstable; urgency=low + + * debugging add more field + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.0-10 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 05 Oct 2010 19:03:22 +0900 + +contacts-service (0.2.0-9) unstable; urgency=low + + * add temporary library link + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.0-9 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 05 Oct 2010 10:48:40 +0900 + +contacts-service (0.2.0-8) unstable; urgency=low + + * debugging name search + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.0-8 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 04 Oct 2010 18:18:11 +0900 + +contacts-service (0.2.0-7) unstable; urgency=low + + * debugging double free + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.0-7 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 04 Oct 2010 16:22:06 +0900 + +contacts-service (0.2.0-6) unstable; urgency=low + + * add number list searched by number + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.0-6 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 04 Oct 2010 13:14:13 +0900 + +contacts-service (0.2.0-5) unstable; urgency=low + + * debugging name order + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.0-5 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 02 Oct 2010 11:33:16 +0900 + +contacts-service (0.2.0-4) unstable; urgency=low + + * debugging contacts_svc_get_contact_from_vcard() + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.0-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 02 Oct 2010 11:15:00 +0900 + +contacts-service (0.2.0-3) unstable; urgency=low + + * debugging contacts_svc_get_custom_type() + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.0-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 01 Oct 2010 13:59:02 +0900 + +contacts-service (0.2.0-2) unstable; urgency=low + + * debugging(assigning group and vcard crash) + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.0-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 01 Oct 2010 10:25:30 +0900 + +contacts-service (0.2.0-1) unstable; urgency=low + + * remove old contacts-service + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.2.0-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 28 Sep 2010 20:10:10 +0900 + +contacts-service (0.1.2-11) unstable; urgency=low + + * debugging connection mechanism + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.2-11 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 27 Sep 2010 22:09:41 +0900 + +contacts-service (0.1.2-10) unstable; urgency=low + + * debugging update_contact(default num, email) + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.2-10 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 27 Sep 2010 16:38:29 +0900 + +contacts-service (0.1.2-9) unstable; urgency=low + + * change image path from ums to opt + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.2-9 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 27 Sep 2010 09:59:17 +0900 + +contacts-service (0.1.2-8) unstable; urgency=low + + * add group API and favorite noti + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.2-8 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 16 Sep 2010 09:33:52 +0900 + +contacts-service (0.1.2-7) unstable; urgency=low + + * add/modify function(deprecate contacts_svc_save_image) + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.2-7 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 14 Sep 2010 14:38:08 +0900 + +contacts-service (0.1.2-6) unstable; urgency=low + + * debugging dpkg + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.2-6 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 11 Sep 2010 16:42:04 +0900 + +contacts-service (0.1.2-5) unstable; urgency=low + + * remove eina dependency + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.2-5 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 11 Sep 2010 15:13:10 +0900 + +contacts-service (0.1.2-4) unstable; urgency=low + + * add favorite list, modify count function, fix sorting bug + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.2-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 09 Sep 2010 20:29:27 +0900 + +contacts-service (0.1.2-3) unstable; urgency=low + + * complete get_contact() + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.2-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 08 Sep 2010 21:05:17 +0900 + +contacts-service (0.1.2-2) unstable; urgency=low + + * modify doxygen and add account API + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.2-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 08 Sep 2010 12:22:10 +0900 + +contacts-service (0.1.2-1) unstable; urgency=low + + * revise some API by Mike + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.2-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 06 Sep 2010 17:57:19 +0900 + +contacts-service (0.1.1-2) unstable; urgency=low + + * add some functions + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.1-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 04 Sep 2010 17:37:38 +0900 + +contacts-service (0.1.1-1) unstable; urgency=low + + * apply some requirements + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.1-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 02 Sep 2010 09:47:05 +0900 + +contacts-service (0.1.1-0) unstable; urgency=low + + * release + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.1-0 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 01 Sep 2010 15:07:42 +0900 + +contacts-service (0.1.0-5) unstable; urgency=low + + * remove alarm dependency + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.0-5 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 31 Aug 2010 21:10:10 +0900 + +contacts-service (0.1.0-4) unstable; urgency=low + + * add doxygen + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.0-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 27 Aug 2010 22:02:07 +0900 + +contacts-service (0.1.0-3) unstable; urgency=low + + * fix package config file + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.0-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 18 Aug 2010 13:29:08 +0900 + +contacts-service (0.1.0-2) unstable; urgency=low + + * add phone logs + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.0-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 18 Aug 2010 12:53:44 +0900 + +contacts-service (0.1.0-1) unstable; urgency=low + + * add new contacts-service + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.1.0-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 13 Aug 2010 09:48:32 +0900 + +contacts-service (0.0.2-8) unstable; urgency=low + + * fix errata in schema + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.2-8 + + -- Youngjae Shin <yj99.shin@samsung.com> Sat, 07 Aug 2010 09:40:28 +0900 + +contacts-service (0.0.2-7) unstable; urgency=low + + * change parameter name for vcard API + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.2-7 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 04 Aug 2010 14:18:58 +0900 + +contacts-service (0.0.2-6) unstable; urgency=low + + * add some missed old API + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.2-6 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 30 Jul 2010 20:34:45 +0900 + +contacts-service (0.0.2-5) unstable; urgency=low + + * fix buf(not finalize) + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.2-5 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 30 Jul 2010 17:38:04 +0900 + +contacts-service (0.0.2-4) unstable; urgency=low + + * fix BS + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.2-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 30 Jul 2010 14:01:48 +0900 + +contacts-service (0.0.2-3) unstable; urgency=low + + * fix a problem of version + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.2-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 30 Jul 2010 10:37:21 +0900 + +contacts-service (0.0.2-2) unstable; urgency=low + + * fix build-break(upload contacts-svc-struct.h) + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.2-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 30 Jul 2010 08:56:29 +0900 + +contacts-service (0.0.2-1) unstable; urgency=low + + * add image handling and struct handling code + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.2-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Thu, 29 Jul 2010 11:38:38 +0900 + +contacts-service (0.0.1-9) unstable; urgency=low + + * debugging BS which is occurred for handling sim + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.1-9 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 28 Jul 2010 10:02:09 +0900 + +contacts-service (0.0.1-8) unstable; urgency=low + + * remove log + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.1-8 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 27 Jul 2010 09:22:46 +0900 + +contacts-service (0.0.1-7) unstable; urgency=low + + * fix sim init in helper + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.1-7 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 26 Jul 2010 11:46:10 +0900 + +contacts-service (0.0.1-6) unstable; urgency=low + + * fix some bug(related group) + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.1-6 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 23 Jul 2010 10:01:42 +0900 + +contacts-service (0.0.1-5) unstable; urgency=low + + * modify bulid process for database file and change some API + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.1-5 + + -- Youngjae Shin <yj99.shin@samsung.com> Wed, 21 Jul 2010 11:30:34 +0900 + +contacts-service (0.0.1-4) unstable; urgency=low + + * fix some bugs(related image) and change some API + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.1-4 + + -- Youngjae Shin <yj99.shin@samsung.com> Tue, 20 Jul 2010 14:51:25 +0900 + +contacts-service (0.0.1-3) unstable; urgency=low + + * the hidden symbol change + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.1-3 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 19 Jul 2010 10:42:11 +0900 + +contacts-service (0.0.1-2) unstable; urgency=low + + * include old API header in package + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.1-2 + + -- Youngjae Shin <yj99.shin@samsung.com> Mon, 19 Jul 2010 09:59:55 +0900 + +contacts-service (0.0.1-1) unstable; urgency=low + + * change package name and source tree + * Git: /git/slp/pkgs/contacts-service + * Tag: contacts-service_0.0.1-1 + + -- Youngjae Shin <yj99.shin@samsung.com> Fri, 16 Jul 2010 13:23:35 +0900 diff --git a/debian_NOT_USED/compat b/debian_NOT_USED/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian_NOT_USED/compat @@ -0,0 +1 @@ +5 diff --git a/debian_NOT_USED/contacts-service-bin.install.in b/debian_NOT_USED/contacts-service-bin.install.in new file mode 100644 index 0000000..5549ed0 --- /dev/null +++ b/debian_NOT_USED/contacts-service-bin.install.in @@ -0,0 +1,2 @@ +@PREFIX@/bin/* +/etc/* diff --git a/debian_NOT_USED/contacts-service-bin.postinst.in b/debian_NOT_USED/contacts-service-bin.postinst.in new file mode 100755 index 0000000..a853e91 --- /dev/null +++ b/debian_NOT_USED/contacts-service-bin.postinst.in @@ -0,0 +1,28 @@ +#!/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_NOT_USED/control b/debian_NOT_USED/control new file mode 100644 index 0000000..3d3eb07 --- /dev/null +++ b/debian_NOT_USED/control @@ -0,0 +1,33 @@ +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_NOT_USED/copyright b/debian_NOT_USED/copyright new file mode 100644 index 0000000..74c3188 --- /dev/null +++ b/debian_NOT_USED/copyright @@ -0,0 +1,7 @@ +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_NOT_USED/dirs b/debian_NOT_USED/dirs new file mode 100644 index 0000000..ca882bb --- /dev/null +++ b/debian_NOT_USED/dirs @@ -0,0 +1,2 @@ +usr/bin +usr/sbin diff --git a/debian_NOT_USED/docs b/debian_NOT_USED/docs new file mode 100644 index 0000000..a0f0008 --- /dev/null +++ b/debian_NOT_USED/docs @@ -0,0 +1 @@ +CMakeLists.txt diff --git a/debian_NOT_USED/libcontacts-service-dev.install.in b/debian_NOT_USED/libcontacts-service-dev.install.in new file mode 100644 index 0000000..1bcdd80 --- /dev/null +++ b/debian_NOT_USED/libcontacts-service-dev.install.in @@ -0,0 +1,4 @@ +@PREFIX@/lib/*.so +@PREFIX@/include/contacts-svc/*.h +@PREFIX@/lib/pkgconfig/contacts-service.pc + diff --git a/debian_NOT_USED/libcontacts-service.install.in b/debian_NOT_USED/libcontacts-service.install.in new file mode 100644 index 0000000..348fb98 --- /dev/null +++ b/debian_NOT_USED/libcontacts-service.install.in @@ -0,0 +1,2 @@ +@PREFIX@/lib/*.so.* +/opt/* diff --git a/debian_NOT_USED/libcontacts-service.postinst.in b/debian_NOT_USED/libcontacts-service.postinst.in new file mode 100755 index 0000000..5f04744 --- /dev/null +++ b/debian_NOT_USED/libcontacts-service.postinst.in @@ -0,0 +1,25 @@ +#!/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_NOT_USED/rules b/debian_NOT_USED/rules new file mode 100755 index 0000000..5b1c2fe --- /dev/null +++ b/debian_NOT_USED/rules @@ -0,0 +1,115 @@ +#!/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/include/contacts.h b/include/contacts.h new file mode 100644 index 0000000..89e4c03 --- /dev/null +++ b/include/contacts.h @@ -0,0 +1,1316 @@ +/* + * 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_H__ +#define __TIZEN_SOCIAL_CONTACTS_H__ + +#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_utils.h> +#include <contacts_phone_log.h> + +#endif //__TIZEN_SOCIAL_CONTACTS_H__ + +/** + * @ingroup CAPI_SOCIAL_FRAMEWORK + * @defgroup CAPI_SOCIAL_CONTACTS_SVC_MODULE Contacts(New) + * + * @brief The Contacts Service API provides functions for managing phone contacts (a.k.a. phonebook). + * This API allows you not only to store information about contacts but also to query contact information. + * + * @section CAPI_SOCIAL_CONTACTS_SVC_MODULE_HEADER Required Header + * \#include <contacts.h> + * + * @section CAPI_SOCIAL_CONTACTS_SVC_MODULE_OVERVIEW Overview + * + * The basic concept in Contacts APi 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. 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. + * + * Effectively, a record can be a node in a tree or graph of relations between records. + * + * Each record type has a special structure defined for it, called 'view', which contains identifiers of its properties. + * 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. The address record is described by + * the _contacts_address view. A special property in such structures is the URI, which is used to identify + * the record's type. Every view describing a record has this property. You can think of views + * as of classes in an object oriented language. Whenever you use a record, you refer to its view to know + * the record's properties. + * + * To operate on a record, you must obtain its handle. The handle is provided during creation of the record. + * It can also be obtained when referring to a child record of a record the handle of which you already have. + * + * 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. The code below creates a contact record and obtains its handle. + * + * @code + * contacts_record_h hcontact = NULL; + * contacts_record_create( _contacts_contact._uri, &hcontact ); + * @endcode + * + * A record can have basic properties of four 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> contacts_record_set_str </td> + * <td> contacts_record_get_str </td> + * </tr> + * <tr> + * <td> integer </td> + * <td> contacts_record_set_int </td> + * <td> contacts_record_get_int </td> + * </tr> + * <tr> + * <td> boolean </td> + * <td> contacts_record_set_bool </td> + * <td> contacts_record_get_bool </td> + * </tr> + * <tr> + * <td> long integer </td> + * <td> contacts_record_set_lli </td> + * <td> contacts_record_get_lli </td> + * </tr> + * <tr> + * <td> long integer </td> + * <td> contacts_record_set_double </td> + * <td> contacts_record_get_double </td> + * </tr> + * </table> + * + * For long integer functions, "lli" stands for long long int, ususally used to hold UTC time. + * + * These functions also require specifying which property you wish to get/set. The code below sets the "ringtone_path" + * property of a contact record. + * + * @code + * contacts_record_set_str( hcontact, _contacts_contact.ringtone_path , "My Documents/1.mp3" ); + * @endcode + * + * Note on returned values ownership: some functions 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. For example: + * + * @code + * API int contacts_record_get_str( contacts_record_h record, unsigned int property_id, char** out_str ); + * API int contacts_record_get_str_p( contacts_record_h record, unsigned int property_id, char** out_str ); + * @endcode + * + * In the first case, the returned string should be freed by the application, in the second one it should not. + * + * + * A record can also have properties of type 'record' - other records, called child records. + * A record can contain many child records of a given type. For example, a contact record + * can contain many address records, and is called the parent record of the address records. + * 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. + * + * @code + * contacts_record_h haddress = NULL; + * contacts_record_h himage = NULL; + * contacts_record_create( _contacts_contact._uri, &hcontact ); + * contacts_record_create( _contacts_image._uri, &himage ); + * contacts_record_create( _contacts_address._uri, &haddress ); + * contacts_record_set_str( himage, _contacts_image.path, "My Documents/1.jpg" ); + * contacts_record_set_str( hcontact, _contacts_address.country, "Korea" ); + * contacts_record_add_child_record( hcontact, _contacts_contact.image, himage ); + * contacts_record_add_child_record( hcontact, _contacts_contact.address, haddress ); + * + * contacts_db_insert_record( hcontact ); + * contacts_record_destroy( hcontact, true ); + * @endcode + * + * Establishing parent/child relation between records is also possible + * through the use of identifiers, described in following paragraphs. + * + * One of record's properties is the identifier (id). If you know the id of a record existing in the database, + * you can directly access it. The id is available after the record has been inserted into the database + * and is a read-only property. + * + * @code + * contacts_record_h haddress = NULL; + * contacts_record_create( _contacts_contact._uri, &hcontact ); + * contacts_db_insert_record( hcontact ); + * int id = contacts_record_get_int( hcontact, _contacts_contact.id ); + * // use hcontact ... + * // ... + * contacts_record_destroy( hcontact, true); // hcontact is no longer usable + * + * contacts_db_get_record( _contacts_contact._uri, id, &hcontact ); + * // hcontact is now a handle to the same record as before + * @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 acts as a foreign key here. 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 + * the parent record. + * + * @code + * contacts_record_create( _contacts_contact._uri, &hcontact ); + * int id = ... // acquire id of created contact + * + * contacts_record_create( _contacts_address._uri, &haddress ); + * contacts_record_set_int( haddress, _contacts_address.contact_id, id ); + * // set other address properties + * contacts_db_insert_record( haddress ); + * @endcode + * + * As mentioned above, a record can have many child records, just as more than one record in a database can have + * its foreign keys set to the id of another record. + * Having a record handle, you can access all records of a specific type related to the given record: + * + * @code + * contacts_db_get_record( _contacts_contact._uri, id, &hcontact ); + * int address_num = contacts_record_get_child_record_count( hcontact, _contacts_contact.address ); + * for( int i=0; i < address_num; i++ ) + * { + * haddress = contacts_record_get_child_record_at( hcontact, _contacts_contact.address, i ); + * contacts_record_set_str( haddress, _contacts_address.country, "Korea" ); + * } + * contacts_db_update_record( hcontact ); + * + * contacts_record_destroy( hcontact, true ); + * @endcode + * + * This code acquires the number of child records of type 'address' and iterates over them. Each address + * has its 'country' property set to 'Korea'. Only the parent record is saved to the database - all changes + * made to the child records are saved automatically. + * + * + * Another two important concepts in Contacts API are filters and queries, related to searching. + * Filters allow returning results that satisfy a given condition, e.g. an integer property + * value must be greater than a given value, or a string must contain a given substring. Many + * conditions can be added to a filter, creating a composite filter with the use of AND and OR logical operators. + * + * A query acts as a container for filters and as an interface to the stored data. It allows configuring + * sorting and grouping methods of returned results. + * + * 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 + * + * A query can contain more than one fiter. You can add logical operators between filters. Whole filters + * are operators' arguments, not just the conditions. Extending the example above, the following code creates two filters + * and connects them with the OR operator: + * + * @code + * contacts_filter_h filter1 = NULL; + * contacts_filter_h filter2 = NULL; + * contacts_query_h query = NULL; + * + * contacts_filter_create( _contacts_address._uri, &filter1 ); + * contacts_filter_add_int( filter1, _contacts_address.contact_id, CONTACTS_MATCH_EQUAL, id ); + * contacts_filter_add_operator( filter1, CONTACTS_FILTER_OPERATOR_OR); + * contacts_filter_add_str( filter1, _contacts_address.country, CONTACTS_MATCH_EXACTLY, "Korea" ); + * + * contacts_filter_create( _contacts_address._uri, &filter2 ); + * contacts_filter_add_str( filter2, _contacts_address.country, CONTACTS_MATCH_EXACTLY, "USA" ); + * contacts_filter_add_operator( filter2, CONTACTS_FILTER_OPERATOR_AND); + * contacts_filter_add_str( filter2, _contacts_address.region, CONTACTS_MATCH_CONTAINS, "California" ); + * + * contacts_filter_add_operator(filter1, CONTACTS_FILTER_OPERATOR_OR); + * contacts_filter_add_filter(filter1, filter2); + * + * contacts_query_create( _contacts_address._uri, &query ); + * contacts_query_set_filter(query, filter1); + * + * contacts_db_get_records_with_query( query, 0, 0, &list ); + * + * contacts_filter_destroy( filter1 ); + * contacts_filter_destroy( filter2 ); + * contacts_query_destroy( query ); + * // ... + * @endcode + * + * The first filter accepts addresses with country equal to "Korea" or contact id equal to 'id' variable. + * The second filter accepts addresses with "USA" as country and region containing the string "California". + * The query in the code above will return addresses accepted by either of the filters. + * + * Furthermore, the order in which filters and operators are added determines the placement of parentheses. + * For example, If the following are added, in given order: + * + * @code + * Filter F1 + * OR + * Filter F2 + * AND + * Filter F3 + * @endcode + * + * the result is: + * + * @code + * (F1 OR F2) AND F3 + * @endcode + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_View_properties View properties + * In \ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE category, you can find tables with view properties. 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). + * + * Properties of type 'record' are other 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. + * + */ + +/** + * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE + * @defgroup CAPI_SOCIAL_CONTACTS_SVC_DATABASE_MODULE Database + * + * @brief The contacts database API provides the set of the definitions and interfaces that enable you to handle contacts database. + * + * @section CAPI_SOCIAL_CONTACTS_SVC_DATABASE_MODULE_HEADER Required Header + * \#include <contacts.h> + * + * <BR> + */ + +/** + * @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 you to get/set data from/to contacts record handle. + * + * @section CAPI_SOCIAL_CONTACTS_SVC_RECORD_MODULE_HEADER Required Header + * \#include <contacts.h> + * + * <BR> + */ + +/** + * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE + * @defgroup CAPI_SOCIAL_CONTACTS_SVC_LIST_MODULE List + * + * @brief The contacts record API provides the set of the definitions and interfaces that enable you to get/set records list data. + * + * @section CAPI_SOCIAL_CONTACTS_SVC_LIST_MODULE_HEADER Required Header + * \#include <contacts.h> + * + * <BR> + */ + +/** + * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE + * @defgroup CAPI_SOCIAL_CONTACTS_SVC_PERSON_MODULE Person + * + * @brief The contacts person API provides the set of the definitions and interfaces that enable you to link/unlink person and contact. + * + * @section CAPI_SOCIAL_CONTACTS_SVC_PERSON_MODULE_HEADER Required Header + * \#include <contacts.h> + * + * <BR> + */ + +/** + * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE + * @defgroup CAPI_SOCIAL_CONTACTS_SVC_GROUP_MODULE Group + * + * @brief The contacts group API provides the set of the definitions and interfaces that enable you to add/remove contact as group member. + * + * @section CAPI_SOCIAL_CONTACTS_SVC_GROUP_MODULE_HEADER Required Header + * \#include <contacts.h> + * + * <BR> + */ + + +/** + * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE + * @defgroup CAPI_SOCIAL_CONTACTS_SVC_FILTER_MODULE Filter + * + * @brief The contacts Filter API provides the set of the definitions and interfaces that enable you to make filters to set query. + * + * @section CAPI_SOCIAL_CONTACTS_SVC_CONTACTS_FILTER_HEADER Required Header + * \#include <contacts.h> + * + * <BR> + */ + +/** + * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE + * @defgroup CAPI_SOCIAL_CONTACTS_SVC_QUERY_MODULE Query + * + * @brief The contacts Query API provides the set of the definitions and interfaces that enable you to make query to get list. + * + * @section CAPI_SOCIAL_CONTACTS_SVC_CONTACTS_QUERY_HEADER Required Header + * \#include <contacts.h> + * + * <BR> + */ + +/** + * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE + * @defgroup CAPI_SOCIAL_CONTACTS_SVC_VCARD_MODULE vCard + * + * @brief The contacts record API provides the set of the definitions and interfaces that enable you to get/set data from/to vCard. + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VCARD_MODULE_HEADER Required Header + * \#include <contacts.h> + * + * <BR> + */ + +/** + * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE + * @defgroup CAPI_SOCIAL_CONTACTS_SVC_ACTIVITY_MODULE Activity + * + * @brief The contacts activity API provides the set of the definitions and interfaces that enable you to delete activities by contact_id and account_id. \n + * Please refer to \ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_activity for more details. + * + * @section CAPI_SOCIAL_CONTACTS_SVC_ACTIVITY_MODULE_HEADER Required Header + * \#include <contacts.h> + * + * <BR> + */ + +/** + * @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 the definitions and interfaces that enable you to reset phone log count. + * + * @section CAPI_SOCIAL_CONTACTS_SVC_PHONELOG_MODULE_HEADER Required Header + * \#include <contacts.h> + * + * <BR> + */ + +/** + * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE + * @defgroup CAPI_SOCIAL_CONTACTS_SVC_SETTING_MODULE Setting + * + * @brief The contacts setting API provides the set of the definitions and interfaces that enable you to set up contacts features. + * + * @section CAPI_SOCIAL_CONTACTS_SVC_SETTING_MODULE_HEADER Required Header + * \#include <contacts.h> + * + * <BR> + */ + +/** + * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE + * @defgroup CAPI_SOCIAL_CONTACTS_SVC_SIM_MODULE SIM + * + * @brief The contacts SIM API provides the set of the definitions and interfaces that enable you to get/set data from/to SIM card. + * + * @section CAPI_SOCIAL_CONTACTS_SVC_CONTACTS_SIM_HEADER Required Header + * \#include <contacts.h> + * + * <BR> + */ + +/** + * @ingroup CAPI_SOCIAL_CONTACTS_SVC_MODULE + * @defgroup CAPI_SOCIAL_CONTACTS_SVC_UTILS_MODULE Utils + * + * @brief The contacts Utils API provides the set of the definitions and interfaces that enable you to get index characters of language according to phone setting + * + * @section CAPI_SOCIAL_CONTACTS_SVC_CONTACTS_UTILS_HEADER Required Header + * \#include <contacts.h> + * + * <BR> + */ + +/** + * @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_OVERVIEW Overview + * A view is a structure which describes properties of a record. + * A record can have basic properties of four 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> contacts_record_set_str </td> + * <td> contacts_record_get_str </td> + * </tr> + * <tr> + * <td> integer </td> + * <td> contacts_record_set_int </td> + * <td> contacts_record_get_int </td> + * </tr> + * <tr> + * <td> boolean </td> + * <td> contacts_record_set_bool </td> + * <td> contacts_record_get_bool </td> + * </tr> + * <tr> + * <td> long integer </td> + * <td> contacts_record_set_lli </td> + * <td> contacts_record_get_lli </td> + * </tr> + * <tr> + * <td> long integer </td> + * <td> contacts_record_set_double </td> + * <td> contacts_record_get_double </td> + * </tr> + * </table> + * + * For long integer functions, "lli" stands for long long int, ususally used to hold UTC time. + * + * Below you can find tables with view properties. + * + * 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. + * + * Please refer to the main section of Contacts API for a more detailed explanation and examples. + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_HEADER Required Header + * \#include <contacts.h> + * + * @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> View uri for contact </td></tr> + * <tr><td>integer</td><td>id</td><td>read only</td><td></td></tr> + * <tr><td>string</td><td>display_name</td><td>read only</td><td></td></tr> + * <tr><td>integer</td><td>display_source_id</td><td>read only</td><td>The source type of display name contacts_display_name_source_type_e</td></tr> + * <tr><td>integer</td><td>address_book_id</td><td>read, write once</td><td></td></tr> + * <tr><td>string</td><td>ringtone_path</td><td>read, write</td><td></td></tr> + * <tr><td>string</td><td>image_thumbnail_path</td><td>read only</td><td></td></tr> + * <tr><td>boolean</td><td>is_favorite</td><td>read, write</td><td></td></tr> + * <tr><td>boolean</td><td>has_phonenumber</td><td>read only</td><td></td></tr> + * <tr><td>boolean</td><td>has_email</td><td>read only</td><td></td></tr> + * <tr><td>integer</td><td>person_id</td><td>read only</td><td></td></tr> + * <tr><td>string</td><td>uid</td><td>read, write</td><td></td></tr> + * <tr><td>string</td><td>vibration</td><td>read, write</td><td></td></tr> + * <tr><td>integer</td><td>changed_time</td><td>read only</td><td></td></tr> + * <tr><td>record</td><td>name</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>company</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>note</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>number</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>email</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>event</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>messenger</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>address</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>url</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>nickname</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>profile</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>relationship</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>image</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>group_relation</td><td>read, write</td><td></td></tr> + * </table> + * + * @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> View uri for my profile </td></tr> + * <tr><td>integer</td><td>id</td><td>read only</td><td></td></tr> + * <tr><td>string</td><td>display_name</td><td>read only</td><td></td></tr> + * <tr><td>integer</td><td>address_book_id</td><td>read, write once</td><td></td></tr> + * <tr><td>string</td><td>image_thumbnail_path</td><td>read only</td><td></td></tr> + * <tr><td>string</td><td>uid</td><td>read, write</td><td></td></tr> + * <tr><td>integer</td><td>changed_time</td><td>read only</td><td></td></tr> + * <tr><td>record</td><td>name</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>company</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>note</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>number</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>email</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>event</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>messenger</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>address</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>url</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>nickname</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>profile</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>relationship</td><td>read, write</td><td></td></tr> + * <tr><td>record</td><td>image</td><td>read, write</td><td></td></tr> + * </table> + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_simple_contact _contacts_simple_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> </td></tr> + * <tr><td>integer</td><td>id</td><td>read only</td><td> </td></tr> + * <tr><td>string</td><td>display_name</td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td>display_source_id</td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td>address_book_id</td><td>read, write once</td><td> </td></tr> + * <tr><td>string</td><td>ringtone_path</td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td>image_thumbnail_path</td><td>read only</td><td> </td></tr> + * <tr><td>boolean</td><td>is_favorite</td><td>read, write</td><td> </td></tr> + * <tr><td>boolean</td><td>has_phonenumber</td><td>read only</td><td> </td></tr> + * <tr><td>boolean</td><td>has_email</td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td>person_id</td><td>read only</td><td> </td></tr> + * <tr><td>string</td><td>uid</td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td>vibration</td><td>read, write</td><td> </td></tr> + * <tr><td>integer</td><td>changed_time</td><td>read only</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>string</td><td> display_name </td><td>read only</td><td> </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. </td></tr> + * <tr><td>integer</td><td> display_contact_id </td><td>read only</td><td> </td></tr> + * <tr><td>string</td><td> ringtone_path </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> image_thumbnail_path </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> vibration </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> status </td><td>read only</td><td> </td></tr> + * <tr><td>boolean</td><td> is_favorite </td><td>read, write</td><td> </td></tr> + * <tr><td>double</td><td> favorite_priority </td><td> filter only </td><td> The priority of favorite contacts. You can not set the value but you can use it as sorting key. </td></tr> + * <tr><td>integer</td><td> link_count </td><td>read, write</td><td> </td></tr> + * <tr><td>integer</td><td> account_id1 </td><td>read, write</td><td> </td></tr> + * <tr><td>integer</td><td> account_id2 </td><td>read, write</td><td> </td></tr> + * <tr><td>integer</td><td> account_id3 </td><td>read, write</td><td> </td></tr> + * <tr><td>integer</td><td> addressbook_ids </td><td>read, write</td><td> </td></tr> + * <tr><td>boolean</td><td> has_phonenumber </td><td>read only</td><td> </td></tr> + * <tr><td>boolean</td><td> has_email </td><td>read only</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> account_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>string</td><td> name </td><td>read, write</td><td> It can not be NULL. Duplicate names are not allowed. </td></tr> + * <tr><td>integer</td><td> mode </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> address_book_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>string</td><td> name </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> ringtone_path </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> image_path </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> vibration </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> system_id </td><td>read, write</td><td> </td></tr> + * <tr><td>boolean</td><td> is_read_only </td><td>read only</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>string</td><td> first </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> last </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> addition </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> suffix </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> prefix </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> phonetic_first </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> phonetic_middle </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> phonetic_last </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>integer</td><td> type </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> label </td><td>read, write</td><td> </td></tr> + * <tr><td>boolean</td><td> is_default </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> number </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>integer</td><td> type </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> label </td><td>read, write</td><td> </td></tr> + * <tr><td>boolean</td><td> is_default </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> email </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>integer</td><td> type </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> label </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> postbox </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> postal_code </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> region </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> locality </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> street </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> country </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> extend </td><td>read, write</td><td> </td></tr> + * <tr><td>boolean</td><td> is_default </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>string</td><td> note </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>integer</td><td> type </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> label </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> url </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>integer</td><td> type </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> label </td><td>read, write</td><td> </td></tr> + * <tr><td>integer</td><td> date </td><td>read, write</td><td> </td></tr> + * <tr><td>integer</td><td> is_lunar </td><td>read, write</td><td> </td></tr> + * <tr><td>integer</td><td> lunar_date </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>integer</td><td> type </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> label </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> name </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>integer</td><td> type </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> label </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> path </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>integer</td><td> type </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> label </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> name </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> department </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> job_title </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> assistant_name </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> role </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> logo </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> location </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> description </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> phonetic_name </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>string</td><td> nickname </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>integer</td><td> type </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> label </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> im_id </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>integer</td><td> data1 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> data2 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> data3 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> data4 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> data5 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> data6 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> data7 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> data8 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> data9 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> data10 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> data11 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> data12 </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>string</td><td> name </td><td>read, write once</td><td> </td></tr> + * <tr><td>string</td><td> number </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>integer</td><td> type </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> label </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> uid </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> text </td><td>read, write</td><td> </td></tr> + * <tr><td>integer</td><td> order </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> appsvc_operation </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> data1 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> data2 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> data3 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> data4 </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> contact_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>string</td><td> source_name </td><td>read, write</td><td> </td></tr> + * <tr><td>int</td><td> timestamp </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> status </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> sync_data1 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> sync_data2 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> sync_data3 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> sync_data4 </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> photo </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> activity_id </td><td>read, write once</td><td> </td></tr> + * <tr><td>string</td><td> photo_url </td><td>read, write</td><td> </td></tr> + * <tr><td>integer</td><td> sort_index </td><td>read, write</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> speeddial_number </td><td>read, write</td><td> </td></tr> + * <tr><td>integer</td><td> number_id </td><td>read, write</td><td> </td></tr> + * <tr><td>string</td><td> number </td><td>read only</td><td> </td></tr> + * <tr><td>string</td><td> number_label </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> number_type </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> person_id </td><td>read only</td><td> </td></tr> + * <tr><td>string</td><td> display_name </td><td>read only</td><td> </td></tr> + * <tr><td>string</td><td> image_thumbnail_path </td><td>read only</td><td> </td></tr> + * </table> + * + * @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> </td></tr> + * <tr><td>integer</td><td> id </td><td>read only</td><td> </td></tr> + * <tr><td>integer</td><td> person_id </td><td>read, write once </td><td> </td></tr> + * <tr><td>string</td><td> address </td><td>read, write once </td><td> </td></tr> + * <tr><td>integer</td><td> log_time </td><td>read, write once</td><td> </td></tr> + * <tr><td>integer</td><td> log_type </td><td>read, write</td><td> </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 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> + * </table> + * +* <br><br> +* Read-only View URIs +* <br> + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact_updated_info _contacts_contact_updated_info view + * <table> + * <tr> + * <th>Type</th> + * <th>Property ID</th> + * <th>Primay Key</th> + * <th>Description</th> + * </tr> + * <tr><td>string</td><td>_uri</td><td></td><td> </td></tr> + * <tr><td>integer</td><td> contact_id </td><td>*</td><td> </td></tr> + * <tr><td>integer</td><td> address_book_id </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> type </td><td></td><td> </td></tr> + * </table> + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_group_updated_info _contacts_group_updated_info view + * <table> + * <tr> + * <th>Type</th> + * <th>Property ID</th> + * <th>Primary Key</th> + * <th>Description</th> + * </tr> + * <tr><td>string</td><td>_uri</td><td></td><td> </td></tr> + * <tr><td>integer</td><td> group_id </td><td>*</td><td> </td></tr> + * <tr><td>integer</td><td> address_book_id </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> type </td><td></td><td> </td></tr> + * </table> + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_number _contacts_person_number view + * <table> + * <tr> + * <th>Type</th> + * <th>Property ID</th> + * <th>Primary Key</th> + * <th>Description</th> + * </tr> + * <tr><td>string</td><td>_uri</td><td></td><td> </td></tr> + * <tr><td>integer</td><td> person_id </td><td></td><td> </td></tr> + * <tr><td>string</td><td> display_name </td><td></td><td> </td></tr> + * <tr><td>string</td><td> display_name_index </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> display_contact_id </td><td></td><td> </td></tr> + * <tr><td>string</td><td> ringtone_path </td><td></td><td> </td></tr> + * <tr><td>string</td><td> image_thumbnail_path </td><td></td><td> </td></tr> + * <tr><td>string</td><td> vibration </td><td></td><td> </td></tr> + * <tr><td>boolean</td><td> is_favorite </td><td></td><td> </td></tr> + * <tr><td>boolean</td><td> has_phonenumber </td><td></td><td> </td></tr> + * <tr><td>boolean</td><td> has_email </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> number_id </td><td>*</td><td> </td></tr> + * <tr><td>integer</td><td> type </td><td></td><td> </td></tr> + * <tr><td>string</td><td> label </td><td></td><td> </td></tr> + * <tr><td>boolean</td><td> is_primary_default </td><td></td><td> </td></tr> + * <tr><td>string</td><td> number </td><td></td><td> </td></tr> + * <tr><td>string</td><td> number_filter </td><td></td><td> If you add filter with this property, the string will be normalized internally and the match rule will be applied CONTACTS_MATCH_EXACTLY </td></tr> + * </table> + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_email _contacts_person_email view + * <table> + * <tr> + * <th>Type</th> + * <th>Property ID</th> + * <th>Primary Key</th> + * <th>Description</th> + * </tr> + * <tr><td>string</td><td>_uri</td><td></td><td> </td></tr> + * <tr><td>integer</td><td> person_id </td><td></td><td> </td></tr> + * <tr><td>string</td><td> display_name </td><td></td><td> </td></tr> + * <tr><td>string</td><td> display_name_index </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> display_contact_id </td><td></td><td> </td></tr> + * <tr><td>string</td><td> ringtone_path </td><td></td><td> </td></tr> + * <tr><td>string</td><td> image_thumbnail_path </td><td></td><td> </td></tr> + * <tr><td>string</td><td> vibration </td><td></td><td> </td></tr> + * <tr><td>boolean</td><td> is_favorite </td><td></td><td> </td></tr> + * <tr><td>boolean</td><td> has_phonenumber </td><td></td><td> </td></tr> + * <tr><td>boolean</td><td> has_email </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> email_id </td><td>*</td><td> </td></tr> + * <tr><td>integer</td><td> type </td><td></td><td> </td></tr> + * <tr><td>string</td><td> label </td><td></td><td> </td></tr> + * <tr><td>boolean</td><td> is_primary_default </td><td></td><td> </td></tr> + * <tr><td>string</td><td> email </td><td></td><td> </td></tr> + * </table> + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_grouprel _contacts_person_grouprel view + * <table> + * <tr> + * <th>Type</th> + * <th>Property ID</th> + * <th>Primary Key</th> + * <th>Description</th> + * </tr> + * <tr><td>string</td><td>_uri</td><td></td><td> </td></tr> + * <tr><td>integer</td><td> person_id </td><td>*</td><td> </td></tr> + * <tr><td>string</td><td> display_name </td><td></td><td> </td></tr> + * <tr><td>string</td><td> display_name_index </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> display_contact_id </td><td></td><td> </td></tr> + * <tr><td>string</td><td> ringtone_path </td><td></td><td> </td></tr> + * <tr><td>string</td><td> image_thumbnail_path </td><td></td><td> </td></tr> + * <tr><td>string</td><td> vibration </td><td></td><td> </td></tr> + * <tr><td>string</td><td> status </td><td></td><td> </td></tr> + * <tr><td>boolean</td><td> is_favorite </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> link_count </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> account_id1 </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> account_id2 </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> account_id3 </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> addressbook_ids </td><td></td><td> </td></tr> + * <tr><td>boolean</td><td> has_phonenumber </td><td></td><td> </td></tr> + * <tr><td>boolean</td><td> has_email </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> address_book_id </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> group_id </td><td>*</td><td> </td></tr> + * <tr><td>string</td><td> group_name </td><td></td><td> </td></tr> + * </table> + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_phone_log _contacts_person_phone_log view + * <table> + * <tr> + * <th>Type</th> + * <th>Property ID</th> + * <th>Primary Key</th> + * <th>Description</th> + * </tr> + * <tr><td>string</td><td>_uri</td><td></td><td> </td></tr> + * <tr><td>integer</td><td> person_id </td><td> * </td><td> </td></tr> + * <tr><td>string</td><td> display_name </td><td></td><td> </td></tr> + * <tr><td>string</td><td> image_thumbnail_path </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> log_id </td><td> * </td><td> </td></tr> + * <tr><td>string</td><td> address </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> log_time </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> log_type </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> extra_data1 </td><td></td><td> </td></tr> + * <tr><td>string</td><td> extra_data2 </td><td></td><td> </td></tr> + * </table> + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_usage _contacts_person_usage view + * <table> + * <tr> + * <th>Type</th> + * <th>Property ID</th> + * <th>Primary Key</th> + * <th>Description</th> + * </tr> + * <tr><td>string</td><td>_uri</td><td></td><td> </td></tr> + * <tr><td>integer</td><td> person_id </td><td>*</td><td> </td></tr> + * <tr><td>string</td><td> display_name </td><td></td><td> </td></tr> + * <tr><td>string</td><td> display_name_index </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> display_contact_id </td><td></td><td> </td></tr> + * <tr><td>string</td><td> ringtone_path </td><td></td><td> </td></tr> + * <tr><td>string</td><td> image_thumbnail_path </td><td></td><td> </td></tr> + * <tr><td>string</td><td> vibration </td><td></td><td> </td></tr> + * <tr><td>boolean</td><td> is_favorite </td><td></td><td> </td></tr> + * <tr><td>boolean</td><td> has_phonenumber </td><td></td>><td> </td></tr> + * <tr><td>boolean</td><td> has_email </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> usage_type </td><td></td>*<td> </td></tr> + * <tr><td>integer</td><td> times_used </td><td></td><td> </td></tr> + * </table> + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact_number _contacts_contact_number view + * <table> + * <tr> + * <th>Type</th> + * <th>Property ID</th> + * <th>Primary Key</th> + * <th>Description</th> + * </tr> + * <tr><td>string</td><td>_uri</td><td></td><td> </td></tr> + * <tr><td>integer</td><td>contact_id</td><td></td><td> </td></tr> + * <tr><td>string</td><td>display_name</td><td></td><td> </td></tr> + * <tr><td>integer</td><td>display_source_type</td><td></td><td> </td></tr> + * <tr><td>integer</td><td>address_book_id</td><td></td><td> </td></tr> + * <tr><td>integer</td><td>person_id</td><td></td><td> </td></tr> + * <tr><td>string</td><td>ringtone_path</td><td></td><td> </td></tr> + * <tr><td>string</td><td>image_thumbnail_path</td><td></td><td> </td></tr> + * <tr><td>integer</td><td> number_id </td><td>*</td><td> </td></tr> + * <tr><td>integer</td><td> type </td><td></td><td> </td></tr> + * <tr><td>string</td><td> label </td><td></td><td> </td></tr> + * <tr><td>boolean</td><td> is_ default </td><td></td><td> </td></tr> + * <tr><td>string</td><td> number </td><td></td><td> </td></tr> + * <tr><td>string</td><td> number_filter </td><td></td><td> If you add filter with this property, the string will be normalized internally and the match rule will be applied CONTACTS_MATCH_EXACTLY </td></tr> + * </table> + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact_email _contacts_contact_email view + * <table> + * <tr> + * <th>Type</th> + * <th>Property ID</th> + * <th>Primary Key</th> + * <th>Description</th> + * </tr> + * <tr><td>string</td><td>_uri</td><td></td><td> </td></tr> + * <tr><td>integer</td><td>contact_id</td><td></td><td> </td></tr> + * <tr><td>string</td><td>display_name</td><td></td><td> </td></tr> + * <tr><td>integer</td><td>display_source_type</td><td></td><td> </td></tr> + * <tr><td>integer</td><td>address_book_id</td><td></td><td> </td></tr> + * <tr><td>integer</td><td>person_id</td><td></td><td> </td></tr> + * <tr><td>string</td><td>ringtone_path</td><td></td><td> </td></tr> + * <tr><td>string</td><td>image_thumbnail_path</td><td></td><td> </td></tr> + * <tr><td>integer</td><td> email_id </td><td>*</td><td> </td></tr> + * <tr><td>integer</td><td> type </td><td></td><td> </td></tr> + * <tr><td>string</td><td> label </td><td></td><td> </td></tr> + * <tr><td>boolean</td><td> is_ default </td><td></td><td> </td></tr> + * <tr><td>string</td><td> email </td><td></td><td> </td></tr> + * </table> + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact_grouprel _contacts_contact_grouprel view + * <table> + * <tr> + * <th>Type</th> + * <th>Property ID</th> + * <th>Primary Key</th> + * <th>Description</th> + * </tr> + * <tr><td>string</td><td>_uri</td><td></td><td> </td></tr> + * <tr><td>integer</td><td>contact_id</td><td>*</td><td> </td></tr> + * <tr><td>string</td><td>display_name</td><td></td><td> </td></tr> + * <tr><td>integer</td><td>display_source_type</td><td></td><td> </td></tr> + * <tr><td>integer</td><td>address_book_id</td><td></td><td> </td></tr> + * <tr><td>integer</td><td>person_id</td><td></td><td> </td></tr> + * <tr><td>string</td><td>ringtone_path</td><td></td><td> </td></tr> + * <tr><td>string</td><td>image_thumbnail_path</td><td></td><td> </td></tr> + * <tr><td>integer</td><td> group_id </td><td>*</td><td> </td></tr> + * <tr><td>string</td><td> group_name </td><td></td><td> </td></tr> + * </table> + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact_activity _contacts_contact_activity view + * <table> + * <tr> + * <th>Type</th> + * <th>Property ID</th> + * <th>Primary Key</th> + * <th>Description</th> + * </tr> + * <tr><td>string</td><td>_uri</td><td></td><td> </td></tr> + * <tr><td>integer</td><td>contact_id</td><td></td><td> </td></tr> + * <tr><td>string</td><td>display_name</td><td></td><td> </td></tr> + * <tr><td>integer</td><td>display_source_type</td><td></td><td> </td></tr> + * <tr><td>integer</td><td>address_book_id</td><td></td><td> </td></tr> + * <tr><td>integer</td><td>person_id</td><td></td><td> </td></tr> + * <tr><td>string</td><td>ringtone_path</td><td></td><td> </td></tr> + * <tr><td>string</td><td>image_thumbnail_path</td><td></td><td> </td></tr> + * <tr><td>integer</td><td> activity_id </td><td>*</td><td> </td></tr> + * <tr><td>string</td><td> source_name </td><td></td><td> </td></tr> + * <tr><td>string</td><td> status </td><td></td><td> </td></tr> + * <tr><td>integer</td><td> timestamp </td><td></td><td> </td></tr> + * <tr><td>string</td><td> sync_data1 </td><td></td><td> </td></tr> + * <tr><td>string</td><td> sync_data2 </td><td></td><td> </td></tr> + * <tr><td>string</td><td> sync_data3 </td><td></td><td> </td></tr> + * <tr><td>string</td><td> sync_data4 </td><td></td><td> </td></tr> + * </table> + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log_number _contacts_phone_log_number view + * <table> + * <tr> + * <th>Type</th> + * <th>Property ID</th> + * <th>Primary Key</th> + * <th>Description</th> + * </tr> + * <tr><td>string</td><td>_uri</td><td></td><td> </td></tr> + * <tr><td>string</td><td> number </td><td> * </td><td> </td></tr> + * </table> + * + * @section CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_phone_log_stat _contacts_phone_log_stat view + * <table> + * <tr> + * <th>Type</th> + * <th>Property ID</th> + * <th>Primary Key</th> + * <th>Description</th> + * </tr> + * <tr><td>string</td><td>_uri</td><td></td><td> </td></tr> + * <tr><td>integer</td><td> log_count </td><td> </td><td> </td></tr> + * <tr><td>integer</td><td> log_type </td><td> * </td><td> </td></tr> + * </table> + */ + diff --git a/include/contacts_activity.h b/include/contacts_activity.h new file mode 100644 index 0000000..815d6fa --- /dev/null +++ b/include/contacts_activity.h @@ -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_ACTIVITY_H__
+#define __TIZEN_SOCIAL_CONTACTS_ACTIVITY_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_ACTIVITY_MODULE
+ * @{
+ */
+
+/**
+ * @brief Deletes activity record from the contacts database by contact id.
+ *
+ * @param[in] contact_id The contact ID to delete
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #CONTACTS_ERROR_NONE Successful
+ * @retval #CONTACTS_ERROR_DB Database operation failure
+ *
+ * @pre This function requires an open connection to contacts service by contacts_connect2().
+ *
+ * @see contacts_connect2()
+ */
+API int contacts_activity_delete_by_contact_id(int contact_id);
+
+/**
+ * @brief Deletes activity record from the contacts database by account id.
+ *
+ * @param[in] account_id The account ID to delete
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval #CONTACTS_ERROR_NONE Successful
+ * @retval #CONTACTS_ERROR_DB Database operation failure
+ *
+ * @pre This function requires an open connection to contacts service by contacts_connect2().
+ *
+ * @see contacts_connect2()
+ */
+API 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 index 0000000..73de2ca --- /dev/null +++ b/include/contacts_db.h @@ -0,0 +1,591 @@ +/* + * 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 + +/** + * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_DATABASE_MODULE + * @{ + */ + +typedef enum +{ + CONTACTS_CHANGE_INSERTED, /**< . */ + CONTACTS_CHANGE_UPDATED, /**< . */ + CONTACTS_CHANGE_DELETED, /**< . */ +// CONTACTS_CHANGE_BULK_INSERTED, +// CONTACTS_CHANGE_BULK_DELETED +} contacts_changed_e; + +/** + * @brief Called when designated view changes. + * + * @param[in] view_uri The view uri + * @param[in] user_data The user data passed from the callback registration function + * + * @see contacts_db_add_changed_cb() + */ +typedef void (*contacts_db_changed_cb)(const char* view_uri, void* user_data); + +/** + * @brief The callback function to get the result of insert batch operation. + * + * @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() will invoke this callback. + * + * @see contacts_db_insert_records() + */ +typedef void (*contacts_db_insert_result_cb)( int error, int *ids, unsigned int count, void *user_data); + +/** + * @brief The callback function to get the result of batch operation. + * + * @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() will invoke this callback. + * + * @see contacts_db_update_records() + */ +typedef void (*contacts_db_result_cb)( int error, void *user_data); + +/** + * @brief Inserts a record to the contacts database. + * + * @param[in] record The record handle + * + * @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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_db_update_record() + * @see contacts_db_delete_record() + * @see contacts_db_get_record() + */ +API 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 contact will be created, which is filled with contact information. + * + * @remarks @a record must be released with contacts_record_destroy() by you. + * + * @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 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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_record_destroy() + */ +API int contacts_db_get_record( const char* view_uri, int record_id, contacts_record_h* record ); + +/** + * @brief Updates a record to the contacts database. + * + * @param[in] record The record handle + * + * @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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_db_insert_record() + * @see contacts_db_delete_record() + * @see contacts_db_get_record() + */ +API int contacts_db_update_record( contacts_record_h record ); + +/** + * @brief Deletes a record from the contacts database. + * + * @param[in] view_uri The view URI of a record + * @param[in] record_id The record ID to delete + * + * @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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_db_insert_record() + */ +API int contacts_db_delete_record( const char* view_uri, int record_id ); + +/** + * @brief Replace the record to the contacts database related to id. + * + * @remarks @the write once value of record is not replaced. + * + * @param[in] record The new record handle to replace + * @param[in] id The db record ID to replace + * + * @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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_db_update_record() + * @see contacts_db_delete_record() + * @see contacts_db_get_record() + */ +API int contacts_db_replace_record( contacts_record_h record, int id ); + +/** + * @brief Retrieves all record as a list + * + * @remarks @a record_list must be released with contacts_list_destroy() by you. + * + * @param[in] view_uri The view URI to get records + * @param[in] offset The index to get results from which index + * @param[in] limit The number to limit results + * @param[out] record_list The record list + * + * @return 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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_list_destroy() + */ +API int contacts_db_get_all_records( const char* view_uri, int offset, int limit, contacts_list_h* record_list ); + +/** + * @brief Retrieves records with a query handle + * + * @remarks @a record_list must be released with contacts_list_destroy() by you. + * + * @param[in] query The query handle to filter + * @param[in] offset The index to get results from which index + * @param[in] limit The number to limit results + * @param[out] record_list The record list + * + * @return 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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_list_destroy() + */ +API int contacts_db_get_records_with_query( contacts_query_h query, int offset, int limit, contacts_list_h* record_list ); + +/** + * @brief Inserts multiple records as batch operation to the contacts database. + * + * @param[in] record_list The record list handle + * @param[out] ids IDs of inserted records + * @param[out] count The number of ids + * + * @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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_db_update_records() + * @see contacts_db_delete_records() + * @see contacts_db_result_cb() + */ +API int contacts_db_insert_records( contacts_list_h record_list, int **ids, unsigned int *count); + +/** + * @brief Inserts multiple records as batch operation to the contacts database. + * + * @param[in] record_list The record list handle + * @param[in] callback The callback function to invoke which lets you know result of batch operation + * @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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_db_insert_records() + * @see contacts_db_update_records_async() + * @see contacts_db_delete_records_async() + * @see contacts_db_insert_result_cb() + */ +API int contacts_db_insert_records_async( contacts_list_h record_list, contacts_db_insert_result_cb callback, void *user_data); + +/** + * @brief Updates multiple records as batch operation to the contacts database. + * + * @param[in] record_list The record list handle + * + * @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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_db_insert_records() + * @see contacts_db_delete_records() + * @see contacts_db_result_cb() + */ +API int contacts_db_update_records( contacts_list_h record_list); + +/** + * @brief Updates multiple records as batch operation to the contacts database. + * + * @param[in] record_list The record list handle + * @param[in] callback The callback function to invoke which lets you know result of batch operation + * @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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_db_update_records() + * @see contacts_db_insert_records_async() + * @see contacts_db_delete_records_async() + * @see contacts_db_result_cb() + */ +API int contacts_db_update_records_async( contacts_list_h record_list, contacts_db_result_cb callback, void *user_data); + +/** + * @brief Deletes multiple records as batch operation to the contacts database. + * + * @param[in] view_uri The view URI of records + * @param[in] record_id_array The record IDs to delete + * @param[in] count The number of record ID array + * + * @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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_db_insert_records() + * @see contacts_db_update_records() + * @see contacts_db_result_cb() + */ +API int contacts_db_delete_records(const char* view_uri, int record_id_array[], int count); + +/** + * @brief Deletes multiple records as batch operation to the contacts database. + * + * @param[in] view_uri The view URI of records + * @param[in] record_id_array The record IDs to delete + * @param[in] count The number of record ID array + * @param[in] callback The callback function to invoke which lets you know result of batch operation + * @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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_db_delete_records() + * @see contacts_db_insert_records_async() + * @see contacts_db_update_records_async() + * @see contacts_db_result_cb() + */ +API int contacts_db_delete_records_async(const char* view_uri, int record_id_array[], int count, contacts_db_result_cb callback, void *user_data); + +/** + * @brief Replace the record to the contacts database related to id. + * + * @param[in] record The new record list handle to replace + * @param[in] record_id_array The record IDs to replace + * @param[in] count The number of record ID array + * + * @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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_db_update_record() + * @see contacts_db_delete_record() + * @see contacts_db_get_record() + */ +API int contacts_db_replace_records( contacts_list_h list, int record_id_array[], unsigned int count ); + +/** + * @brief Replace the record to the contacts database related to id. + * + * @param[in] record The new record list handle to replace + * @param[in] record_id_array The record IDs to replace + * @param[in] count The number of record ID array + * @param[in] callback The callback function to invoke which lets you know result of batch operation + * @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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_db_replace_record() + * @see contacts_db_update_record_async() + * @see contacts_db_delete_records_async() + * @see contacts_db_get_record() + */ +API int contacts_db_replace_records_async( contacts_list_h list, int record_id_array[], unsigned int count, contacts_db_result_cb callback, void *user_data ); + +/** + * @brief Gets the current contacts database version. + * + * @param[out] contacts_db_version The contacts database version + * + * @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 + * + * @pre This function requires an open connection to the contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_db_get_changes_by_version() + */ +API int contacts_db_get_current_version( int* contacts_db_version ); + +/** + * @brief Registers a callback function to be invoked when the record changes. + * + * @param[in] view_uri The view URI of record to subscribe to changing notifications + * @param[in] callback The callback function to register + * @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 + * + * @pre This function requires an open connection to the contacts service by contacts_connect2(). + * @post contacts_db_changed_cb() will be invoked when the designated view changes. + * + * @see contacts_connect2() + * @see contacts_db_changed_cb() + * @see contacts_db_remove_changed_cb() + */ +API int contacts_db_add_changed_cb( const char* view_uri, contacts_db_changed_cb callback, void* user_data ); + +/** + * @brief Unregisters a callback function. + * + * @param[in] view_uri The view URI of record to subscribe to changing notifications + * @param[in] callback The callback function to register + * @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 + * + * @pre This function requires an open connection to the contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_db_changed_cb() + * @see contacts_db_add_changed_cb() + */ +API int contacts_db_remove_changed_cb( const char* view_uri, contacts_db_changed_cb callback, void* user_data ); + +#ifndef _CONTACTS_NATIVE + +typedef void (*contacts_db_change_cb_with_info)(const char* view_uri, char *changes, void* user_data); + +API int contacts_db_add_changed_cb_with_info(const char* view_uri, contacts_db_change_cb_with_info callback, void* user_data); +API int contacts_db_remove_changed_cb_with_info(const char* view_uri, contacts_db_change_cb_with_info callback, void* user_data); +#endif + +/** + * @brief Retrieves records with the contacts database version. + * + * @details This function will find all changed records since the given @a contacts_db_version + * + * @remarks @a change_record_list must be released with contacts_list_destroy() by you. + * + * @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] record_list The record list + * @param[out] current_contacts_db_version The current contacts database version + * + * @return 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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_list_destroy() + */ +API 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 Retrieves records with a keyword + * + * @remarks @a record_list must be released with contacts_list_destroy() by you. \n + * This API works only for \ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person and \ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_grouprel. + * + * @param[in] view_uri The view URI to get records + * @param[in] keyword Thekeyword + * @param[in] offset The index to get results from which index + * @param[in] limit The number to limit results + * @param[out] record_list The record list + * + * @return 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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_list_destroy() + */ +API int contacts_db_search_records(const char* view_uri, const char *keyword, int offset, int limit, contacts_list_h* record_list); + +/** + * @brief Retrieves records with a query handle and a keyword + * + * @remarks @a record_list must be released with contacts_list_destroy() by you. \n + * This API works only for \ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person and \ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_person_grouprel. + * + * @param[in] query The query handle to filter + * @param[in] keyword Thekeyword + * @param[in] offset The index to get results from which index + * @param[in] limit The number to limit results + * @param[out] record_list The record list + * + * @return 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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_list_destroy() + */ +API int contacts_db_search_records_with_query(contacts_query_h query, const char *keyword, int offset, int limit, contacts_list_h* record_list); + +/** + * @brief Gets records count of a specific view + * + * @param[in] view_uri The view URI to get records + * @param[out] count The count of records + * + * @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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + */ +API int contacts_db_get_count( const char* view_uri, int *count); + +/** + * @brief Gets records count with a query handle + * + * @param[in] query The query handle to filter + * @param[out] count The count of records + * + * @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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + */ +API int contacts_db_get_count_with_query( contacts_query_h query, int *count); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif //__TIZEN_SOCIAL_CONTACTS_DB_H__ diff --git a/include/contacts_errors.h b/include/contacts_errors.h new file mode 100755 index 0000000..1ec24cd --- /dev/null +++ b/include/contacts_errors.h @@ -0,0 +1,85 @@ +/* + * 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 +/** + * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_DATABASE_MODULE + * @{ + */ + +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 */ + /* LOGIC & DATA */ + CONTACTS_ERROR_NO_DATA = TIZEN_ERROR_SOCIAL_CLASS | TIZEN_ERROR_NO_DATA, /**< Requested data does not exist */ + + /* DB */ +// CONTACTS_ERROR_DB_NOT_OPENED = TIZEN_ERROR_SOCIAL_CLASS | 0x80, /**< Database didn't opened not yet */ +// CONTACTS_ERROR_DB_LOCKED = TIZEN_ERROR_SOCIAL_CLASS | 0x81, /**< Database table locked or file locked */ +// CONTACTS_ERROR_DB_FAILED = TIZEN_ERROR_SOCIAL_CLASS | 0x82, /**< Database operation failure */ +// CONTACTS_ERROR_DB_RECORD_NOT_FOUND = TIZEN_ERROR_SOCIAL_CLASS | 0x83, /**< Empty result set */ +// CONTACTS_ERROR_DB_FULL = TIZEN_ERROR_SOCIAL_CLASS | 0x84, /**< Database Full */ +// CONTACTS_ERROR_DB_IO_ERROR = TIZEN_ERROR_SOCIAL_CLASS | 0x85, /**< Database I/O error */ + + CONTACTS_ERROR_DB = TIZEN_ERROR_SOCIAL_CLASS | 0x9F, /**< Unknown DB error */ + + /* IPC */ +// CONTACTS_ERROR_IPC_BUSY = TIZEN_ERROR_SOCIAL_CLASS | 0xB0, /**< IPC bus locked */ + CONTACTS_ERROR_IPC_NOT_AVALIABLE = TIZEN_ERROR_SOCIAL_CLASS | 0xB1, /**< IPC server is not available */ + CONTACTS_ERROR_IPC = TIZEN_ERROR_SOCIAL_CLASS | 0xBF, /**< Unknown IPC error */ + + /* VCARD */ +// CONTACTS_ERROR_VCARD_UNKNOWN_ERROR = TIZEN_ERROR_SOCIAL_CLASS | 0xCF, /**< Unknown Vcard error */ + + /* ENVIRONMENT & OTEHR MODULE */ + CONTACTS_ERROR_SYSTEM = TIZEN_ERROR_SOCIAL_CLASS | 0xEF, /**< . */ +/* + CONTACTS_ERROR_SOCKET_FAILED = TIZEN_ERROR_SOCIAL_CLASS | 0xE0, + CONTACTS_ERROR_INOTIFY_FAILED = TIZEN_ERROR_SOCIAL_CLASS | 0xE1, + CONTACTS_ERROR_VCONF_FAILED = TIZEN_ERROR_SOCIAL_CLASS | 0xE2, + CONTACTS_ERROR_ICU_FAILED = TIZEN_ERROR_SOCIAL_CLASS | 0xE3, + CONTACTS_ERROR_TAPI_FAILED = TIZEN_ERROR_SOCIAL_CLASS | 0xE4, +*/ + + /* UNHANDLED EXCEPTION */ + CONTACTS_ERROR_INTERNAL = TIZEN_ERROR_SOCIAL_CLASS | 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 index 0000000..e6310ce --- /dev/null +++ b/include/contacts_filter.h @@ -0,0 +1,213 @@ +/* + * 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 + + +/** + * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_FILTER_MODULE + * @{ + */ + +typedef enum +{ + CONTACTS_MATCH_EXACTLY, /**< . */ + CONTACTS_MATCH_FULLSTRING, /**< . */ + CONTACTS_MATCH_CONTAINS, /**< . */ + CONTACTS_MATCH_STARTSWITH, /**< . */ + CONTACTS_MATCH_ENDSWITH, /**< . */ + CONTACTS_MATCH_EXISTS /**< . */ +} contacts_match_str_flag_e; + +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, /**< . */ +} contacts_match_int_flag_e; + +typedef enum { + CONTACTS_FILTER_OPERATOR_AND, /**< . */ + CONTACTS_FILTER_OPERATOR_OR /**< . */ +} contacts_filter_operator_e; + + +/** + * @brief Creates a handle to filter. + * + * @remarks @a filter must be released with contacts_filter_destroy() by you. + * + * @param[in] view_uri The view URI of a filter + * @param[out] filter The filter handle + * + * @return 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 + * + * @see contacts_filter_destroy() + */ +API int contacts_filter_create( const char* view_uri, contacts_filter_h* filter ); + +/** + * @brief Destroys a filter handle. + * + * @param[in] filter The filter handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_filter_create() + */ +API int contacts_filter_destroy( contacts_filter_h filter ); + +/** + * @brief Adds a condition for string type property + * + * @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 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() + */ +API 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 integer type property + * + * @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 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() + */ +API 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 long long int type property + * + * @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 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() + */ +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 ); + +/** + * @brief Adds a condition for double type property + * + * @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 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() + */ +API 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 boolean type property + * + * @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 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() + */ +API int contacts_filter_add_bool( contacts_filter_h filter, unsigned int property_id, bool match_value ); + +/** + * @brief Adds a operator between conditions + * + * @param[in] filter The filter handle + * @param[in] operator_type The operator type + * + * @return 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() + */ +API int contacts_filter_add_operator( contacts_filter_h filter, contacts_filter_operator_e operator_type ); + +/** + * @brief Adds a filter handle to filter handle. + * + * @param[in] parent_filter The parent filter handle + * @param[in] child_filter The child filter handle + * + * @return 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() + */ +API 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 index 0000000..2e0fe73 --- /dev/null +++ b/include/contacts_group.h @@ -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. + * + */ +#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 + +/** + * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_GROUP_MODULE + * @{ + */ + +/** + * @brief Adds a contact and a group relationship to the contacts database. + * + * @param[in] group_id The group ID + * @param[in] contact_id The contact ID + * + * @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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_group_remove_contact() + */ +API int contacts_group_add_contact(int group_id, int contact_id); + +/** + * @brief Removes a contact and a group relationship from the contacts database. + * + * @param[in] group_id The group ID + * @param[in] contact_id The contact ID + * + * @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 + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + * @see contacts_group_add_contact() + */ +API int contacts_group_remove_contact(int group_id, int contact_id); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif //__TIZEN_SOCIAL_CONTACTS_GROUP_H__ diff --git a/include/contacts_list.h b/include/contacts_list.h new file mode 100644 index 0000000..146bb9f --- /dev/null +++ b/include/contacts_list.h @@ -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. + * + */ +#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 + +/** + * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_LIST_MODULE + * @{ + */ + +/** + * @brief Creates a handle to the contacts list. + * + * @remarks @a contacts_list must be released with contacts_list_destroy() by you. + * + * @param[out] contacts_list The contacts list handle + * + * @return 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() + */ +API int contacts_list_create( contacts_list_h* contacts_list ); + +/** + * @brief Destroys a contacts list handle and releases all its resources. + * + * @param[in] contacts_list The contacts list handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_list_create() + */ +API int contacts_list_destroy( contacts_list_h contacts_list, bool delete_child ); + +/** + * @brief Retrieves count of contact entity from a contacts list. + * + * @param[in] contacts_list The contacts list handle + * @param[out] count The count of contact entity + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_list_add() + */ +API int contacts_list_get_count( contacts_list_h contacts_list, unsigned int *count ); + +/** + * @brief Adds a record handle to contacts list handle. + * + * @param[in] contacts_list The contacts list handle + * @param[in] record The record handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_list_remove() + */ +API int contacts_list_add( contacts_list_h contacts_list, contacts_record_h record ); + +/** + * @brief Removes a record handle to contacts list handle. + * @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 NULL. + * + * @param[in] contacts_list The contacts list handle + * @param[in] record The record handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_list_add() + */ +API int contacts_list_remove( contacts_list_h contacts_list, contacts_record_h record ); + +/** + * @brief Retrieves a record handle from contacts list handle. + * @details The default current record is the first record + * @remarks The @a record handle MUST NOT destroyed by you. + * 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 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + */ +API int contacts_list_get_current_record_p( contacts_list_h contacts_list, contacts_record_h* record ); + +/** + * @brief Moves a contacts list to previous position. + * + * @param[in] contacts_list The contacts list handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_list_next() + */ +API int contacts_list_prev( contacts_list_h contacts_list ); + +/** + * @brief Moves a contacts list to next position. + * + * @param[in] contacts_list The contacts list handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_list_prev() + */ +API int contacts_list_next( contacts_list_h contacts_list ); + +/** + * @brief Moves a contacts list to the first position. + * + * @param[in] contacts_list The contacts list handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_list_last() + */ +API int contacts_list_first( contacts_list_h contacts_list ); + +/** + * @brief Moves a contacts lis tto the last position. + * + * @param[in] contacts_list The contacts list handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_list_first() + */ +API 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 index 0000000..fbea293 --- /dev/null +++ b/include/contacts_person.h @@ -0,0 +1,160 @@ +/* + * 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 + +/** + * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_PERSON_MODULE + * @{ + */ + +/** + * @brief Links a person to a person. + * + * @param[in] base_person_id The base person ID + * @param[in] person_id The person ID to be linked + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_DB Database operation failure + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + */ +API int contacts_person_link_person(int base_person_id, int person_id); + +/** + * @brief Unlinks a contact from a person. + * + * @param[in] person_id The person ID + * @param[in] contact_id The contact ID to unlink + * @param[out] unliked_person_id The person ID generated + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_DB Database operation failure + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + */ +API 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 frequent contacted person list. + * + * @param[in] person_id The person ID + * @param[in] type The type to reset + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_DB Database operation failure + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + */ +API int contacts_person_reset_usage(int person_id, contacts_usage_type_e type); + +/** + * @brief Sets a favorite person place between a previous person and a next person. + * + * @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 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_DB Database operation failure + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + */ +API int contacts_person_set_favorite_order(int person_id, int previous_person_id, int next_person_id); + +typedef enum { + CONTACTS_PERSON_PROPERTY_NAME_CONTACT, /**< . */ + CONTACTS_PERSON_PROPERTY_NUMBER, /**< . */ + CONTACTS_PERSON_PROPERTY_EMAIL, /**< . */ + CONTACTS_PERSON_PROPERTY_IMAGE, /**< . */ +} contacts_person_property_e; + +/** + * @brief Sets a default property for a record. + * + * @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 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_DB Database operation failure + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + */ +API int contacts_person_set_default_property(contacts_person_property_e property, int person_id, + int id); + +/** + * @brief Gets a default property for a record. + * + * @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 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_DB Database operation failure + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + */ +API 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 index 0000000..f799307 --- /dev/null +++ b/include/contacts_phone_log.h @@ -0,0 +1,85 @@ +/* + * 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 + +/** + * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_PHONELOG_MODULE + * @{ + */ + +/** + * @brief Resets a phonelog's count. + * @details The count of all type of phonelog will be 0. + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_DB Database operation failure + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + */ +API int contacts_phone_log_reset_statistics(); + +typedef enum { + CONTACTS_PHONE_LOG_DELETE_BY_ADDRESS, /**< . */ + CONTACTS_PHONE_LOG_DELETE_BY_MESSAGE_EXTRA_DATA1, /**< . */ + CONTACTS_PHONE_LOG_DELETE_BY_EMAIL_EXTRA_DATA1, /**< . */ +} contacts_phone_log_delete_e; + +/** + * @brief Delete phone log with extra_data1 + * + * @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 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * @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 + */ +API int contacts_phone_log_delete(contacts_phone_log_delete_e op, ...); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + + +#endif //__TIZEN_SOCIAL_CONTACTS_PHONELOG_H__ diff --git a/include/contacts_query.h b/include/contacts_query.h new file mode 100644 index 0000000..af9c799 --- /dev/null +++ b/include/contacts_query.h @@ -0,0 +1,128 @@ +/* + * 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 + +/** + * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_QUERY_MODULE + * @{ + */ + +/** + * @brief Creates a query handle. + * + * @remarks @a query must be released with contacts_query_destroy() by you. + * + * @param[in] view_uri The view URI of a query + * @param[out] query The filter handle + * + * @return 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 + * + * @see contacts_query_destroy() + */ +API int contacts_query_create( const char* view_uri, contacts_query_h* query ); + +/** + * @brief Destroys a query handle. + * + * @param[in] query The query handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_query_create() + */ +API int contacts_query_destroy( contacts_query_h query ); + +/** + * @brief Adds property IDs for projection. + * + * @param[in] filter The filter handle + * @param[in] property_id_array The property ID array + * @param[in] count The number of property IDs + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + */ +API int contacts_query_set_projection(contacts_query_h query, unsigned int property_id_array[], int count); + +/** + * @brief Set distinct option for projection. + * + * @param[in] query The query handle + * @param[in] set Set or unset + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + */ +API int contacts_query_set_distinct(contacts_query_h query, bool set); + +/** + * @brief Set a filter handle to query handle. + * + * @param[in] query The query handle + * @param[in] filter The filter handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_filter_create() + */ +API int contacts_query_set_filter(contacts_query_h query, contacts_filter_h filter); + +/** + * @brief Sets sort mode. + * + * @param[in] query The query handle + * @param[in] property_id The property ID to sort + * @param[in] is_ascending Ascending or decending + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + */ +API 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 index 0000000..60ac4bf --- /dev/null +++ b/include/contacts_record.h @@ -0,0 +1,349 @@ +/* + * 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 + + +/** + * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_RECORD_MODULE + * @{ + */ + +/** + * @brief Creates a handle to the record. + * + * @remarks @a record must be released with contacts_record_destroy() by you. + * + * @param[in] view_uri The view uri + * @param[out] record The record handle + * + * @return 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() + */ +API int contacts_record_create( const char* view_uri, contacts_record_h* record ); + +/** + * @brief Destroys a record handle and releases all its resources. + * + * @param[in] record The record handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_list_create() + */ +API int contacts_record_destroy( contacts_record_h record, bool delete_child ); + +/** + * @brief Makes a clone of a record handle. + * + * @remarks @a cloned_record must be released with contacts_record_destroy() by you. + * + * @param[in] record The record handle + * @param[out] cloned_record The cloned record handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_record_destroy() + */ +API int contacts_record_clone( contacts_record_h record, contacts_record_h* cloned_record ); + +/** + * @brief Gets a string from a record handle. + * + * @remarks @a value must be released with free() by you. + * + * @param[in] record The record handle + * @param[in] property_id The property ID + * @param[out] value The value to be returned + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_record_get_str_p() + * @see contacts_record_set_str() + */ +API int contacts_record_get_str( contacts_record_h record, unsigned int property_id, char** value ); + +/** + * @brief Gets a string pointer from a record handle. + * + * @remarks @a value MUST NOT be released by you. + * + * @param[in] record The record handle + * @param[in] property_id The property ID + * @param[out] value The value to be returned + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_record_get_str() + * @see contacts_record_set_str() + */ +API int contacts_record_get_str_p( contacts_record_h record, unsigned int property_id, char** value ); + +/** + * @brief Sets a string to a record handle. + * + * @param[in] record The record handle + * @param[in] property_id The property ID + * @param[in] value The value to set + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_record_get_str() + * @see contacts_record_get_str_p() + */ +API int contacts_record_set_str( contacts_record_h record, unsigned int property_id, const char* value ); + +/** + * @brief Gets a integer from a record handle. + * + * @param[in] record The record handle + * @param[in] property_id The property ID + * @param[out] value The value to be returned + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_record_set_int() + */ +API int contacts_record_get_int( contacts_record_h record, unsigned int property_id, int* value ); + +/** + * @brief Sets a integer to a record handle. + * + * @param[in] record The record handle + * @param[in] property_id The property ID + * @param[in] value The value to set + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_record_get_int() + */ +API int contacts_record_set_int( contacts_record_h record, unsigned int property_id, int value ); + +/** + * @brief Gets a long integer from a record handle. + * + * @param[in] record The record handle + * @param[in] property_id The property ID + * @param[out] value The value to be returned + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_record_set_lli() + */ +API int contacts_record_get_lli( contacts_record_h record, unsigned int property_id, long long int *value ); + +/** + * @brief Sets a long integer to a record handle. + * + * @param[in] record The record handle + * @param[in] property_id The property ID + * @param[in] value The value to set + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_record_get_lli() + */ +API int contacts_record_set_lli( contacts_record_h record, unsigned int property_id, long long int value ); + +/** + * @brief Gets a boolean from a record handle. + * + * @param[in] record The record handle + * @param[in] property_id The property ID + * @param[out] value The value to be returned + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_record_set_bool() + */ +API int contacts_record_get_bool( contacts_record_h record, unsigned int property_id, bool *value ); + +/** + * @brief Sets a boolean to the record handle. + * + * @param[in] record The record handle + * @param[in] property_id The property ID + * @param[in] value The value to set + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_record_get_bool() + */ +API int contacts_record_set_bool( contacts_record_h record, unsigned int property_id, bool value ); + +/** + * @brief Gets a double from a record handle. + * + * @param[in] record The record handle + * @param[in] property_id The property ID + * @param[out] value The value to be returned + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_record_set_bool() + */ +API int contacts_record_get_double( contacts_record_h record, unsigned int property_id, double *value ); + +/** + * @brief Sets a double to the record handle. + * + * @param[in] record The record handle + * @param[in] property_id The property ID + * @param[in] value The value to set + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_record_get_bool() + */ +API int contacts_record_set_double( contacts_record_h record, unsigned int property_id, double value ); + +/** + * @brief Adds a child record handle to a parent record handle. + * + * @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 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_record_remove_child_record() + */ +API int contacts_record_add_child_record( contacts_record_h record, unsigned int property_id, contacts_record_h child_record ); + +/** + * @brief Removes a child record handle from a parent record handle. + * + * @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 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_record_add_child_record() + */ +API int contacts_record_remove_child_record( contacts_record_h record, unsigned int property_id, contacts_record_h child_record ); + +//API int contacts_record_update_child_record( contacts_record_h record, contacts_record_h child_record ); + +/** + * @brief Gets a number of child record handle from a parent record handle. + * + * @param[in] record The parent record handle + * @param[in] property_id The property ID + * @param[out] count The child record count + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_record_add_child_record() + * @see contacts_record_remove_child_record() + */ +API int contacts_record_get_child_record_count( contacts_record_h record, unsigned int property_id, unsigned int *count ); + +/** + * @brief Gets a child record handle pointer from a parent record handle. + * + * @remarks @a child_record MUST NOT be released by you. \n It is released when the parent record handle 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 to be returned + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_record_add_child_record() + * @see contacts_record_remove_child_record() + * @see contacts_record_get_child_record_count() + */ +API int contacts_record_get_child_record_at_p( contacts_record_h record, unsigned int property_id, int index, contacts_record_h* child_record ); + +/** + * @brief Makes a clone of a child record list handle from a parent record handle. + * + * @remarks @a cloned_list MUST be released with contacts_list_destroy() by you. + * + * @param[in] record The record handle + * @param[in] property_id The property ID + * @param[out] cloned_list The cloned list handle + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + * + * @see contacts_list_destroy() + */ +API int contacts_record_clone_child_record_list( contacts_record_h record, unsigned int property_id, contacts_list_h* cloned_list ); + +/** + * @} + */ + +#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 index 0000000..a82b9bc --- /dev/null +++ b/include/contacts_service.h @@ -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_SERVICE_H__ +#define __TIZEN_SOCIAL_CONTACTS_SERVICE_H__ + +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_DATABASE_MODULE + * @{ + */ + +/** + * @brief Connects to the contacts service. + * + * @remarks Connection opening is necessary to access the contacts database such as fetching, inserting, or updating records.\n + * The execution of contacts_connect2() and contacts_disconnect2() could slow down your application so you are recommended not to call them frequently. + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_DB Database operation failure + * + * @see contacts_disconnect2() + */ +API int contacts_connect2(); + +/** + * @brief Disconnects from the contacts service. + * + * @remarks If there is no opened connection, this function returns #CONTACTS_ERROR_DB. + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_DB Database operation failure + * + * @see contacts_connect2() + */ +API int contacts_disconnect2(); + + + +/** + * @brief Connects to the contacts service with another connection for thread. + * + * @remarks + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_DB Database operation failure + * + * @see contacts_disconnect_on_thread() + */ +API int contacts_connect_on_thread(); + +/** + * @brief Disconnects from the contacts service. + * + * @remarks + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_DB Database operation failure + * + * @see contacts_connect_on_thread() + */ +API int contacts_disconnect_on_thread(); + + +#define CONTACTS_CONNECT_FLAG_RETRY 0x00000001 +#define CONTACTS_CONNECT_FLAG_NONE 0 + +/** + * @brief Connects to the contacts service. If connection is failed because contacts-service is not running, it will retry for several seconds + * + * @remarks Connection opening is necessary to access the contacts database such as fetching, inserting, or updating records.\n + * The execution of contacts_connect2() and contacts_disconnect2() could slow down your application so you are recommended not to call them frequently. + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_DB Database operation failure + * + * @see contacts_disconnect2() + */ +API 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 index 0000000..410eebb --- /dev/null +++ b/include/contacts_setting.h @@ -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. + * + */ +#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 + +/** + * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_SETTING_MODULE + * @{ + */ + +/** + * @brief Enumerations of name display order + */ +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. + * + * @param[out] name_display_order The name display order + * + * @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 + * + * @pre This function requires an open connection to the contacts service by contacts_connect2(). + * + * @see contacts_connect2() + */ +API int contacts_setting_get_name_display_order(contacts_name_display_order_e *name_display_order); + +/** + * @brief Sets the contacts name display order. + * + * @param[in] name_display_order The name display order + * + * @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 + * + * @pre This function requires an open connection to the contacts service by contacts_connect2(). + * + * @see contacts_connect2() + */ +API int contacts_setting_set_name_display_order(contacts_name_display_order_e name_display_order); + +/** + * @} + */ + +#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 index 0000000..3a7019c --- /dev/null +++ b/include/contacts_sim.h @@ -0,0 +1,72 @@ +/* + * 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 + +/** + * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_SIM_MODULE + * @{ + */ + +/** + * @brief Imports all contacts to Contacts Database from SIM. + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_DB Database operation failure + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + */ +API int contacts_sim_import_all_contacts(); + + +/** + * @brief check whether to complete sim initialize . + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_DB Database operation failure + * + * @pre This function requires an open connection to contacts service by contacts_connect2(). + * + * @see contacts_connect2() + */ +API 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 index 0000000..0112176 --- /dev/null +++ b/include/contacts_types.h @@ -0,0 +1,231 @@ +/* + * 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 ) + +/** + * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_RECORD_MODULE + * @{ + */ + +/** + * 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. + */ +typedef enum { + CONTACTS_NUMBER_TYPE_OTHER, /**< . */ + 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_ASSISTANT = 1<<30, /**< A additional type for assistant */ +}contacts_number_type_e; + +typedef enum { + CONTACTS_EMAIL_TYPE_OTHER, /**< . */ + CONTACTS_EMAIL_TYPE_CUSTOM = 1<<0, /**< . */ + CONTACTS_EMAIL_TYPE_HOME = 1<<1, /**< . */ + CONTACTS_EMAIL_TYPE_WORK = 1<<2, /**< . */ + CONTACTS_EMAIL_TYPE_MOBILE = 1<<3, /**< . */ +}contacts_email_type_e; + +typedef enum { + CONTACTS_COMPANY_TYPE_OTHER, /**< . */ + CONTACTS_COMPANY_TYPE_CUSTOM = 1<<0, /**< . */ + CONTACTS_COMPANY_TYPE_WORK = 1<<1, /**< . */ +}contacts_company_type_e; + +typedef enum { + CONTACTS_ADDRESS_TYPE_OTHER, /**< . */ + 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; + +typedef enum { + CONTACTS_URL_TYPE_OTHER, /**< . */ + CONTACTS_URL_TYPE_CUSTOM, /**< . */ + CONTACTS_URL_TYPE_HOME, /**< . */ + CONTACTS_URL_TYPE_WORK, /**< . */ +}contacts_url_type_e; + +typedef enum{ + CONTACTS_MESSENGER_TYPE_OTHER, /**< . */ + CONTACTS_MESSENGER_TYPE_CUSTOM, /**< . */ + CONTACTS_MESSENGER_TYPE_GOOGLE, /**< . */ + CONTACTS_MESSENGER_TYPE_WLM, /**< . */ + CONTACTS_MESSENGER_TYPE_YAHOO, /**< . */ + CONTACTS_MESSENGER_TYPE_FACEBOOK, /**< . */ + CONTACTS_MESSENGER_TYPE_ICQ, /**< . */ + CONTACTS_MESSENGER_TYPE_AIM, /**< . */ + CONTACTS_MESSENGER_TYPE_QQ, /**< . */ + CONTACTS_MESSENGER_TYPE_JABBER, /**< . */ + CONTACTS_MESSENGER_TYPE_SKYPE, /**< . */ + CONTACTS_MESSENGER_TYPE_IRC, /**< . */ +}contacts_messenger_type_e; + +typedef enum { + CONTACTS_PLOG_TYPE_NONE, + CONTACTS_PLOG_TYPE_VOICE_INCOMMING = 1, /**< . */ + CONTACTS_PLOG_TYPE_VOICE_OUTGOING = 2, /**< . */ + CONTACTS_PLOG_TYPE_VIDEO_INCOMMING = 3, /**< . */ + CONTACTS_PLOG_TYPE_VIDEO_OUTGOING = 4, /**< . */ + 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, /**< . */ + CONTACTS_PLOG_TYPE_VIDEO_REJECT = 10, /**< . */ + CONTACTS_PLOG_TYPE_VOICE_BLOCKED = 11, /**< . */ + CONTACTS_PLOG_TYPE_VIDEO_BLOCKED = 12, /**< . */ + + CONTACTS_PLOG_TYPE_MMS_INCOMMING = 101, /**< . */ + CONTACTS_PLOG_TYPE_MMS_OUTGOING = 102, /**< . */ + CONTACTS_PLOG_TYPE_SMS_INCOMMING = 103, /**< . */ + CONTACTS_PLOG_TYPE_SMS_OUTGOING = 104, /**< . */ + CONTACTS_PLOG_TYPE_SMS_BLOCKED = 105, /**< . */ + CONTACTS_PLOG_TYPE_MMS_BLOCKED = 106, /**< . */ + + CONTACTS_PLOG_TYPE_EMAIL_RECEIVED = 201, /**<.*/ + CONTACTS_PLOG_TYPE_EMAIL_SENT = 202, /**<.*/ + + CONTACTS_PLOG_TYPE_MAX +}contacts_phone_log_type_e; + +typedef enum { + CONTACTS_EVENT_TYPE_OTHER, /**< . */ + CONTACTS_EVENT_TYPE_CUSTOM, /**< . */ + CONTACTS_EVENT_TYPE_BIRTH, /**< . */ + CONTACTS_EVENT_TYPE_ANNIVERSARY /**< . */ +}contacts_event_type_e; + +typedef enum { + CONTACTS_USAGE_STAT_TYPE_NONE, /**< . */ + CONTACTS_USAGE_STAT_TYPE_OUTGOING_CALL, /**< . */ + CONTACTS_USAGE_STAT_TYPE_OUTGOING_MSG /**< . */ +}contacts_usage_type_e; + +typedef enum { + CONTACTS_DISPLAY_NAME_SOURCE_TYPE_INVALID, /**< . */ + CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL, /**< . */ + CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NUMBER, /**< . */ + CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NICKNAME, /**< . */ + CONTACTS_DISPLAY_NAME_SOURCE_TYPE_COMPANY, /**< . */ + CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME, /**< . */ +}contacts_display_name_source_type_e; + +typedef enum { + CONTACTS_ADDRESS_BOOK_MODE_NONE, /**< .*/ + CONTACTS_ADDRESS_BOOK_MODE_READONLY, /**< .*/ +}contacts_address_book_mode_e; + +typedef enum { + CONTACTS_RELATIONSHIP_TYPE_OTHER, /**< .*/ + CONTACTS_RELATIONSHIP_TYPE_ASSISTANT, /**< .*/ + CONTACTS_RELATIONSHIP_TYPE_BROTHER, /**< .*/ + CONTACTS_RELATIONSHIP_TYPE_CHILD, /**< .*/ + CONTACTS_RELATIONSHIP_TYPE_DOMESTIC_PARTNER, /**< .*/ + CONTACTS_RELATIONSHIP_TYPE_FATHER, /**< .*/ + CONTACTS_RELATIONSHIP_TYPE_FRIEND, /**< .*/ + CONTACTS_RELATIONSHIP_TYPE_MANAGER, /**< .*/ + CONTACTS_RELATIONSHIP_TYPE_MOTHER, /**< .*/ + CONTACTS_RELATIONSHIP_TYPE_PARENT, /**< .*/ + CONTACTS_RELATIONSHIP_TYPE_PARTNER, /**< .*/ + CONTACTS_RELATIONSHIP_TYPE_REFERRED_BY, /**< .*/ + CONTACTS_RELATIONSHIP_TYPE_RELATIVE, /**< .*/ + CONTACTS_RELATIONSHIP_TYPE_SISTER, /**< .*/ + CONTACTS_RELATIONSHIP_TYPE_SPOUSE, /**< .*/ + CONTACTS_RELATIONSHIP_TYPE_CUSTOM, /**< .*/ +}contacts_relationship_type_e; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_SOCIAL_CONTACTS_TYPES_H__ */ + diff --git a/include/contacts_utils.h b/include/contacts_utils.h new file mode 100644 index 0000000..9757b20 --- /dev/null +++ b/include/contacts_utils.h @@ -0,0 +1,57 @@ +/*
+ * 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_UTILS_H__
+#define __TIZEN_SOCIAL_CONTACTS_UTILS_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_UTILS_MODULE
+ * @{
+ */
+
+/**
+ * Gets normalized string.
+ *
+ * @param[out] index_string The pointer of language index (number, first language, second language(if differ from first), #).
+ *
+ * @return 0 on success, otherwise a negative error value.
+ *
+ * @retval #CONTACTS_ERROR_NONE Successful +*/
+API int contacts_utils_get_index_characters(char **index_string);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //__TIZEN_SOCIAL_CONTACTS_UTILS_H__
+
diff --git a/include/contacts_vcard.h b/include/contacts_vcard.h new file mode 100644 index 0000000..3f64535 --- /dev/null +++ b/include/contacts_vcard.h @@ -0,0 +1,127 @@ +/* + * 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 + +/** + * @addtogroup CAPI_SOCIAL_CONTACTS_SVC_VCARD_MODULE + * @{ + */ +/** + * @brief The callback function to get record hadle of \ref CAPI_SOCIAL_CONTACTS_SVC_VIEW_MODULE_contacts_contact. + * + * @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 or @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 record handle(_contacts_contact) from a vCard file. + * + * @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 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 + * + * @post This function invokes contacts_vcard_stream_cb(). + * + * @see contacts_vcard_parse_cb() + */ +API 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 contacts list from vCard stream. + * + * @param[in] vcard_stream The vCard stream + * @param[out] contacts_list The contacts list handle + * + * @return 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 + */ +API int contacts_vcard_parse_to_contacts(const char *vcard_stream, contacts_list_h *contacts_list); + +/** + * @brief Retrieves vCard stream from a contact. + * + * @param[in] contact The contact record handle + * @param[out] vcard_stream The vCard stream + * + * @return 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 + */ +API int contacts_vcard_make_from_contact(contacts_record_h contact, char **vcard_stream); + +/** + * @brief Retrieves vCard stream from a person. + * + * @param[in] person The person record handle + * @param[out] vcard_stream The vCard stream + * + * @return 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 + */ +API int contacts_vcard_make_from_person(contacts_record_h person, char **vcard_stream); + +/** + * @brief Retrieves count of contact entity from a vCard file. + * + * @param[in] vcard_file_path The person record handle + * @param[out] count The count of contact entity + * + * @return 0 on success, otherwise a negative error value. + * @retval #CONTACTS_ERROR_NONE Successful + * @retval #CONTACTS_ERROR_INVALID_PARAMETER Invalid parameter + */ +API 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 index 0000000..358dbb7 --- /dev/null +++ b/include/contacts_views.h @@ -0,0 +1,607 @@ +/* + * 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 + +// address_book +_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 ) + +// group +_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( system_id ) // read, write, string + _CONTACTS_PROPERTY_BOOL( is_read_only ) // read only +_CONTACTS_END_VIEW( _contacts_group ) + +// person +_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, write + _CONTACTS_PROPERTY_STR( vibration ) // read, write + _CONTACTS_PROPERTY_STR( status ) // read only + _CONTACTS_PROPERTY_BOOL( is_favorite ) // read, write + _CONTACTS_PROPERTY_DOUBLE( favorite_priority ) // read only + _CONTACTS_PROPERTY_INT( link_count ) // read only + _CONTACTS_PROPERTY_INT( account_id1 ) // read only + _CONTACTS_PROPERTY_INT( account_id2 ) // read only + _CONTACTS_PROPERTY_INT( account_id3 ) // read only + _CONTACTS_PROPERTY_STR( addressbook_ids ) // read only + _CONTACTS_PROPERTY_BOOL( has_phonenumber ) // read only + _CONTACTS_PROPERTY_BOOL( has_email ) // read only +_CONTACTS_END_VIEW( _contacts_person ) + +// simple contact +_CONTACTS_BEGIN_VIEW() + _CONTACTS_PROPERTY_INT( id ) // read only + _CONTACTS_PROPERTY_STR( display_name ) // read only + _CONTACTS_PROPERTY_INT( display_source_type) // read only, internal field ? + _CONTACTS_PROPERTY_INT( address_book_id ) // read, write-once + _CONTACTS_PROPERTY_STR( ringtone_path ) // read, write + _CONTACTS_PROPERTY_STR( image_thumbnail_path ) // read, write + _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, write + _CONTACTS_PROPERTY_STR( vibration ) // read, write + _CONTACTS_PROPERTY_INT( changed_time ) // read only +_CONTACTS_END_VIEW( _contacts_simple_contact ) + +// contact +_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, write + _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, write + _CONTACTS_PROPERTY_STR( vibration ) // read, write + _CONTACTS_PROPERTY_INT( changed_time ) // read only + _CONTACTS_PROPERTY_CHILD_SINGLE( name ) // read, write + _CONTACTS_PROPERTY_CHILD_SINGLE( 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_END_VIEW( _contacts_contact ) + +// my_profile +_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, write + _CONTACTS_PROPERTY_STR( uid ) // read, write + _CONTACTS_PROPERTY_INT( changed_time ) // read only + _CONTACTS_PROPERTY_CHILD_SINGLE( name ) // read, write + _CONTACTS_PROPERTY_CHILD_SINGLE( 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 ) + + +// contact_name +_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 ) + +// contact_number +_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_END_VIEW( _contacts_number ) + +// contact_email +_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 ) + +// contact_address +_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 ) + +// contact_note +_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 ) + +// contact_url +_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 ) + +// contact_event +_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( is_lunar ) // read, write + _CONTACTS_PROPERTY_INT( lunar_date ) // read, write +_CONTACTS_END_VIEW( _contacts_event ) + +// contact_grouprelation +// refer to the contacts_group_add_contact, contacts_group_remove_contact +_CONTACTS_BEGIN_VIEW() + _CONTACTS_PROPERTY_INT( id ) // read only, can not used as filter + _CONTACTS_PROPERTY_INT( group_id ) // read, write + _CONTACTS_PROPERTY_INT( contact_id ) // read, write once + _CONTACTS_PROPERTY_STR( name ) // read only +_CONTACTS_END_VIEW( _contacts_group_relation ) + +// contact_relationship +_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 ) + +// contact_image +_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 ) + +// contact_company +_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 ) + +// contact_nickname +_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 ) + +// contact_messenger +_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 ) + +// contact_extend +_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 ) + +// contact_sdn +_CONTACTS_BEGIN_VIEW() + _CONTACTS_PROPERTY_INT( id ) // read only + _CONTACTS_PROPERTY_STR( name ) // read, write + _CONTACTS_PROPERTY_STR( number ) // read, write +_CONTACTS_END_VIEW( _contacts_sdn ) + +// contact_profile +_CONTACTS_BEGIN_VIEW() + _CONTACTS_PROPERTY_INT( id ) // read only + _CONTACTS_PROPERTY_INT( type ) // read, write + _CONTACTS_PROPERTY_STR( label ) // read, write + _CONTACTS_PROPERTY_STR( uid ) // read, write + _CONTACTS_PROPERTY_STR( text ) // read, write + _CONTACTS_PROPERTY_INT( order ) // read, write + _CONTACTS_PROPERTY_STR( appsvc_operation ) // read, write + _CONTACTS_PROPERTY_STR( data1 ) // read, write + _CONTACTS_PROPERTY_STR( data2 ) // read, write + _CONTACTS_PROPERTY_STR( data3 ) // read, write + _CONTACTS_PROPERTY_STR( data4 ) // read, write + _CONTACTS_PROPERTY_INT( contact_id ) // read, write once +_CONTACTS_END_VIEW( _contacts_profile ) + +// activity photo +_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 ) + +// activity +_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( sync_data1 ) // read, write + _CONTACTS_PROPERTY_STR( sync_data2 ) // read, write + _CONTACTS_PROPERTY_STR( sync_data3 ) // read, write + _CONTACTS_PROPERTY_STR( sync_data4 ) // read, write + _CONTACTS_PROPERTY_CHILD_MULTIPLE(photo) // read, write +_CONTACTS_END_VIEW( _contacts_activity ) + +// speeddial +_CONTACTS_BEGIN_VIEW() + _CONTACTS_PROPERTY_INT( speeddial_number ) // read, write + _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_END_VIEW( _contacts_speeddial ) + +// phone_log +_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 + _CONTACTS_PROPERTY_STR( extra_data2 ) // read, write once : shortmsg, subject +_CONTACTS_END_VIEW( _contacts_phone_log ) + +// contact_updated_info : read only +_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_END_READ_ONLY_VIEW( _contacts_contact_updated_info ) + +// group_updated_info : read only +_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 ) + + +// group_updated_info : read only +_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 ) + +// grouprel_updated_info : read only +_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 ) + +// only for query (filter/projection) +// person_contact : read only +_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_INT( account_id1 ) + _CONTACTS_PROPERTY_PROJECTION_INT( account_id2 ) + _CONTACTS_PROPERTY_PROJECTION_INT( account_id3 ) + _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_END_READ_ONLY_VIEW( _contacts_person_contact ) + +// person_number : read only +_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_END_READ_ONLY_VIEW( _contacts_person_number ) + +// person_email : read only +_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_END_READ_ONLY_VIEW( _contacts_person_email ) + +// person_group : read only +_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_INT( account_id1 ) + _CONTACTS_PROPERTY_PROJECTION_INT( account_id2 ) + _CONTACTS_PROPERTY_PROJECTION_INT( account_id3 ) + _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_END_READ_ONLY_VIEW( _contacts_person_grouprel ) + +//person phone_log : read only +_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_END_READ_ONLY_VIEW( _contacts_person_phone_log ) + +// person, stat : read only +_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_END_READ_ONLY_VIEW( _contacts_person_usage ) + +// simple contact number : read only +_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_END_READ_ONLY_VIEW( _contacts_contact_number ) + +// simple contact email : read only +_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 ) + +// simple contact group : read only +_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 ) + +// simple contact activity : read only +_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_PROJECTION_STR( sync_data1 ) + _CONTACTS_PROPERTY_PROJECTION_STR( sync_data2 ) + _CONTACTS_PROPERTY_PROJECTION_STR( sync_data3 ) + _CONTACTS_PROPERTY_PROJECTION_STR( sync_data4 ) +_CONTACTS_END_READ_ONLY_VIEW( _contacts_contact_activity ) + +// phone_log number list : read only +_CONTACTS_BEGIN_READ_ONLY_VIEW() + _CONTACTS_PROPERTY_STR( number ) +_CONTACTS_END_READ_ONLY_VIEW( _contacts_phone_log_number ) + +// phone_log stat : read only +_CONTACTS_BEGIN_READ_ONLY_VIEW() + _CONTACTS_PROPERTY_PROJECTION_STR( log_count ) + _CONTACTS_PROPERTY_STR( log_type ) +_CONTACTS_END_READ_ONLY_VIEW( _contacts_phone_log_stat ) + +#ifdef __cplusplus +} +#endif + +#endif /* __TIZEN_SOCIAL_CONTACTS_VIEWS_H__ */ + diff --git a/native/CMakeLists.txt b/native/CMakeLists.txt new file mode 100755 index 0000000..8636905 --- /dev/null +++ b/native/CMakeLists.txt @@ -0,0 +1,28 @@ +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common) + +SET(NATIVE contacts-service3) + +FILE(GLOB SRCS *.c ../common/*.c) + +INCLUDE(FindPkgConfig) +pkg_check_modules(service_pkgs REQUIRED sqlite3 db-util capi-media-image-util badge) + +FOREACH(flag ${service_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +ADD_DEFINITIONS("-D_CONTACTS_NATIVE") + +ADD_LIBRARY(${NATIVE} SHARED ${SRCS}) +SET_TARGET_PROPERTIES(${NATIVE} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${NATIVE} PROPERTIES VERSION ${VERSION}) +TARGET_LINK_LIBRARIES(${NATIVE} ${pkgs_LDFLAGS} ${service_pkgs_LDFLAGS} -lpthread) + +INSTALL(TARGETS ${NATIVE} DESTINATION lib) + +# Make pc file and install +CONFIGURE_FILE(${NATIVE}.pc.in ${NATIVE}.pc @ONLY) +INSTALL(FILES ${NATIVE}.pc DESTINATION lib/pkgconfig) diff --git a/native/contacts-service3.pc.in b/native/contacts-service3.pc.in new file mode 100644 index 0000000..3948eac --- /dev/null +++ b/native/contacts-service3.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: @TARGET@ +Description: @PROJECT_NAME@ library +Version: @VERSION@ +Requires: glib-2.0 @PC_REQUIRED@ +Libs: -L${libdir} -l@NATIVE@ +Cflags: -I${includedir} diff --git a/native/ctsvc_activity.c b/native/ctsvc_activity.c new file mode 100644 index 0000000..5b59a50 --- /dev/null +++ b/native/ctsvc_activity.c @@ -0,0 +1,88 @@ +/*
+ * 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"
+
+API int contacts_activity_delete_by_contact_id(int contact_id)
+{
+ char query[CTS_SQL_MAX_LEN] = {0};
+
+ 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("cts_query_exec() Failed(%d)", ret);
+ ctsvc_end_trans(false);
+ return ret;
+ }
+
+ ctsvc_set_activity_noti();
+
+/* why notify twice?
+ ctsvc_set_contact_noti();
+ ctsvc_db_contact_update_changed_time(contact_id);
+*/
+
+ 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};
+
+ 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("cts_query_exec() Failed(%d)", ret);
+ ctsvc_end_trans(false);
+ return ret;
+ }
+
+ ctsvc_set_activity_noti();
+/*
+ ctsvc_set_contact_noti();
+ ctsvc_db_contact_update_changed_time(contact_id);
+*/
+
+ ret = ctsvc_end_trans(true);
+ return ret;
+}
+
+
diff --git a/native/ctsvc_activity.h b/native/ctsvc_activity.h new file mode 100644 index 0000000..f95dc52 --- /dev/null +++ b/native/ctsvc_activity.h @@ -0,0 +1,24 @@ +/*
+ * 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_ACTIVITY_H__
+#define __TIZEN_SOCIAL_CTSVC_ACTIVITY_H__
+
+#endif // __TIZEN_SOCIAL_CTSVC_PERSON_H__
+
diff --git a/native/ctsvc_db_init.c b/native/ctsvc_db_init.c new file mode 100644 index 0000000..1d0441c --- /dev/null +++ b/native/ctsvc_db_init.c @@ -0,0 +1,896 @@ +/* + * 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_restriction.h" +#include "ctsvc_view.h" +#include "ctsvc_notification.h" + +#define MODULE_NAME_DB "DB" + +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; +extern ctsvc_db_plugin_info_s ctsvc_db_plugin_phonelog; +extern ctsvc_db_plugin_info_s ctsvc_db_plugin_speeddial; +extern ctsvc_db_plugin_info_s ctsvc_db_plugin_sdn; + +extern ctsvc_db_plugin_info_s ctsvc_db_plugin_activity; +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; + + +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; +}db_table_info_s; + +static const db_table_info_s __db_tables[] = { + {CTSVC_VIEW_URI_ADDRESSBOOK, CTS_TABLE_ADDRESSBOOKS}, + {CTSVC_VIEW_URI_GROUP, CTS_TABLE_GROUPS}, + {CTSVC_VIEW_URI_PERSON, CTSVC_DB_VIEW_PERSON}, + {CTSVC_VIEW_URI_SIMPLE_CONTACT, CTSVC_DB_VIEW_CONTACT}, + {CTSVC_VIEW_URI_CONTACT, CTSVC_DB_VIEW_CONTACT}, + {CTSVC_VIEW_URI_MY_PROFILE, CTS_TABLE_MY_PROFILES}, + {CTSVC_VIEW_URI_ACTIVITY, CTSVC_DB_VIEW_ACTIVITY}, + {CTSVC_VIEW_URI_PHONELOG, CTS_TABLE_PHONELOGS}, + {CTSVC_VIEW_URI_SPEEDDIAL, CTSVC_DB_VIEW_SPEEDIDAL}, + {CTSVC_VIEW_URI_SDN, CTS_TABLE_SDN}, + + {CTSVC_VIEW_URI_NAME, CTSVC_DB_VIEW_NAME}, + {CTSVC_VIEW_URI_COMPANY, CTSVC_DB_VIEW_COMPANY}, + {CTSVC_VIEW_URI_NUMBER, CTSVC_DB_VIEW_NUMBER}, + {CTSVC_VIEW_URI_EMAIL, CTSVC_DB_VIEW_EMAIL}, + {CTSVC_VIEW_URI_URL, CTSVC_DB_VIEW_URL}, + {CTSVC_VIEW_URI_ADDRESS, CTSVC_DB_VIEW_ADDRESS}, + {CTSVC_VIEW_URI_PROFILE, CTSVC_DB_VIEW_PROFILE}, + {CTSVC_VIEW_URI_RELATIONSHIP, CTSVC_DB_VIEW_RELATIONSHIP}, + {CTSVC_VIEW_URI_IMAGE, CTSVC_DB_VIEW_IMAGE}, + {CTSVC_VIEW_URI_NOTE, CTSVC_DB_VIEW_NOTE}, + {CTSVC_VIEW_URI_NICKNAME, CTSVC_DB_VIEW_NICKNAME}, + {CTSVC_VIEW_URI_EVENT, CTSVC_DB_VIEW_EVENT}, + {CTSVC_VIEW_URI_MESSENGER, CTSVC_DB_VIEW_MESSENGER}, + {CTSVC_VIEW_URI_GROUP_RELATION, CTSVC_DB_VIEW_GROUP_RELATION}, + {CTSVC_VIEW_URI_EXTENSION, CTSVC_DB_VIEW_EXTENSION}, + +// 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}, +// {CTSVC_VIEW_URI_GROUPS_MEMBER_UPDATED_INFO, CTSVC_DB_VIEW_GROUPS_MEMBER_UPDATED_INFO}, +// {CTSVC_VIEW_URI_CONTACTS_UPDATED_INFO, CTSVC_DB_VIEW_CONTACTS_UPDATED_INFO}, +// {CTSVC_VIEW_URI_GROUPRELS_UPDATED_INFO, NULL, NULL}, + + {CTSVC_VIEW_URI_READ_ONLY_PERSON_CONTACT, CTSVC_DB_VIEW_PERSON_CONTACT}, + {CTSVC_VIEW_URI_READ_ONLY_PERSON_NUMBER, CTSVC_DB_VIEW_PERSON_NUMBER}, + {CTSVC_VIEW_URI_READ_ONLY_PERSON_EMAIL, CTSVC_DB_VIEW_PERSON_EMAIL}, + {CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP, CTSVC_DB_VIEW_PERSON_GROUP}, + {CTSVC_VIEW_URI_READ_ONLY_PERSON_PHONELOG, CTSVC_DB_VIEW_PERSON_PHONELOG}, + {CTSVC_VIEW_URI_READ_ONLY_PERSON_USAGE, CTSVC_DB_VIEW_PERSON_USAGE}, + + {CTSVC_VIEW_URI_READ_ONLY_CONTACT_NUMBER, CTSVC_DB_VIEW_CONTACT_NUMBER}, + {CTSVC_VIEW_URI_READ_ONLY_CONTACT_EMAIL, CTSVC_DB_VIEW_CONTACT_EMAIL}, + {CTSVC_VIEW_URI_READ_ONLY_CONTACT_GROUP, CTSVC_DB_VIEW_CONTACT_GROUP}, + {CTSVC_VIEW_URI_READ_ONLY_CONTACT_ACTIVITY, CTSVC_DB_VIEW_CONTACT_ACTIVITY}, + + {CTSVC_VIEW_URI_READ_ONLY_PHONELOG_NUMBER, CTSVC_DB_VIEW_PHONELOG_NUMBER}, + {CTSVC_VIEW_URI_READ_ONLY_PHONELOG_STAT, CTS_TABLE_PHONELOG_STAT}, +}; + +// this function is called in mutex lock +int ctsvc_db_plugin_init() +{ + int i; +// pims_ipc_svc_init("/opt/CONTACT_SVC", getuid(), 0660); + + 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) { + i = 0; + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_ADDRESSBOOK, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_GROUP, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_PERSON, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_SIMPLE_CONTACT, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_CONTACT, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_MY_PROFILE, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_ACTIVITY, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_PHONELOG, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_SPEEDDIAL, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_SDN, GINT_TO_POINTER(&(__db_tables[i++]))); + + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_NAME, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_COMPANY, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_NUMBER, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_EMAIL, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_URL, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_ADDRESS, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_PROFILE, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_RELATIONSHIP, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_IMAGE, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_NOTE, GINT_TO_POINTER(&(__db_tables[i++])) ); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_NICKNAME, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_EVENT, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_MESSENGER, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_GROUP_RELATION, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_EXTENSION, GINT_TO_POINTER(&(__db_tables[i++]))); + +// g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_GROUPS_UPDATED_INFO, GINT_TO_POINTER(&(__db_tables[i++])) ); +// g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_GROUPS_MEMBER_UPDATED_INFO, GINT_TO_POINTER(&(__db_tables[i++])) ); +// g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_CONTACTS_UPDATED_INFO, GINT_TO_POINTER(&(__db_tables[i++])) ); +// g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_GROUPRELS_UPDATED_INFO, GINT_TO_POINTER(&(__db_tables[i++])) ); + + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_READ_ONLY_PERSON_CONTACT, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_READ_ONLY_PERSON_NUMBER, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_READ_ONLY_PERSON_EMAIL, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_READ_ONLY_PERSON_PHONELOG, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_READ_ONLY_PERSON_USAGE, GINT_TO_POINTER(&(__db_tables[i++]))); + + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_READ_ONLY_CONTACT_NUMBER, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_READ_ONLY_CONTACT_EMAIL, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_READ_ONLY_CONTACT_GROUP, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_READ_ONLY_CONTACT_ACTIVITY, GINT_TO_POINTER(&(__db_tables[i++]))); + + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_READ_ONLY_PHONELOG_NUMBER, GINT_TO_POINTER(&(__db_tables[i++]))); + g_hash_table_insert(__ctsvc_db_view_hash_table, CTSVC_VIEW_URI_READ_ONLY_PHONELOG_STAT, GINT_TO_POINTER(&(__db_tables[i++]))); + } + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_plugin_deinit() +{ + 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_connect2()"); + + return CONTACTS_ERROR_INVALID_PARAMETER; +} + +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_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_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; + case CTSVC_RECORD_PHONELOG: + return &ctsvc_db_plugin_phonelog; + case CTSVC_RECORD_SPEEDDIAL: + return &ctsvc_db_plugin_speeddial; + case CTSVC_RECORD_SDN: + return &ctsvc_db_plugin_sdn; + 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_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, " + "sortkey, reverse_sortkey, " + "name_contact_id, " + "persons.ringtone_path, " + "persons.image_thumbnail_path, " + "persons.vibration, " + "status, " + "link_count, " + "account_id1, " + "account_id2, " + "account_id3, " + "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, " + "data2 first, " + "data3 last, " + "data4 addition, " + "data5 prefix, " + "data6 suffix, " + "data7 phonetic_first, " + "data8 phonetic_middle, " + "data9 phonetic_last " + "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, " + "is_default, " + "data1 type, " + "data2 label, " + "data3 number, " + "data4 lookup " + "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, " + "is_default, " + "data1 type, " + "data2 label, " + "data3 email " + "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, " + "is_default, " + "data1 type, " + "data2 label, " + "data3 postbox, " + "data4 postal_code, " + "data5 region, " + "data6 locality, " + "data7 street, " + "data8 extend, " + "data9 country " + "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, " + "data1 type, " + "data2 label, " + "data3 url " + "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, " + "data1 type, " + "data2 label, " + "data3 date " + "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, " + "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_name COLLATE NOCASE"); + 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, " + "data1 type, " + "data2 label, " + "data3 name " + "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, " + "data1 type, " + "data2 label, " + "data3 path " + "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, " + "data1 type, " + "data2 label, " + "data3 name, " + "data4 department, " + "data5 job_title, " + "data6 assistant, " + "data7 role, " + "data8 logo, " + "data9 location, " + "data10 description, " + "data11 phonetic_name " + "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, " + "data3 nickname " + "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, " + "data1 type, " + "data2 label, " + "data3 im_id " + "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, " + "data3 note " + "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, " + "data1 type, " + "data2 label, " + "data3 uid, " + "data4 text, " + "data5 profile_order, " + "data6 appsvc_op, " + "data7 data1, " + "data8 data2, " + "data9 data3, " + "data10 data4 " + "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, " + "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, " + "source_name, " + "status, " + "timestamp, " + "sync_data1, " + "sync_data2, " + "sync_data3, " + "sync_data4 " + "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_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.sortkey, name_contacts.reverse_sortkey, " + "persons.image_thumbnail_path, " + "data.id number_id, " + "data.data1 type, " + "data.data2 label, " + "data.data3 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); +#if 0 + // CTSVC_DB_VIEW_CONTACTS_UPDATED_INFO + snprintf(query, sizeof(query), + "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_CONTACTS_UPDATED_INFO" AS " + "SELECT %d, contact_id, changed_ver version, addressbook_id " + "FROM "CTS_TABLE_CONTACTS" " + "WHERE changed_ver == created_ver " + "UNION SELECT %d, contact_id, changed_ver version, addressbook_id " + "FROM "CTS_TABLE_CONTACTS" " + "WHERE changed_ver > created_ver " + "UNION SELECT %d, contact_id, deleted_ver version, addressbook_id " + "FROM "CTS_TABLE_DELETEDS, + CONTACTS_CHANGE_INSERTED, CONTACTS_CHANGE_UPDATED, CONTACTS_CHANGE_DELETED); + ret = ctsvc_query_exec(query); + RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret); + + // CTSVC_DB_VIEW_GROUPS_UPDATED_INFO + snprintf(query, sizeof(query), + "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_GROUPS_UPDATED_INFO" AS " + "SELECT %d, group_id, changed_ver version, addressbook_id " + "FROM "CTS_TABLE_GROUPS" " + "WHERE changed_ver == created_ver " + "UNION SELECT %d, group_id, changed_ver version, addressbook_id " + "FROM "CTS_TABLE_GROUPS" " + "WHERE changed_ver > created_ver " + "UNION SELECT %d, group_id, deleted_ver version, addressbook_id " + "FROM "CTS_TABLE_GROUP_DELETEDS, + CONTACTS_CHANGE_INSERTED, CONTACTS_CHANGE_UPDATED, CONTACTS_CHANGE_DELETED); + ret = ctsvc_query_exec(query); + RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret); +#endif + + // CTSVC_DB_VIEW_GROUPS_MEMBER_UPDATED_INFO + snprintf(query, sizeof(query), + "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_GROUPS_MEMBER_UPDATED_INFO" AS " + "SELECT group_id, member_changed_ver version, addressbook_id " + "FROM "CTS_TABLE_GROUPS); + ret = ctsvc_query_exec(query); + RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : ctsvc_query_exec() Failed(%d)", ret); + + // 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 normalized_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); + + // CTSVC_DB_VIEW_PERSON_PHONELOG + snprintf(query, sizeof(query), + "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_PERSON_PHONELOG" AS " + "SELECT C.id phonelog_id, " + "F.display_name, F.reverse_display_name, " + "F.display_name_language, " + "F.sortkey, F.reverse_sortkey, " + "F.image_thumbnail_path, " + "C.number address, " + "C.log_type, " + "C.log_time, " + "C.data1, " + "C.data2, " + "C.person_id id, " + "C.number_type address_type " + "FROM (SELECT A.id, A.number, A.log_type, A.log_time, A.data1, A.data2, " + "MIN(B.person_id) person_id, B.data1 number_type " + "FROM "CTS_TABLE_PHONELOGS" A " + "LEFT JOIN (SELECT G.person_id person_id, G.contact_id contact_id, " + "H.datatype datatype, H.data1 data1, H.data4 data4 " + "FROM "CTSVC_DB_VIEW_CONTACT" G, "CTS_TABLE_DATA" H " + "ON H.datatype = %d AND G.contact_id = H.contact_id AND H.is_my_profile = 0 ) B " + "ON A.normal_num = B.data4 " + "AND (A.person_id = B.person_id " + "OR A.person_id IS NULL " + "OR NOT EXISTS (SELECT id FROM "CTS_TABLE_DATA" " + "WHERE datatype = %d AND is_my_profile = 0 " + "AND contact_id IN(SELECT contact_id " + "FROM "CTSVC_DB_VIEW_CONTACT" " + "WHERE person_id = A.person_id) " + "AND A.normal_num = data4)) " + "GROUP BY A.id) C " + "LEFT JOIN (SELECT D.person_id, D.display_name, D.reverse_display_name, " + "D.display_name_language, D.sortkey, D.reverse_sortkey, " + "E.image_thumbnail_path " + "FROM "CTS_TABLE_CONTACTS" D, "CTS_TABLE_PERSONS" E " + "ON E.name_contact_id = D.contact_id) F " + "ON C.person_id = F.person_id " + "ORDER BY C.log_time DESC", + CTSVC_DATA_NUMBER, 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_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 * FROM "CTSVC_DB_VIEW_PERSON_CONTACT" " + "LEFT JOIN (SELECT group_relations.group_id, " + "group_name, " + "contact_id contact_id_in_group " + "FROM "CTS_TABLE_GROUP_RELATIONS", "CTS_TABLE_GROUPS" " + "ON group_relations.group_id = groups.group_id AND deleted = 0) temp_group " + "ON temp_group.contact_id_in_group = "CTSVC_DB_VIEW_PERSON_CONTACT".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_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 normalized_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 * FROM "CTSVC_DB_VIEW_CONTACT" " + "LEFT JOIN (SELECT group_relations.group_id, " + "group_name, " + "contact_id contact_id_in_group " + "FROM "CTS_TABLE_GROUP_RELATIONS", "CTS_TABLE_GROUPS" " + "ON group_relations.group_id = groups.group_id AND deleted = 0) temp_group " + "ON temp_group.contact_id_in_group = "CTSVC_DB_VIEW_CONTACT".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_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.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.sync_data1, " + "AC.sync_data2, " + "AC.sync_data3, " + "AC.sync_data4 " + "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_PHONELOG_NUMBER + snprintf(query, sizeof(query), + "CREATE VIEW IF NOT EXISTS "CTSVC_DB_VIEW_PHONELOG_NUMBER" AS " + "SELECT DISTINCT number FROM "CTS_TABLE_PHONELOGS" " + "WHERE log_type < %d", CONTACTS_PLOG_TYPE_EMAIL_RECEIVED); + 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; + } + ret = ctsvc_restriction_init(); + if (ret != CONTACTS_ERROR_NONE) { + CTS_ERR("ctsvc_restriction_init() Failed(%d)", ret); + return ret; + } + +#ifdef _CONTACTS_IPC_SERVER + ret = __ctsvc_db_create_views(); +#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; + } + ctsvc_restriction_deinit(); + return CONTACTS_ERROR_NONE; +} + + diff --git a/native/ctsvc_db_init.h b/native/ctsvc_db_init.h new file mode 100644 index 0000000..deb6e91 --- /dev/null +++ b/native/ctsvc_db_init.h @@ -0,0 +1,71 @@ +/* + * 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_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_db_plugin_init(); +int ctsvc_db_plugin_deinit(); + + +#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 index 0000000..fdab06f --- /dev/null +++ b/native/ctsvc_db_plugin_activity.c @@ -0,0 +1,529 @@ +/* + * 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_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" + +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_photo_insert_record( ctsvc_activity_photo_s *photo, int activity_id ) +{ + int ret; + cts_stmt stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + RETV_IF(NULL == photo, CONTACTS_ERROR_INVALID_PARAMETER); + RETV_IF(NULL == photo->photo_url, CONTACTS_ERROR_INVALID_PARAMETER); + snprintf(query, sizeof(query), "INSERT INTO "CTS_TABLE_ACTIVITY_PHOTOS"(" + "activity_id, photo_url, sort_index) " + "VALUES(%d, ?, %d)", + activity_id, photo->sort_index); + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + + cts_stmt_bind_text(stmt, 1, photo->photo_url); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_activity_insert_record( contacts_record_h record, int *id ) +{ + int ret; + int activity_id; + int contact_id; + cts_stmt stmt = NULL; + unsigned 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 contact_id from %s WHERE contact_id = %d", + CTSVC_DB_VIEW_CONTACT, activity->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret ) { + CTS_ERR("No data : contact id (%d)", activity->contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + snprintf(query, sizeof(query), "INSERT INTO "CTS_TABLE_ACTIVITIES"(" + "contact_id, source_name, status, timestamp, sync_data1, sync_data2, " + "sync_data3, sync_data4) " + "VALUES(%d, ?, ?, %d, ?, ?, ?, ?)", + activity->contact_id, activity->timestamp); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("DB error : cts_query_prepare() Failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + if (activity->source_name) + cts_stmt_bind_text(stmt, 1, activity->source_name); + if (activity->status) + cts_stmt_bind_text(stmt, 2, activity->status); + if (activity->sync_data1) + cts_stmt_bind_text(stmt, 3, activity->sync_data1); + if (activity->sync_data2) + cts_stmt_bind_text(stmt, 4, activity->sync_data2); + if (activity->sync_data3) + cts_stmt_bind_text(stmt, 5, activity->sync_data3); + if (activity->sync_data4) + cts_stmt_bind_text(stmt, 6, activity->sync_data4); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + + activity_id = cts_db_get_last_insert_id(); + + cts_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_record(photo, activity_id); + 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_contact_noti(); + + ret = ctsvc_db_contact_update_changed_time(activity->contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_query_exec() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + + 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_photo_value_set(cts_stmt stmt, contacts_record_h *record) +{ + int i = 0; + char *temp; + ctsvc_activity_photo_s *photo; + + contacts_record_create(_contacts_activity_photo._uri, record); + photo = (ctsvc_activity_photo_s*)*record; + + photo->id = ctsvc_stmt_get_int(stmt, i++); + photo->activity_id = ctsvc_stmt_get_int(stmt, i++); + temp = ctsvc_stmt_get_text(stmt, i++); + photo->photo_url = SAFE_STRDUP(temp); + photo->sort_index = ctsvc_stmt_get_int(stmt, i++); + + 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->sync_data1 = SAFE_STRDUP(temp); + temp = ctsvc_stmt_get_text(stmt, i++); + activity->sync_data2 = SAFE_STRDUP(temp); + temp = ctsvc_stmt_get_text(stmt, i++); + activity->sync_data3 = SAFE_STRDUP(temp); + temp = ctsvc_stmt_get_text(stmt, i++); + activity->sync_data4 = SAFE_STRDUP(temp); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_activity_photo_get_records(int id, contacts_record_h record) +{ + char query[CTS_SQL_MAX_LEN] = {0}; + int ret; + cts_stmt stmt = NULL; + contacts_list_h list; + + snprintf(query, sizeof(query), "SELECT id, activity_id, photo_url, sort_index " + "FROM "CTS_TABLE_ACTIVITY_PHOTOS" WHERE activity_id = %d " + "ORDER BY sort_index ASC", id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return ret; + } + + __ctsvc_db_activity_photo_value_set(stmt, &record); + + ctsvc_list_prepend(list, record); + } + + cts_stmt_finalize(stmt); + + ((ctsvc_activity_s*)record)->photos = (ctsvc_list_s*)list; + + 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, sync_data1, sync_data2, sync_data3, sync_data4 " + "FROM "CTSVC_DB_VIEW_ACTIVITY" WHERE id = %d", id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + __ctsvc_db_activity_value_set(stmt, &record); + cts_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 contact_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 contact_id FROM "CTSVC_DB_VIEW_ACTIVITY" WHERE id = %d", id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret ) { + CTS_ERR("No data : id (%d)", id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_NO_DATA; + } + + 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("cts_query_exec() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + + ctsvc_set_activity_noti(); + ctsvc_set_contact_noti(); + + ret = ctsvc_db_contact_update_changed_time(contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_query_exec() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + + 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, contact_id, source_name, status, " + "timestamp, sync_data1, sync_data2, sync_data3, sync_data4 " + "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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return CONTACTS_ERROR_NO_DATA; + } + ctsvc_list_prepend(list, record); + } + cts_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) { + s_query->projection = realloc(s_query->projection, s_query->projection_count+1); + 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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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_SYNC_DATA1: + temp = ctsvc_stmt_get_text(stmt, i); + activity->sync_data1 = SAFE_STRDUP(temp); + break; + case CTSVC_PROPERTY_ACTIVITY_SYNC_DATA2: + temp = ctsvc_stmt_get_text(stmt, i); + activity->sync_data2 = SAFE_STRDUP(temp); + break; + case CTSVC_PROPERTY_ACTIVITY_SYNC_DATA3: + temp = ctsvc_stmt_get_text(stmt, i); + activity->sync_data3 = SAFE_STRDUP(temp); + break; + case CTSVC_PROPERTY_ACTIVITY_SYNC_DATA4: + temp = ctsvc_stmt_get_text(stmt, i); + activity->sync_data4 = SAFE_STRDUP(temp); + break; + default: + break; + } + } + __ctsvc_db_activity_photo_get_records(activity_id, record); + + ctsvc_list_prepend(list, record); + } + cts_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_address.c b/native/ctsvc_db_plugin_address.c new file mode 100644 index 0000000..d5d7440 --- /dev/null +++ b/native/ctsvc_db_plugin_address.c @@ -0,0 +1,371 @@ +/* + * 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" + +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 contact_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", address->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + 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_query_exec() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + + 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 contact_id; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_address_s *address = (ctsvc_address_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", address->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + ret = ctsvc_db_address_update(record, address->contact_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(address->contact_id); + 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) + return ret; + else + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_address_delete_record( int id ) +{ + int ret; + int contact_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 FROM "CTS_TABLE_DATA" WHERE id = %d", id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret ) { + CTS_ERR("No data : id (%d)", id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_NO_DATA; + } + + ret = ctsvc_db_address_delete(id); + if (CONTACTS_ERROR_NONE != ret) { + ret = ctsvc_db_contact_update_changed_time(contact_id); + 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); + } + else + ctsvc_end_trans(false); + + 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 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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + ctsvc_db_address_get_value_from_stmt(stmt, (contacts_record_h*)&address, 0); + cts_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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step Failed(%d)", ret); + cts_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); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step Failed(%d)", ret); + cts_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); + } + cts_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 index 0000000..3bdc4b4 --- /dev/null +++ b/native/ctsvc_db_plugin_address_helper.c @@ -0,0 +1,218 @@ +/* + * 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_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; +} + +int ctsvc_db_address_insert(contacts_record_h record, int contact_id, bool is_my_profile, int *id) +{ + int ret; + cts_stmt stmt = NULL; + ctsvc_address_s *address = (ctsvc_address_s*)record; + char query[CTS_SQL_MAX_LEN] = {0}; + +// RETVM_IF(address->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted address record"); + 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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + if (address->label) + sqlite3_bind_text(stmt, 1, address->label, + strlen(address->label), SQLITE_STATIC); + if (address->pobox) + sqlite3_bind_text(stmt, 2, address->pobox, + strlen(address->pobox), SQLITE_STATIC); + if (address->postalcode) + sqlite3_bind_text(stmt, 3, address->postalcode, + strlen(address->postalcode), SQLITE_STATIC); + if (address->region) + sqlite3_bind_text(stmt, 4, address->region, + strlen(address->region), SQLITE_STATIC); + if (address->locality) + sqlite3_bind_text(stmt, 5, address->locality, + strlen(address->locality), SQLITE_STATIC); + if (address->street) + sqlite3_bind_text(stmt, 6, address->street, + strlen(address->street), SQLITE_STATIC); + if (address->extended) + sqlite3_bind_text(stmt, 7, address->extended, + strlen(address->extended), SQLITE_STATIC); + if (address->country) + sqlite3_bind_text(stmt, 8, address->country, + strlen(address->country), SQLITE_STATIC); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + if (id) + *id = cts_db_get_last_insert_id(); + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_address_noti(); + } + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_address_update(contacts_record_h record, int contact_id, bool is_my_profile) +{ + int ret; + cts_stmt stmt = NULL; + ctsvc_address_s *address = (ctsvc_address_s*)record; + char query[CTS_SQL_MAX_LEN] = {0}; + +// RETVM_IF(address->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted address record"); + 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"); + 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(address->id <= 0, CONTACTS_ERROR_INVALID_PARAMETER, + "Invalid parameter : id(%d), This record is already inserted", address->id); + + snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_DATA" SET is_my_profile=%d, is_default=?, data1 = ?, data2 = ?, data3 = ?, " + "data4 = ?, data5 = ?, data6 = ?, data7 = ?, data8 = ?, data9 = ? " + "WHERE id = %d", is_my_profile, address->id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + sqlite3_bind_int(stmt, 1, address->is_default); + sqlite3_bind_int(stmt, 2, address->type); + + if (address->label) + sqlite3_bind_text(stmt, 3, address->label, + strlen(address->label), SQLITE_STATIC); + if (address->pobox) + sqlite3_bind_text(stmt, 4, address->pobox, + strlen(address->pobox), SQLITE_STATIC); + if (address->postalcode) + sqlite3_bind_text(stmt, 5, address->postalcode, + strlen(address->postalcode), SQLITE_STATIC); + if (address->region) + sqlite3_bind_text(stmt, 6, address->region, + strlen(address->region), SQLITE_STATIC); + if (address->locality) + sqlite3_bind_text(stmt, 7, address->locality, + strlen(address->locality), SQLITE_STATIC); + if (address->street) + sqlite3_bind_text(stmt, 8, address->street, + strlen(address->street), SQLITE_STATIC); + if (address->extended) + sqlite3_bind_text(stmt, 9, address->extended, + strlen(address->extended), SQLITE_STATIC); + if (address->country) + sqlite3_bind_text(stmt, 10, address->country, + strlen(address->country), SQLITE_STATIC); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_address_noti(); + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_address_delete(int id) +{ + int ret; + cts_stmt stmt; + 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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + cts_stmt_finalize(stmt); + + 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 index 0000000..4af38f7 --- /dev/null +++ b/native/ctsvc_db_plugin_address_helper.h @@ -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, int contact_id, bool is_my_profile); +int ctsvc_db_address_delete(int id); +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 index 0000000..56557fd --- /dev/null +++ b/native/ctsvc_db_plugin_addressbook.c @@ -0,0 +1,522 @@ +/* + * 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_db_plugin_person_helper.h" +#include "ctsvc_person.h" +#include "ctsvc_record.h" +#include "ctsvc_notification.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; + int len; + 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; + + len = snprintf(query, sizeof(query), + "SELECT addressbook_id, addressbook_name, account_id, mode, last_sync_ver " + "FROM "CTS_TABLE_ADDRESSBOOKS" WHERE addressbook_id = %d", + id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ret = __ctsvc_db_addressbook_value_set(stmt, &record); + + cts_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 ) +{ + 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); + + cts_stmt stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + snprintf(query, sizeof(query), + "INSERT INTO %s(addressbook_name, account_id, mode) " + "VALUES(?, %d, %d)", + CTS_TABLE_ADDRESSBOOKS, addressbook->account_id, addressbook->mode); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("DB error : cts_query_prepare() Failed"); + return CONTACTS_ERROR_DB; + } + + cts_stmt_bind_text(stmt, 1, addressbook->name); + + /* BEGIN_TRANSACTION */ + int ret = ctsvc_begin_trans(); + if( ret < CONTACTS_ERROR_NONE ) + { + CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + /* DOING JOB */ + do { + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + break; + } + + //int index = cts_db_get_last_insert_id(); + if (id) + *id = cts_db_get_last_insert_id(); + cts_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); + return ret; + } + //addressbook->id = index; + + // SUCCESS + return CONTACTS_ERROR_NONE; + + } while(0); + + /* ROLLBACK TRANSACTION */ + ctsvc_end_trans(false); + + return ret; +} + +static int __ctsvc_db_addressbook_update_record( contacts_record_h record ) +{ + 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); + + cts_stmt stmt = NULL; + char query[CTS_SQL_MIN_LEN] = {0}; + + snprintf(query, sizeof(query), + "UPDATE %s SET addressbook_name=?, account_id=%d, mode=%d " + "WHERE addressbook_id=%d", CTS_TABLE_ADDRESSBOOKS, + addressbook->account_id, addressbook->mode, addressbook->id); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("DB error : cts_query_prepare() Failed"); + return CONTACTS_ERROR_DB; + } + + cts_stmt_bind_text(stmt, 1, addressbook->name); + + /* BEGIN_TRANSACTION */ + int ret = ctsvc_begin_trans(); + if( ret < CONTACTS_ERROR_NONE ) + { + CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + /* DOING JOB */ + do { + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + break; + } + cts_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); + return ret; + } + + return CONTACTS_ERROR_NONE; + + } while(0); + + /* ROLLBACK TRANSACTION */ + ctsvc_end_trans(false); + + return ret; +} + +static inline int __ctsvc_db_addressbook_reset_internal_addressbook(void) +{ + CTS_FN_CALL; + char query[CTS_SQL_MIN_LEN] = {0}; + + 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*/); + + /* BEGIN_TRANSACTION */ + int ret = ctsvc_begin_trans(); + RETVM_IF(CONTACTS_ERROR_NONE > ret, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret); + + /* 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 : cts_person_garbagecollection() Failed(%d)", ret); + break; + } + + ctsvc_set_contact_noti(); + ctsvc_set_my_profile_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; +} + +static int __ctsvc_db_addressbook_delete_record( int addressbook_id ) +{ + CTS_FN_CALL; + + if (0 /*CTS_ADDRESSBOOK_INTERNAL*/ == addressbook_id) + return __ctsvc_db_addressbook_reset_internal_addressbook(); + + char query[CTS_SQL_MAX_LEN] = {0}; + snprintf(query, sizeof(query), "DELETE FROM %s WHERE addressbook_id = %d", + CTS_TABLE_ADDRESSBOOKS, addressbook_id); + + /* BEGIN_TRANSACTION */ + int ret = ctsvc_begin_trans(); + RETVM_IF(CONTACTS_ERROR_NONE > ret, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret); + + /* 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 = cts_db_change(); + if (0 < ret) { + ctsvc_set_my_profile_noti(); + ctsvc_set_contact_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 : cts_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" 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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return CONTACTS_ERROR_NO_DATA; + } + __ctsvc_db_addressbook_value_set(stmt, &record); + + ctsvc_list_prepend(list, record); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return CONTACTS_ERROR_NO_DATA; + } + + 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; + + 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_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); + } + cts_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_company.c b/native/ctsvc_db_plugin_company.c new file mode 100644 index 0000000..7bd00a0 --- /dev/null +++ b/native/ctsvc_db_plugin_company.c @@ -0,0 +1,404 @@ +/* + * 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_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" + +#define CTS_LOGO_IMAGE_LOCATION "/opt/usr/data/contacts-svc/img/logo" + +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; + int len; + cts_stmt stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER); + *out_record = NULL; + + 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 id = %d AND datatype = %d ", + id, CTSVC_DATA_COMPANY); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ctsvc_db_company_get_value_from_stmt(stmt, out_record, 0); + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_company_insert_record( contacts_record_h record, int *id ) +{ + int ret; + int contact_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", company->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + 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; + } + + ret = ctsvc_db_contact_update_changed_time(company->contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + + ctsvc_set_contact_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 contact_id; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_company_s *company = (ctsvc_company_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", company->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + ret = ctsvc_db_company_update(record, company->contact_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 display company update + ret = ctsvc_db_contact_update_changed_time(company->contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + + ctsvc_set_contact_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}; + + 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 FROM "CTSVC_DB_VIEW_CONTACT" " + "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if( ret != CONTACTS_ERROR_NONE ) { + CTS_ERR("The id(%d) is Invalid(%d)", id, ret); + ctsvc_end_trans(false); + return contact_id; + } + + ret = ctsvc_db_company_delete(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(contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + + ctsvc_set_contact_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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB : cts_stmt_step fail(%d)", ret); + cts_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); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + } + cts_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 index 0000000..31f48f0 --- /dev/null +++ b/native/ctsvc_db_plugin_company_helper.c @@ -0,0 +1,307 @@ +/* + * 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_plugin_company_helper.h" +#include "ctsvc_record.h" +#include "ctsvc_notification.h" + +#define CTS_LOGO_IMAGE_LOCATION "/opt/usr/data/contacts-svc/img/logo" + +static int __ctsvc_company_add_logo_file(int index, char *src_img, char *dest_name, int dest_size) +{ + int ret; + char *ext; + char dest[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0}; + + RETVM_IF(NULL == src_img, CONTACTS_ERROR_INVALID_PARAMETER, "img_path is NULL"); + RETVM_IF(NULL == dest_name, CONTACTS_ERROR_INVALID_PARAMETER, "img_path is NULL"); + dest_name[0] = '\0'; + + ext = strrchr(src_img, '.'); + if (NULL == ext || strchr(ext, '/')) + ext = ""; + + snprintf(dest, sizeof(dest), "%s/%d%s", + CTS_LOGO_IMAGE_LOCATION, index, ext); + + ret = ctsvc_copy_image(src_img, dest); + RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "cts_copy_file() Failed(%d)", ret); + + snprintf(dest_name, dest_size, "%d%s", index, ext); + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_company_update_logo_file(int index, char *src_img, char *dest_name, int dest_size) +{ + int ret; + dest_name[0] = '\0'; + ret = ctsvc_company_delete_logo_file(index); + RETVM_IF(CONTACTS_ERROR_NONE != ret && CONTACTS_ERROR_NO_DATA != ret, + ret, "ccts_company_delete_logo_file() Failed(%d)", ret); + + if (src_img) { + ret = __ctsvc_company_add_logo_file(index, src_img, dest_name, dest_size); + RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_company_add_logo_file() Failed(%d)", ret); + } + return ret; +} + +static int __ctsvc_company_bind_stmt(cts_stmt stmt, ctsvc_company_s *company, int start_cnt) +{ + cts_stmt_bind_int(stmt, start_cnt, company->is_default); + cts_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; + cts_stmt stmt = NULL; + ctsvc_company_s *company = (ctsvc_company_s*)record; + char query[CTS_SQL_MAX_LEN] = {0}; + +// RETVM_IF(company->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted company record"); + 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) { + 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_COMPANY); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + __ctsvc_company_bind_stmt(stmt, company, 1); + if (company->logo) { + char image[CTS_SQL_MAX_LEN] = {0}; + ret = __ctsvc_company_add_logo_file(company->contact_id, company->logo, image, sizeof(image)); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("__ctsvc_company_add_logo_file() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + cts_stmt_bind_text(stmt, 9, image); + } + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + if (id) + *id = cts_db_get_last_insert_id(); + cts_stmt_finalize(stmt); + + 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; + ctsvc_company_s *company = (ctsvc_company_s*)record; + char query[CTS_SQL_MAX_LEN] = {0}; + cts_stmt stmt; + + RETVM_IF(!company->id, CONTACTS_ERROR_INVALID_PARAMETER, "company of contact has no ID."); + + if (company->name || company->department || company->job_title || company->role + || company->assistant_name || company->logo || company->location || company->description + || company->phonetic_name) { + snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_DATA" SET contact_id=%d, is_my_profile=%d, is_default=?, data1=?, data2=?, data3=?, data4=?," + "data5=?, data6=?, data7=?, data8=?, data9=?, data10=?, data11=?, data12=? WHERE id=%d", + contact_id, is_my_profile, company->id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + __ctsvc_company_bind_stmt(stmt, company, 1); + if (company->logo_changed) { + char dest[CTS_SQL_MAX_LEN] = {0}; + __ctsvc_company_update_logo_file(contact_id, company->logo, dest, sizeof(dest)); + if (*dest) + cts_stmt_bind_text(stmt, 9, dest); + company->logo_changed = false; + } + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_company_noti(); + } + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_company_delete(int id) +{ + 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); + ctsvc_set_company_noti(); + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_company_delete_logo_file(int index) +{ + int ret; + cts_stmt stmt; + char *tmp_path; + char query[CTS_SQL_MIN_LEN] = {0}; + snprintf(query, sizeof(query), + "SELECT data8 FROM %s WHERE contact_id = %d AND datatype = %d AND is_my_profile = 0", + CTS_TABLE_DATA, index, CTSVC_DATA_COMPANY); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare() Failed"); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_DB; + } + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_DBG("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + tmp_path = ctsvc_stmt_get_text(stmt, 0); + if (tmp_path) { + char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0}; + snprintf(full_path, sizeof(full_path), "%s/%s", CTS_LOGO_IMAGE_LOCATION, tmp_path); + ret = unlink(full_path); + WARN_IF(ret < 0, "unlink(%s) Failed(%d)", full_path, errno); + } + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + diff --git a/native/ctsvc_db_plugin_company_helper.h b/native/ctsvc_db_plugin_company_helper.h new file mode 100644 index 0000000..93644be --- /dev/null +++ b/native/ctsvc_db_plugin_company_helper.h @@ -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_DB_PLUGIN_COMPANY_HELPER_H__ +#define __CTSVC_DB_PLUGIN_COMPANY_HELPER_H__ + +#include "contacts.h" +#include "ctsvc_sqlite.h" + +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); + +int ctsvc_db_company_get_value_from_stmt(cts_stmt stmt, contacts_record_h *record, int start_count); +int ctsvc_company_delete_logo_file(int index); + +#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 index 0000000..f1b9516 --- /dev/null +++ b/native/ctsvc_db_plugin_contact.c @@ -0,0 +1,2089 @@ +/* + * 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.h" +#include "ctsvc_person.h" + +#include "ctsvc_db_plugin_contact_helper.h" +#include "ctsvc_db_plugin_person_helper.h" + +#define CTSVC_MY_IMAGE_LOCATION "/opt/usr/data/contacts-svc/img/my" + +#define CTSVC_CONTACT_DISPLAY_NAME_MAX_LEN 1024 +#define CTSVC_CONTACT_SEARCH_DATA_MAX_LEN 1024 +#define CTSVC_CONTACT_INITIAL_DATA_MAX_LEN 128 + +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, len; + 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}; + + len = snprintf(query, sizeof(query), + "SELECT contact_id, addressbook_id, person_id, changed_time, %s, " + "display_name_source, image_thumbnail_path, " + "ringtone_path, vibration, uid, is_favorite, has_phonenumber, has_email " + "FROM "CTS_TABLE_CONTACTS" WHERE contact_id = %d AND deleted = 0", + ctsvc_get_display_column(), id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + 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++); + 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", CTS_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->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++); +#if 0 + contact->sync_data1 = SAFE_STRDUP(temp); + temp = ctsvc_stmt_get_text(stmt, i++); + contact->sync_data1 = SAFE_STRDUP(temp); + temp = ctsvc_stmt_get_text(stmt, i++); + contact->sync_data1 = SAFE_STRDUP(temp); + temp = ctsvc_stmt_get_text(stmt, i++); + contact->sync_data1 = SAFE_STRDUP(temp); +#endif + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_get_data(int id, ctsvc_contact_s *contact) +{ + int ret, len; + int datatype; + cts_stmt stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + len = 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", id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE */!= ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_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 /*CTS_TRUE*/ == cts_stmt_step(stmt)); + + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; + +} + +static inline int __ctsvc_get_contact_grouprel(int contact_id, ctsvc_contact_s *contact) +{ + CTS_FN_CALL; + 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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + while (1 /*CTS_TRUE */ == cts_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); + } + } + + cts_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("cts_get_main_contacts_info(ALL) Failed(%d)", ret); + contacts_record_destroy(record, true); + return ret; + } + + ret = __ctsvc_db_get_data(id, contact); + if (CONTACTS_ERROR_NONE != 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 ) +{ + 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; + + snprintf(query, sizeof(query), + "SELECT addressbook_id, person_id " + "FROM "CTS_TABLE_CONTACTS" WHERE contact_id = %d AND deleted = 0", id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + 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); + cts_stmt_finalize(stmt); + + ret = ctsvc_begin_trans(); + RETVM_IF(ret, ret, "DB error : ctsvc_begin_trans() Failed(%d)", ret); + + 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, ctsvc_get_next_ver(), CTS_TABLE_GROUP_RELATIONS, 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 = cts_db_change(); + // images are deleted by db trigger callback function in ctsvc_db_contact_delete_callback + snprintf(query, sizeof(query), "DELETE FROM %s WHERE contact_id = %d", + CTS_TABLE_CONTACTS, 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); + 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 int __ctsvc_safe_strcmp(char *s1, char *s2) +{ + if (NULL == s1 || NULL == s2) + return !(s1 == s2); + else + return strcmp(s1, s2); +} + +static inline void __ctsvc_update_contact_display_name(ctsvc_contact_s *contact) +{ + char *temp_display_name = NULL; + char *display = NULL; + char *sortkey = NULL; + GList *cur; + int ret, len=0, display_len=0; + + ctsvc_name_s *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) ) { + if (name->first && name->last){ + temp_display_name = calloc(1, SAFE_STRLEN(name->first) + SAFE_STRLEN(name->first) + 2 ); + snprintf(temp_display_name, SAFE_STRLEN(name->first) + SAFE_STRLEN(name->first) + 2, "%s %s",name->first,name->last); + } + else if (name->first) + temp_display_name = strdup(name->first); + else + temp_display_name = strdup(name->last); + + if (0 != __ctsvc_safe_strcmp(contact->display_name, temp_display_name) + || CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME != contact->display_source_type) { + contact->display_name_changed = true; + + // make display name + display_len = SAFE_STRLEN(name->first) + + SAFE_STRLEN(name->addition) + + SAFE_STRLEN(name->last) + + SAFE_STRLEN(name->suffix) + 5; + + display = calloc(1, display_len); + + if(name->first) + len += snprintf(display + len, display_len - len, "%s", name->first); + + if(name->addition) { + if (*display) + len += snprintf(display + len, display_len - len, " "); + len += snprintf(display + len, display_len - len, "%s", name->addition); + } + + if(name->last) { + if (*display) + len += snprintf(display + len, display_len - len, " "); + len += snprintf(display + len, display_len - len, "%s", name->last); + } + + if(name->suffix) { + if (*display) + len += snprintf(display + len, display_len - len, " "); + len += snprintf(display + len, display_len - len, "%s", name->suffix); + } + contact->display_name = display; + + display = calloc(1, display_len); + // make reverse_display_name + len = 0; + if(name->last) { + len += snprintf(display + len, display_len - len, "%s", name->last); + + if(name->first || name->addition) + len += snprintf(display + len, display_len - len, ","); + } + + if(name->first) { + if (*display) + len += snprintf(display + len, display_len - len, " "); + len += snprintf(display + len, display_len - len, "%s", name->first); + } + + if(name->addition) { + if (*display) + len += snprintf(display + len, display_len - len, " "); + len += snprintf(display + len, display_len - len, "%s", name->addition); + } + + if(name->suffix) { + if (*display) + len += snprintf(display + len, sizeof(display) - len, " "); + len += snprintf(display + len, sizeof(display) - len, "%s", name->suffix); + } + + + contact->reverse_display_name = display; + + ret = ctsvc_check_language_type(contact->display_name); + if (0 <= ret) { + if (ctsvc_get_default_language() == ret) + contact->display_name_language = CTSVC_LANG_DEFAULT; + else if (ctsvc_get_secondary_language() == ret) + contact->display_name_language = CTSVC_LANG_SECONDARY; + else + contact->display_name_language = ret; + } + + ret = ctsvc_collation_str(contact->display_name, &sortkey); + if (CONTACTS_ERROR_NONE == ret) + contact->sortkey = sortkey; + else + free(sortkey); + sortkey = NULL; + + ret = ctsvc_collation_str(contact->reverse_display_name, &sortkey); + if (CONTACTS_ERROR_NONE == ret) + contact->reverse_sortkey = sortkey; + else + free(sortkey); + contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME; + } + + free(temp_display_name); + } + + else { + 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) { + if (__ctsvc_safe_strcmp(contact->display_name, company->name) + || CONTACTS_DISPLAY_NAME_SOURCE_TYPE_COMPANY != contact->display_source_type) { + contact->display_name_changed = true; + contact->display_name = SAFE_STRDUP(company->name); + contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_COMPANY; + break; + } + } + } + } + else if (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) { + if (__ctsvc_safe_strcmp(contact->display_name, nickname->nickname) + || CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NICKNAME != contact->display_source_type) { + contact->display_name = SAFE_STRDUP(nickname->nickname); + contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NICKNAME; + break; + } + } + } + } + else if (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) { + if (__ctsvc_safe_strcmp(contact->display_name, number->number) + || CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NUMBER != contact->display_source_type) { + contact->display_name_changed = true; + contact->display_name = SAFE_STRDUP(number->number); + contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NUMBER; + break; + } + } + } + } + else if (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) { + if (__ctsvc_safe_strcmp(contact->display_name, email->email_addr) + || CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL != contact->display_source_type) { + contact->display_name_changed = true; + contact->display_name = SAFE_STRDUP(email->email_addr); + contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL; + break; + } + } + } + } + + if (contact->display_name_changed) { + contact->reverse_display_name = SAFE_STRDUP(contact->display_name); + + ret = ctsvc_check_language_type(contact->display_name); + if (0 <= ret) { + if (ctsvc_get_default_language() == ret) + contact->display_name_language = CTSVC_LANG_DEFAULT; + else if (ctsvc_get_secondary_language() == ret) + contact->display_name_language = CTSVC_LANG_SECONDARY; + else + contact->display_name_language = ret; + } + + ret = ctsvc_collation_str(contact->display_name, &sortkey); + if (CONTACTS_ERROR_NONE == ret) { + contact->sortkey = sortkey; + contact->reverse_sortkey = strdup(sortkey); + } + else + free(sortkey); + } + } + return; +} + +static inline int __ctsvc_update_contact_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); +} + +static inline int __ctsvc_update_contact_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; + unsigned 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; + + 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 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); i++) + { + if (src[i] == ' ') { + bFirst=true; + } else if (bFirst) { + dest[j++] = src[i]; + if (!pinyin) + dest[j++] = ' '; + bFirst = false; + } + } + CTS_DBG("src(%s) dest(%s)", src, dest); +} + +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'; +} + +static inline int __ctsvc_contact_make_search_name(ctsvc_contact_s *contact, char **search_name) { + char *name = NULL; + int buf_size, ret; + + if (contact->display_name) { + if (ctsvc_has_chinese(contact->display_name)) { + pinyin_name_s *pinyinname; + int size, i; + + ret = ctsvc_convert_chinese_to_pinyin(contact->display_name, &pinyinname, &size); + + if (CONTACTS_ERROR_NONE == ret) { + char *name_nospace = calloc(1, CHINESE_PINYIN_SPELL_MAX_LEN); + char *temp_name = NULL; + + name = calloc(1, strlen(contact->display_name)* 5); + + ctsvc_normalize_str(contact->display_name, name, strlen(contact->display_name)* 5); + + for(i=0; i<size; i++) { + __ctsvc_remove_space(pinyinname[i].pinyin_name, name_nospace, CHINESE_PINYIN_SPELL_MAX_LEN*(CHINESE_PINYIN_MAX_LEN+1)); + + buf_size = SAFE_STRLEN(name) + + SAFE_STRLEN(pinyinname[i].pinyin_name) + + SAFE_STRLEN(name_nospace) + 4; + temp_name = calloc(1, buf_size); + 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; + } + + free(name_nospace); + free(pinyinname); + } + else { + char initial[CTSVC_CONTACT_INITIAL_DATA_MAX_LEN] = {0,}; + char *normalized_display_name = NULL; + + normalized_display_name = calloc(1, strlen(contact->display_name)* 5); + + ctsvc_normalize_str(contact->display_name, normalized_display_name, strlen(contact->display_name)* 5); + __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); + snprintf(name, buf_size, "%s %s", normalized_display_name, initial); + + free(normalized_display_name); + } + } + else if (CTSVC_LANG_KOREAN == ctsvc_check_language_type(contact->display_name)) { + char *temp_name = NULL; + char *chosung = calloc(1, strlen(contact->display_name) + 1); + int count, i, j; + int full_len, chosung_len; + int total_len = strlen(contact->display_name); + + count = ctsvc_get_chosung(contact->display_name, chosung, strlen(contact->display_name) + 1 ); + + name = calloc(1, strlen(contact->display_name)* 5); + + ctsvc_normalize_str(contact->display_name, name, strlen(contact->display_name)* 5); + + 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); + + snprintf(temp_name, buf_size, "%s %s %s", name, &contact->display_name[i], &chosung[j]); + + free(name); + name = temp_name; + } + } + free(chosung); + } + else { + char initial[CTSVC_CONTACT_INITIAL_DATA_MAX_LEN] = {0,}; + char *normalized_display_name=NULL; + + normalized_display_name = calloc(1, strlen(contact->display_name)* 5); + + ctsvc_normalize_str(contact->display_name, normalized_display_name, strlen(contact->display_name)* 5); + __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); + snprintf(name, buf_size, "%s %s", normalized_display_name, initial); + + free(normalized_display_name); + } + } + *search_name = name; + return CONTACTS_ERROR_NONE; +} + + +static inline int __ctsvc_contact_make_search_data(int contact_id, char **search_name, + char **search_number, char **search_data) +{ + int ret, len = 0; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_contact_s *contact; + + char *number = NULL; + char *data = NULL; + char *temp_number=NULL; + char *temp_data=NULL; + int buf_size=0; + + ret = contacts_db_get_record(_contacts_contact._uri, 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("contacts_db_get_record() Failed(%d)", ret); + return ret; + } + + __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); + len = 0; + do { + contacts_list_get_current_record_p(number_list, (contacts_record_h*)&number_record); + if (NULL != number_record) { + buf_size = SAFE_STRLEN(number) + SAFE_STRLEN(number_record->lookup) + 3; + temp_number = calloc(1, buf_size); + if (number) + snprintf(temp_number, buf_size, "%s %s ", SAFE_STR(number), number_record->lookup); + else + snprintf(temp_number, buf_size, "%s ", number_record->lookup); + free(number); + number = temp_number; + } + }while(CONTACTS_ERROR_NONE == contacts_list_next(number_list)); + } + + len = 0; + 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) { + buf_size = SAFE_STRLEN(data) + SAFE_STRLEN(email->email_addr) + 3; + temp_data = calloc(1, buf_size); + if (data) + snprintf(temp_data, buf_size, "%s %s ",data, email->email_addr); + else + snprintf(temp_data, buf_size, "%s ",email->email_addr); + 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) { + buf_size = SAFE_STRLEN(data) + SAFE_STRLEN(nickname->nickname) + 3; + temp_data = calloc(1, buf_size); + if (data) + snprintf(temp_data, buf_size, "%s %s ", data, nickname->nickname); + else + snprintf(temp_data+len, buf_size, "%s ", nickname->nickname); + 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) { + len =0; + buf_size = SAFE_STRLEN(data) + + 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) + 9; + temp_data = calloc(1, buf_size); + if(data) + len += snprintf(temp_data + len, buf_size - len, "%s ", data); + if (address->country) + len += snprintf(temp_data + len, buf_size - len, "%s ", address->country); + if (address->pobox) + len += snprintf(temp_data + len, buf_size - len, "%s ", address->pobox); + if (address->postalcode) + len += snprintf(temp_data + len, buf_size - len, "%s ", address->postalcode); + if (address->region) + len += snprintf(temp_data + len, buf_size - len, "%s ", address->region); + if (address->locality) + len += snprintf(temp_data + len, buf_size - len, "%s ", address->locality); + if (address->street) + len += snprintf(temp_data + len, buf_size - len, "%s ", address->street); + if (address->extended) + len += snprintf(temp_data + len, buf_size - len, "%s ", address->extended); + free(data); + data = temp_data; + } + }while(CONTACTS_ERROR_NONE == contacts_list_next(address_list)); + } + + contacts_record_destroy((contacts_record_h)contact, true); + + *search_number = number; + *search_data = data; + return CONTACTS_ERROR_NONE; +} + +static inline int __ctsvc_update_contact_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; + + ret = ctsvc_begin_trans(); + RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret); + + snprintf(query, sizeof(query), + "UPDATE %s SET name=?, number=?, data=? " + "WHERE contact_id = %d", + CTS_TABLE_SEARCH_INDEX, contact_id); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare() Failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + ret = __ctsvc_contact_make_search_data(contact_id, &search_name, &search_number, &search_data); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_make_contact_search_data() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + + if (search_name) + cts_stmt_bind_text(stmt, 1, search_name); + if(search_number) + cts_stmt_bind_text(stmt, 2, search_number); + if(search_data) + cts_stmt_bind_text(stmt, 3, search_data); + + ret = cts_stmt_step(stmt); + + free(search_name); + free(search_number); + free(search_data); + + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + cts_stmt_finalize(stmt); + + 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 i, ret, len; + int rel_changed = 0; + int count; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_contact_s *contact = (ctsvc_contact_s*)record; + cts_stmt stmt; + + snprintf(query, sizeof(query), + "SELECT count(contact_id) FROM "CTS_TABLE_CONTACTS" " + "WHERE contact_id = %d AND deleted = 0", contact->id); + ret = ctsvc_query_get_first_int_result(query, &count); + RETVM_IF(1 != count, CONTACTS_ERROR_NO_DATA, + "The index(%d) is Invalid. %d Record(s) is(are) found", contact->id, ret); + + ret = ctsvc_begin_trans(); + RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret); + + __ctsvc_update_contact_display_name(contact); + __ctsvc_contact_check_default_data(contact); + + //update data + ret = __ctsvc_update_contact_data(contact); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("__ctsvc_update_contact_data() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + + if (contact->grouprelations) { + rel_changed = __ctsvc_update_contact_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. + free(contact->image_thumbnail_path); + contact->image_thumbnail_path = NULL; + contact->image_thumbnail_changed = false; + + if (contact->images) { + int ret = CONTACTS_ERROR_NONE; + contacts_record_h record = NULL; + unsigned int count = 0; + ctsvc_list_s *list = (ctsvc_list_s*)contact->images; + ctsvc_image_s *image; + GList *cursor; + + for(cursor = list->deleted_records;cursor;cursor=cursor->next) { + image = (ctsvc_image_s *)cursor->data; + contact->image_thumbnail_path = NULL; + } + + 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); + + 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; + + if ( image->path && *image->path && strstr(image->path, CTS_IMG_FULL_LOCATION) != NULL) + contact->image_thumbnail_path = SAFE_STRDUP( image->path + strlen(CTS_IMG_FULL_LOCATION) + 1); + else + contact->image_thumbnail_path = SAFE_STRDUP(image->path); + + } + contact->image_thumbnail_changed = true; + } + // this code will be removed. + ////////////////////////////////////////////////////////////////////// + + len = snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_CONTACTS" SET changed_ver=%d, changed_time=%d, " + "has_phonenumber=%d, has_email=%d ", + ctsvc_get_next_ver(), (int)time(NULL), + contact->has_phonenumber, contact->has_email); + + if (contact->display_name_changed) + len += snprintf(query+len, sizeof(query)-len, ", display_name=?, " + "reverse_display_name=?, display_name_source=?, display_name_language=?, " + "sortkey=?, reverse_sortkey=?"); + + if (contact->uid_changed) + len += snprintf(query+len, sizeof(query)-len, ", uid=?"); + + if (contact->ringtone_changed) + len += snprintf(query+len, sizeof(query)-len, ", ringtone_path=?"); + + if (contact->vibration_changed) + len += snprintf(query+len, sizeof(query)-len, ", vibration=?"); + + if (contact->image_thumbnail_changed) + len += snprintf(query+len, sizeof(query)-len, ", image_thumbnail_path=?"); + + snprintf(query+len, sizeof(query)-len, " WHERE contact_id=%d", contact->id); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare() Failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + i=1; + if (contact->display_name_changed) { + cts_stmt_bind_text(stmt, i++, contact->display_name); + cts_stmt_bind_text(stmt, i++, contact->reverse_display_name); + cts_stmt_bind_int(stmt, i++, contact->display_source_type); + cts_stmt_bind_int(stmt, i++, contact->display_name_language); + cts_stmt_bind_text(stmt, i++, contact->sortkey); + cts_stmt_bind_text(stmt, i++, contact->reverse_sortkey); + } + if (contact->uid_changed) { + if(contact->uid) + cts_stmt_bind_text(stmt, i, contact->uid); + i++; + } + if (contact->ringtone_changed) { + if (contact->ringtone_path) + cts_stmt_bind_text(stmt, i, contact->ringtone_path); + i++; + } + if (contact->vibration_changed) { + if (contact->vibration) + cts_stmt_bind_text(stmt, i, contact->vibration); + i++; + } + + if (contact->image_thumbnail_changed ) { + if (contact->image_thumbnail_path) { + cts_stmt_bind_text(stmt, i, contact->image_thumbnail_path); + } + i++; + } + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + cts_stmt_finalize(stmt); + + ctsvc_set_contact_noti(); + if (0 < rel_changed) + ctsvc_set_group_rel_noti(); + + __ctsvc_update_contact_search_data(contact->id); + ctsvc_db_update_person((contacts_record_h)contact); + + 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_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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return ret; + } + contact_id = ctsvc_stmt_get_int(stmt, 0); + ret = contacts_db_get_record(_contacts_contact._uri, contact_id, &record); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : contacts_db_get_record() Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return CONTACTS_ERROR_NO_DATA; + } + ctsvc_list_prepend(list, record); + } + cts_stmt_finalize(stmt); + ctsvc_list_reverse(list); + + *out_list = (contacts_list_h)list; + return CONTACTS_ERROR_NONE; +} + +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) { + s_query->projection = realloc(s_query->projection, s_query->projection_count+1); + 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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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; + + 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", CTS_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_CHANGED_TIME: + contact->changed_time = ctsvc_stmt_get_int(stmt, i); + break; + default: + break; + } + } + ret = __ctsvc_db_get_data(contact_id, contact); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("ctsvc_get_data_info Failed(%d)", ret); + cts_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); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return ret; + } + + ctsvc_list_prepend(list, record); + } + cts_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; + + DBG("B ctsvc_contact_insert_data_name"); + //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; + } + } + DBG("A ctsvc_contact_insert_data_name"); + + //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; + + ret = ctsvc_begin_trans(); + RETVM_IF(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret); + + snprintf(query, sizeof(query), "DELETE FROM %s WHERE contact_id = %d", + CTS_TABLE_SEARCH_INDEX, 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), + "INSERT INTO %s(contact_id, name, number, data) " + "VALUES(%d, ?, ?, ?)", + CTS_TABLE_SEARCH_INDEX, contact_id); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare() Failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + ret = __ctsvc_contact_make_search_data(contact_id, &search_name, &search_number, &search_data); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("__ctsvc_contact_make_search_data() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + + if(search_name) + cts_stmt_bind_text(stmt, 1, search_name); + if(search_number) + cts_stmt_bind_text(stmt, 2, search_number); + if(search_data) + cts_stmt_bind_text(stmt, 3, search_data); + + ret = cts_stmt_step(stmt); + + free(search_name); + free(search_number); + free(search_data); + + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + cts_stmt_finalize(stmt); + + 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; + unsigned 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 || grouprel->base.deleted) + continue; + + if (grouprel->group_id) { + int 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 *normalized_number, int *person_id) +{ + int ret; + + char query[CTS_SQL_MIN_LEN] = {0}; + char normal_num[CTSVC_NUMBER_MAX_LEN] = {0}; + char clean_num[CTSVC_NUMBER_MAX_LEN] = {0}; + + ret = ctsvc_clean_number(normalized_number, clean_num, sizeof(clean_num)); + if (0 < ret) { + ret = ctsvc_normalize_number(clean_num, normal_num, CTSVC_NUMBER_MAX_LEN); + 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 " + "WHERE D.data4='%s' AND D.is_my_profile = 0", + CTSVC_DATA_NUMBER, normal_num); + ret = ctsvc_query_get_first_int_result(query, person_id); + CTS_DBG("%s", query); + 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 *person_id) +{ + int ret; + 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 " + "WHERE D.data3='%s' AND D.is_my_profile = 0", + CTSVC_DATA_EMAIL, email_addr); + ret = ctsvc_query_get_first_int_result(query, person_id); + CTS_DBG("%s", query); + 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 *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, 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, 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; + + ctsvc_contact_s *contact = (ctsvc_contact_s*)record; + int rel_changed = 0; + cts_stmt stmt; + + // These check should be done in client side +// RETVM_IF(contact->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted contact record"); + 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); + + ret = ctsvc_begin_trans(); + RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_begin_trans() Failed(%d)", ret); + + ret = cts_db_get_next_id(CTS_TABLE_CONTACTS); + if (ret < CONTACTS_ERROR_NONE) { + CTS_ERR("cts_db_get_next_id() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + contact->id = ret; + if (id) + *id = ret; + + DBG("B ctsvc_make_contact_display_name"); + ctsvc_make_contact_display_name(contact); + DBG("A ctsvc_make_contact_display_name"); + __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; + unsigned 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 (auto_link_enabled) { + ret = __ctsvc_find_person_to_link((contacts_record_h)contact, &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; + } + else { + ret = ctsvc_db_insert_person((contacts_record_h)contact); + CTS_DBG("ctsvc_db_insert_person return %d, person_id(%d)", ret, person_id); + 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, person_id); + 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_restricted, " + "created_ver, changed_ver, changed_time, has_phonenumber, has_email, " + "display_name, reverse_display_name, display_name_source, display_name_language, " + "sortkey, reverse_sortkey, " + "uid, ringtone_path, vibration, image_thumbnail_path) " + "VALUES(%d, %d, %d, %d, %d, %d, %d, %d, %d, ?, ?, %d, %d, ?, ?, ?, ?, ?, ?)", + contact->id, contact->person_id, contact->addressbook_id, contact->is_restricted, + version, version, (int)time(NULL), contact->has_phonenumber, contact->has_email, + contact->display_source_type, contact->display_name_language); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare() Failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + if (contact->display_name) + cts_stmt_bind_text(stmt, 1, contact->display_name); + if (contact->reverse_display_name) + cts_stmt_bind_text(stmt, 2, contact->reverse_display_name); + if (contact->sortkey) + cts_stmt_bind_text(stmt, 3, contact->sortkey); + if (contact->reverse_sortkey) + cts_stmt_bind_text(stmt, 4, contact->reverse_sortkey); + if (contact->uid) + cts_stmt_bind_text(stmt, 5, contact->uid); + if (contact->ringtone_path) + cts_stmt_bind_text(stmt, 6, contact->ringtone_path); + if (contact->vibration) + cts_stmt_bind_text(stmt, 7, contact->vibration); + if (contact->image_thumbnail_path) + cts_stmt_bind_text(stmt, 8, contact->image_thumbnail_path); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + cts_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; + } + } + + DBG("B __ctsvc_contact_insert_search_data"); + __ctsvc_contact_insert_search_data(contact->id); + DBG("A __ctsvc_contact_insert_search_data"); + + 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 count; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_contact_s *contact = (ctsvc_contact_s*)record; + cts_stmt stmt; + + snprintf(query, sizeof(query), + "SELECT count(contact_id) FROM "CTS_TABLE_CONTACTS" " + "WHERE contact_id = %d AND deleted = 0", contact_id); + ret = ctsvc_query_get_first_int_result(query, &count); + RETVM_IF(1 != count, CONTACTS_ERROR_NO_DATA, + "The index(%d) is Invalid. %d Record(s) is(are) not found", contact->id, ret); + + ret = ctsvc_begin_trans(); + RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret); + + contact->id = contact_id; + __ctsvc_update_contact_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. + free(contact->image_thumbnail_path); + contact->image_thumbnail_path = NULL; + contact->image_thumbnail_changed = false; + + if (contact->images) { + int ret = CONTACTS_ERROR_NONE; + contacts_record_h record = NULL; + unsigned int count = 0; + ctsvc_list_s *list = (ctsvc_list_s*)contact->images; + ctsvc_image_s *image; + GList *cursor; + + for(cursor = list->deleted_records;cursor;cursor=cursor->next) { + image = (ctsvc_image_s *)cursor->data; + contact->image_thumbnail_path = NULL; + } + + 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); + + 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; + + if ( image->path && *image->path && strstr(image->path, CTS_IMG_FULL_LOCATION) != NULL) + contact->image_thumbnail_path = SAFE_STRDUP( image->path + strlen(CTS_IMG_FULL_LOCATION) + 1); + else + contact->image_thumbnail_path = SAFE_STRDUP(image->path); + + } + contact->image_thumbnail_changed = true; + } + // this code will be removed. + ////////////////////////////////////////////////////////////////////// + + 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, " + "sortkey=?, reverse_sortkey=?, uid=?, ringtone_path=?, vibration=?, " + "image_thumbnail_path=? WHERE contact_id=%d", + ctsvc_get_next_ver(), (int)time(NULL), + contact->has_phonenumber, contact->has_email, + contact->display_source_type, contact->display_name_language, + contact->id); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare() Failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + if (contact->display_name) + cts_stmt_bind_text(stmt, 1, contact->display_name); + if (contact->reverse_display_name) + cts_stmt_bind_text(stmt, 2, contact->reverse_display_name); + if (contact->sortkey) + cts_stmt_bind_text(stmt, 3, contact->sortkey); + if (contact->reverse_sortkey) + cts_stmt_bind_text(stmt, 4, contact->reverse_sortkey); + if (contact->uid) + cts_stmt_bind_text(stmt, 5, contact->uid); + if (contact->ringtone_path) + cts_stmt_bind_text(stmt, 6, contact->ringtone_path); + if (contact->vibration) + cts_stmt_bind_text(stmt, 7, contact->vibration); + if (contact->image_thumbnail_path) + cts_stmt_bind_text(stmt, 8, contact->image_thumbnail_path); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + cts_stmt_finalize(stmt); + + ctsvc_set_contact_noti(); + if (0 < rel_changed) + ctsvc_set_group_rel_noti(); + + __ctsvc_update_contact_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 index 0000000..05684a2 --- /dev/null +++ b/native/ctsvc_db_plugin_contact_helper.c @@ -0,0 +1,1659 @@ +/* + * 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_utils.h" +#include "ctsvc_record.h" +#include "ctsvc_normalize.h" +#include "ctsvc_setting.h" +#include "ctsvc_localize.h" +#include "ctsvc_localize_ch.h" +#include "ctsvc_notification.h" +#include "ctsvc_localize.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_db_plugin_grouprelation_helper.h" + +#include "ctsvc_group.h" + +#define CTSVC_MY_IMAGE_LOCATION "/opt/usr/data/contacts-svc/img/my" + +int ctsvc_contact_add_image_file(ctsvc_img_e image_type, int index, char *src_img, + char *dest_name, int dest_size) +{ + int ret; + char *ext; + char dest[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0}; + + RETVM_IF(NULL == src_img, CONTACTS_ERROR_INVALID_PARAMETER, "image_thumbnail_path is NULL"); + + ext = strrchr(src_img, '.'); + if (NULL == ext || strchr(ext, '/')) + ext = ""; + + snprintf(dest, sizeof(dest), "%s/%d-%d%s", + CTS_IMG_FULL_LOCATION, index, image_type, ext); + + ret = ctsvc_copy_image(src_img, dest); + RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "cts_copy_file() Failed(%d)", ret); + + snprintf(dest_name, dest_size, "%d-%d%s", index, image_type, ext); + return CONTACTS_ERROR_NONE; +} + +static inline const char* __ctsvc_get_image_column_name(ctsvc_img_e image_type) +{ + switch(image_type) + { + case CTSVC_IMG_NORMAL: + return "image_thumbnail_path"; + default: + CTS_ERR("Invalid parameter : The image_type(%d) is not supported", image_type); + return NULL; + } +} + +int ctsvc_contact_delete_image_file(ctsvc_img_e image_type, int index) +{ + int ret; + cts_stmt stmt; + char *tmp_path; + char query[CTS_SQL_MIN_LEN] = {0}; + snprintf(query, sizeof(query), + "SELECT %s FROM %s WHERE contact_id = %d", + __ctsvc_get_image_column_name(image_type), CTS_TABLE_CONTACTS, index); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("DB error: cts_query_prepare() Failed"); + return CONTACTS_ERROR_DB; + } + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("DB error: cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + tmp_path = ctsvc_stmt_get_text(stmt, 0); + if (tmp_path) { + char full_path[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0}; + snprintf(full_path, sizeof(full_path), "%s/%s", CTS_IMG_FULL_LOCATION, tmp_path); + ret = unlink(full_path); + WARN_IF (ret < 0, "unlink(%s) Failed(%d)", full_path, errno); + } + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NONE; +} + +int ctsvc_contact_update_image_file(int image_type, int index, char *src_img, + char *dest_name, int dest_size) +{ + int ret; + if (src_img && strstr(src_img, CTS_IMG_FULL_LOCATION) != NULL) { + snprintf(dest_name, dest_size, "%s", src_img + strlen(CTS_IMG_FULL_LOCATION) + 1); + return CONTACTS_ERROR_NONE; + } + + ret = ctsvc_contact_delete_image_file(image_type, index); + WARN_IF(CONTACTS_ERROR_NONE != ret && CONTACTS_ERROR_NO_DATA != ret, + "ctsvc_contact_delete_image_file() Failed(%d)", ret); + + if (src_img) { + ret = ctsvc_contact_add_image_file(image_type, index, 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, "cts_query_exec() Failed(%d)", ret); + + ctsvc_set_contact_noti(); + + return CONTACTS_ERROR_NONE; +} + +static 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", CTS_IMG_FULL_LOCATION, image_path); + ret = unlink(full_path); + WARN_IF(ret < 0, "unlink(%s) Failed(%d)", full_path, errno); + } + + return CONTACTS_ERROR_NONE; +} + +void ctsvc_db_contact_delete_callback(sqlite3_context * context, + int argc, sqlite3_value ** argv) +{ + int ret; + int contact_id; + const unsigned char* image_thumbnail_path; + const unsigned char* image_path; + + if (argc > 3) { + sqlite3_result_null(context); + return; + } + + contact_id = sqlite3_value_int(argv[0]); + CTS_DBG("contact_id (%d), %c", sqlite3_value_int(argv[0]), contact_id); + image_thumbnail_path = sqlite3_value_text(argv[1]); + image_path = sqlite3_value_text(argv[2]); + + ret = __ctsvc_contact_delete_image_file_with_path(image_thumbnail_path); + WARN_IF (CONTACTS_ERROR_NONE != ret && CONTACTS_ERROR_NO_DATA != ret, + "__ctsvc_contact_delete_image_file_with_path(NORMAL) Failed(%d)", ret); + + 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(FULL) Failed(%d)", ret); + + ret = ctsvc_company_delete_logo_file(contact_id); + if (CONTACTS_ERROR_NONE != ret && CONTACTS_ERROR_NO_DATA != ret) { + CTS_ERR("ctsvc_company_delete_logo_file_with_contact_id() Failed(%d)", ret); + return; + } + + return; +} + +void ctsvc_make_contact_display_name(ctsvc_contact_s *contact) +{ + char *display = NULL; + char *sortkey = NULL; + GList *cur; + int ret, len, display_len; + + ctsvc_name_s *name = NULL; + + contact->display_name_language = CTSVC_LANG_OTHERS; + + 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) ) { + + // make display name + display_len = SAFE_STRLEN(name->first) + + SAFE_STRLEN(name->addition) + + SAFE_STRLEN(name->last) + + SAFE_STRLEN(name->suffix) + 5; + display = calloc(1, display_len); + len=0; + + if(name->first) + len += snprintf(display + len, display_len - len, "%s", name->first); + + if(name->addition) { + if (*display) + len += snprintf(display + len, display_len - len, " "); + len += snprintf(display + len, display_len - len, "%s", name->addition); + } + + if(name->last) { + if (*display) + len += snprintf(display + len, display_len - len, " "); + len += snprintf(display + len, display_len - len, "%s", name->last); + } + + if(name->suffix) { + if (*display) + len += snprintf(display + len, display_len - len, " "); + len += snprintf(display + len, display_len - len, "%s", name->suffix); + } + + contact->display_name = display; + + // make reverse_display_name + display = calloc(1, display_len); + len = 0; + if(name->last) { + len += snprintf(display + len, display_len - len, "%s", name->last); + + if(name->first || name->addition) + len += snprintf(display + len, display_len - len, ","); + } + + if(name->first) { + if (*display) + len += snprintf(display + len, display_len - len, " "); + len += snprintf(display + len, display_len - len, "%s", name->first); + } + + if(name->addition) { + if (*display) + len += snprintf(display + len, display_len - len, " "); + len += snprintf(display + len, display_len - len, "%s", name->addition); + } + + if(name->suffix) { + if (*display) + len += snprintf(display + len, display_len - len, " "); + len += snprintf(display + len, display_len - len, "%s", name->suffix); + } + + contact->reverse_display_name = display; + + ret = ctsvc_check_language_type(contact->display_name); + if (0 <= ret) { + if (ctsvc_get_default_language() == ret) + contact->display_name_language = CTSVC_LANG_DEFAULT; + else if (ctsvc_get_secondary_language() == ret) + contact->display_name_language = CTSVC_LANG_SECONDARY; + else + contact->display_name_language = ret; + } + + if (ctsvc_has_chinese(contact->display_name)) { + pinyin_name_s *pinyinname = NULL; + int size; + + ret = ctsvc_convert_chinese_to_pinyin(contact->display_name, &pinyinname, &size); + + if (CONTACTS_ERROR_NONE == ret) { + ret = ctsvc_collation_str(pinyinname[0].pinyin_name, &sortkey); + if (CONTACTS_ERROR_NONE == ret) { + contact->sortkey = sortkey; + contact->reverse_sortkey = strdup(sortkey); + } + free(pinyinname); + } + else { + ret = ctsvc_collation_str(contact->display_name, &sortkey); + if (CONTACTS_ERROR_NONE == ret) + contact->sortkey = sortkey; + else + free(sortkey); + sortkey = NULL; + + ret = ctsvc_collation_str(contact->reverse_display_name, &sortkey); + if (CONTACTS_ERROR_NONE == ret) + contact->reverse_sortkey = sortkey; + else + free(sortkey); + } + + } + else { + ret = ctsvc_collation_str(contact->display_name, &sortkey); + if (CONTACTS_ERROR_NONE == ret) + contact->sortkey = sortkey; + else + free(sortkey); + sortkey = NULL; + + ret = ctsvc_collation_str(contact->reverse_display_name, &sortkey); + if (CONTACTS_ERROR_NONE == ret) + contact->reverse_sortkey = sortkey; + else + free(sortkey); + + } + contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NAME; + } + else { + 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) { + contact->display_name = SAFE_STRDUP(company->name); + contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_COMPANY; + break; + } + } + } + + if (NULL == contact->display_name && 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) { + contact->display_name = SAFE_STRDUP(nickname->nickname); + contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NICKNAME; + break; + } + } + } + + if (NULL == contact->display_name && 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) { + contact->display_name = SAFE_STRDUP(number->number); + contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_NUMBER; + break; + } + } + } + + if (NULL == contact->display_name && 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) { + contact->display_name = SAFE_STRDUP(email->email_addr); + contact->display_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_EMAIL; + break; + } + } + } + + if (contact->display_name) { + contact->reverse_display_name = SAFE_STRDUP(contact->display_name); + if (ctsvc_has_chinese(contact->display_name)) { + pinyin_name_s *pinyinname; + int size; + ret = ctsvc_convert_chinese_to_pinyin(contact->display_name, &pinyinname, &size); + + if (CONTACTS_ERROR_NONE == ret) { + ret = ctsvc_collation_str(pinyinname[0].pinyin_name, &sortkey); + if (CONTACTS_ERROR_NONE == ret) { + contact->sortkey = sortkey; + contact->reverse_sortkey = strdup(sortkey); + } + else + free(sortkey); + free(pinyinname); + } + else { + ret = ctsvc_collation_str(contact->display_name, &sortkey); + if (CONTACTS_ERROR_NONE == ret) + contact->sortkey = sortkey; + else + free(sortkey); + sortkey = NULL; + + ret = ctsvc_collation_str(contact->reverse_display_name, &sortkey); + if (CONTACTS_ERROR_NONE == ret) + contact->reverse_sortkey = sortkey; + else + free(sortkey); + } + } + else { + ret = ctsvc_check_language_type(contact->display_name); + if (0 <= ret) { + if (ctsvc_get_default_language() == ret) + contact->display_name_language = CTSVC_LANG_DEFAULT; + else if (ctsvc_get_secondary_language() == ret) + contact->display_name_language = CTSVC_LANG_SECONDARY; + else + contact->display_name_language = ret; + } + + ret = ctsvc_collation_str(contact->display_name, &sortkey); + if (CONTACTS_ERROR_NONE == ret) { + contact->sortkey = sortkey; + contact->reverse_sortkey = strdup(sortkey); + } + else + free(sortkey); + } + } + } + + return; +} + +int ctsvc_get_data_info_name(cts_stmt stmt, contacts_list_h name_list) +{ + int ret; + unsigned 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; + unsigned 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 && !number->base.deleted) { + 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->base.deleted) { + number->is_default = true; + 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; + unsigned 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 && !email->base.deleted) { + 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->base.deleted) { + email->is_default = true; + 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; + unsigned 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; + has_default = true; + break; + } + }while(CONTACTS_ERROR_NONE == contacts_list_next(image_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); + } + + 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, contact_id, is_my_profile); + else + ret = ctsvc_db_name_delete(name->id); + } + 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; + unsigned 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); + } + + 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); + } + 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; + unsigned 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); + } + + 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, contact_id, is_my_profile); + else + ret = ctsvc_db_note_delete(note->id); + } + 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; + unsigned 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); + } + + 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, contact_id, is_my_profile); + else + ret = ctsvc_db_event_delete(event->id); + } + 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; + unsigned 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); + } + + 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, contact_id, is_my_profile); + else + ret = ctsvc_db_messenger_delete(messenger->id); + } + 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; + unsigned 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); + } + + 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, contact_id, is_my_profile); + else + ret = ctsvc_db_address_delete(address->id); + } + 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; + unsigned 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); + } + + 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, contact_id, is_my_profile); + else + ret = ctsvc_db_url_delete(url->id); + } + 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; + unsigned 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); + } + 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->appsvc_operation) + ret = ctsvc_db_profile_update(record, contact_id, is_my_profile); + else + ret = ctsvc_db_profile_delete(profile->id); + } + 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; + unsigned 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); + } + + 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, contact_id, is_my_profile); + else + ret = ctsvc_db_relationship_delete(relationship->id); + } + 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; + unsigned 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); + } + + 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 (image->is_changed) { + 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); + } + 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; + unsigned 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); + } + + 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, contact_id, is_my_profile); + else + ret = ctsvc_db_nickname_delete(nickname->id); + } + 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; + unsigned 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); + } + + 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, contact_id, is_my_profile); + else + ret = ctsvc_db_extension_delete(extension->id); + } + 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; + unsigned 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); + } + + 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 (number->number) { + if (0 < number->id) { + if (number->number) + ret = ctsvc_db_number_update(record, contact_id, is_my_profile); + else + ret = ctsvc_db_number_delete(number->id); + } + else + ret = ctsvc_db_number_insert(record, contact_id, is_my_profile, NULL); + if (CONTACTS_ERROR_DB == ret){ + CTS_ERR("DB error : return (%d)", ret); + break; + } + had = true; + } + }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; + unsigned 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); + } + + 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 (email->email_addr) { + if (0 < email->id) { + if (email->email_addr) + ret = ctsvc_db_email_update(record, contact_id, is_my_profile); + else + ret = ctsvc_db_email_delete(email->id); + } + else + ret = ctsvc_db_email_insert(record, contact_id, is_my_profile, NULL); + if (CONTACTS_ERROR_DB == ret){ + CTS_ERR("DB error : return (%d)", ret); + break; + } + had = true; + } + }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; + unsigned 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; + unsigned 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; + unsigned 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; + unsigned 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; + unsigned 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; + unsigned 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; + unsigned 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; + unsigned 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; + unsigned 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; + unsigned 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; + unsigned 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; + unsigned 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; + unsigned 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; +} + diff --git a/native/ctsvc_db_plugin_contact_helper.h b/native/ctsvc_db_plugin_contact_helper.h new file mode 100644 index 0000000..049ed8d --- /dev/null +++ b/native/ctsvc_db_plugin_contact_helper.h @@ -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. + * + */ + +#ifndef __CTSVC_DB_PLUGIN_CONTACT_HELPER_H__ +#define __CTSVC_DB_PLUGIN_CONTACT_HELPER_H__ + +#include "ctsvc_struct.h" +#include "ctsvc_sqlite.h" + +typedef enum +{ + CTSVC_IMG_NORMAL, /**< . */ +} ctsvc_img_e; + +int ctsvc_db_contact_update_changed_time(int contact_id); + +int ctsvc_contact_add_image_file(ctsvc_img_e image_type, int index, char *src_img, + char *dest_name, int dest_size); +int ctsvc_contact_update_image_file(int image_type, int index, char *src_img, + char *dest_name, int dest_size); +int ctsvc_contact_delete_image_file(ctsvc_img_e image_type, int index); +void ctsvc_make_contact_display_name(ctsvc_contact_s *contact); + +void ctsvc_db_contact_delete_callback(sqlite3_context * context, + int argc, sqlite3_value ** argv); + +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_image(contacts_list_h image_list); + +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 index 0000000..1714c85 --- /dev/null +++ b/native/ctsvc_db_plugin_email.c @@ -0,0 +1,370 @@ +/* + * 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_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_insert_record( contacts_record_h record, int *id ) +{ + int ret; + int contact_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, + "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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", email->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + 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("cts_query_exec() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + ctsvc_set_contact_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; + int len; + cts_stmt stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER); + *out_record = NULL; + + 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 id = %d AND datatype = %d ", + id, CTSVC_DATA_EMAIL); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ctsvc_db_email_get_value_from_stmt(stmt, out_record, 0); + + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_email_update_record( contacts_record_h record ) +{ + int ret; + int contact_id; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_email_s *email = (ctsvc_email_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", email->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + ret = ctsvc_db_email_update(record, email->contact_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 display email update + ret = ctsvc_db_contact_update_changed_time(email->contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + + ctsvc_set_contact_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 contact_id; + 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 FROM "CTSVC_DB_VIEW_CONTACT " " + "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if( ret != CONTACTS_ERROR_NONE ) { + CTS_ERR("The id(%d) is Invalid(%d)", id, ret); + ctsvc_end_trans(false); + return contact_id; + } + + ret = ctsvc_db_email_delete(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(contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + + ctsvc_set_contact_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_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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB : cts_stmt_step fail(%d)", ret); + cts_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); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + } + cts_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 index 0000000..416093d --- /dev/null +++ b/native/ctsvc_db_plugin_email_helper.c @@ -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 "contacts.h" +#include "ctsvc_internal.h" +#include "ctsvc_schema.h" +#include "ctsvc_sqlite.h" +#include "ctsvc_db_init.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; +} + +int ctsvc_db_email_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_email_s *email = (ctsvc_email_s *)record; + +// RETVM_IF(email->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted email 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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + if (email->label) + cts_stmt_bind_text(stmt, 1, email->label); + if (email->email_addr) + cts_stmt_bind_text(stmt, 2, email->email_addr); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + //email->id = cts_db_get_last_insert_id(); + if (id) + *id = cts_db_get_last_insert_id(); + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_email_noti(); + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_email_update(contacts_record_h record, int contact_id, bool is_my_profile) +{ + int ret; + ctsvc_email_s *email = (ctsvc_email_s*)record; + char query[CTS_SQL_MAX_LEN] = {0}; + cts_stmt stmt; + + RETVM_IF(!email->id, CONTACTS_ERROR_INVALID_PARAMETER, "email of contact has no ID."); + + snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_DATA" SET contact_id=%d, is_my_profile=%d, data1=%d, data2=?, data3=? WHERE id=%d", + contact_id, is_my_profile, email->type, email->id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + if (email->label) + cts_stmt_bind_text(stmt, 1, email->label); + if (email->email_addr) + cts_stmt_bind_text(stmt, 2, email->email_addr); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_email_noti(); + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_email_delete(int id) +{ + 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); + 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 index 0000000..aec0a87 --- /dev/null +++ b/native/ctsvc_db_plugin_email_helper.h @@ -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, int contact_id, bool is_my_profile); +int ctsvc_db_email_delete(int id); + +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 index 0000000..216236f --- /dev/null +++ b/native/ctsvc_db_plugin_event.c @@ -0,0 +1,363 @@ +/* + * 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_event_helper.h" +#include "ctsvc_db_plugin_contact_helper.h" +#include "ctsvc_record.h" +#include "ctsvc_db_query.h" +#include "ctsvc_list.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 contact_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", event->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + 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_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; +} + +static int __ctsvc_db_event_get_record( int id, contacts_record_h* out_record ) +{ + int ret; + int len; + cts_stmt stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER); + *out_record = NULL; + + 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 id = %d AND datatype = %d ", + id, CTSVC_DATA_EVENT); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ctsvc_db_event_get_value_from_stmt(stmt, out_record, 0); + + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_event_update_record( contacts_record_h record ) +{ + int ret; + int contact_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", event->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + ret = ctsvc_db_event_update(record, event->contact_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 display event update + ret = ctsvc_db_contact_update_changed_time(event->contact_id); + 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; +} + +static int __ctsvc_db_event_delete_record( int id ) +{ + int ret; + int contact_id; + 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 FROM "CTSVC_DB_VIEW_CONTACT " " + "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("The id(%d) is Invalid(%d)", id, ret); + ctsvc_end_trans(false); + return contact_id; + } + + ret = ctsvc_db_event_delete(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(contact_id); + 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; +} + +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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB : cts_stmt_step fail(%d)", ret); + cts_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); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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_IS_LUNAR: + event->is_lunar = ctsvc_stmt_get_int(stmt, i); + break; + case CTSVC_PROPERTY_EVENT_LUNAR_DATE: + event->lunar_date = ctsvc_stmt_get_int(stmt, i); + break; + default: + break; + } + } + ctsvc_list_prepend(list, record); + } + cts_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 index 0000000..22ef48c --- /dev/null +++ b/native/ctsvc_db_plugin_event_helper.c @@ -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_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 +// RETVM_IF(event->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted event record"); + 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_lunar); + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + if (event->label) + cts_stmt_bind_text(stmt, 1, event->label); + cts_stmt_bind_int(stmt, 2, event->date); + cts_stmt_bind_int(stmt, 3, event->lunar_date); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + +// event->id = cts_db_get_last_insert_id(); + if (id) + *id = cts_db_get_last_insert_id(); + + cts_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->is_lunar = ctsvc_stmt_get_int(stmt, start_count++); + event->lunar_date = 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, int contact_id, bool is_my_profile) +{ + int ret; + ctsvc_event_s *event = (ctsvc_event_s*)record; + char query[CTS_SQL_MAX_LEN] = {0}; + cts_stmt stmt; + + RETVM_IF(!event->id, CONTACTS_ERROR_INVALID_PARAMETER, "event of contact has no ID."); + + snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_DATA" SET contact_id=%d, is_my_profile=%d, data1=%d, data2=?, data3=?, data4=%d, data5=? WHERE id=%d", + contact_id, is_my_profile, event->type, event->is_lunar, event->id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + if (event->label) + cts_stmt_bind_text(stmt, 1, event->label); + cts_stmt_bind_int(stmt, 2, event->date); + cts_stmt_bind_int(stmt, 3, event->lunar_date); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_event_noti(); + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_event_delete(int id) +{ + 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); + + 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 index 0000000..e9b8a72 --- /dev/null +++ b/native/ctsvc_db_plugin_event_helper.h @@ -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, int contact_id, bool is_my_profile); +int ctsvc_db_event_delete(int id); + +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 index 0000000..83528c4 --- /dev/null +++ b/native/ctsvc_db_plugin_extension.c @@ -0,0 +1,398 @@ +/* + * 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_extension_helper.h" +#include "ctsvc_record.h" +#include "ctsvc_db_query.h" +#include "ctsvc_list.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 contact_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 paramter"); + + 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 FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", extension->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + 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_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; +} + +static int __ctsvc_db_extension_get_record( int id, contacts_record_h* out_record ) +{ + int ret; + int len; + cts_stmt stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER); + *out_record = NULL; + + 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 id = %d AND datatype = %d ", + id, CTSVC_DATA_EXTENSION); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ctsvc_db_extension_get_value_from_stmt(stmt, out_record, 0); + + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_extension_update_record( contacts_record_h record ) +{ + int ret; + int contact_id; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_extension_s *extension = (ctsvc_extension_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", extension->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + ret = ctsvc_db_extension_update(record, extension->contact_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(extension->contact_id); + 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; +} + +static int __ctsvc_db_extension_delete_record( int id ) +{ + int ret; + int contact_id; + 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 FROM "CTSVC_DB_VIEW_CONTACT " " + "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if( ret != CONTACTS_ERROR_NONE ) { + CTS_ERR("The id(%d) is Invalid(%d)", id, ret); + ctsvc_end_trans(false); + return contact_id; + } + + ret = ctsvc_db_extension_delete(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(contact_id); + 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; +} + +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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB : cts_stmt_step fail(%d)", ret); + cts_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); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + } + cts_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 index 0000000..8815708 --- /dev/null +++ b/native/ctsvc_db_plugin_extension_helper.c @@ -0,0 +1,191 @@ +/* + * 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_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) + cts_stmt_bind_text(stmt, start_cnt, extension->data2); + if (extension->data3) + cts_stmt_bind_text(stmt, start_cnt+1, extension->data3); + if (extension->data4) + cts_stmt_bind_text(stmt, start_cnt+2, extension->data4); + if (extension->data5) + cts_stmt_bind_text(stmt, start_cnt+3, extension->data5); + if (extension->data6) + cts_stmt_bind_text(stmt, start_cnt+4, extension->data6); + if (extension->data7) + cts_stmt_bind_text(stmt, start_cnt+5, extension->data7); + if (extension->data8) + cts_stmt_bind_text(stmt, start_cnt+6, extension->data8); + if (extension->data9) + cts_stmt_bind_text(stmt, start_cnt+7, extension->data9); + if (extension->data10) + cts_stmt_bind_text(stmt, start_cnt+8, extension->data10); + if (extension->data11) + cts_stmt_bind_text(stmt, start_cnt+9, extension->data11); + if (extension->data12) + cts_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(extension->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted extension 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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + __ctsvc_extension_bind_stmt(stmt, extension, 1); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + +// extension->id = cts_db_get_last_insert_id(); + if (id) + *id = cts_db_get_last_insert_id(); + cts_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 contact_id, bool is_my_profile) +{ + int ret; + ctsvc_extension_s *extension = (ctsvc_extension_s*)record; + char query[CTS_SQL_MAX_LEN] = {0}; + cts_stmt stmt; + + RETVM_IF(!extension->id, CONTACTS_ERROR_INVALID_PARAMETER, "extension of contact has no ID."); + + snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_DATA" SET contact_id=%d, is_my_profile=%d, data1=%d, data2=?, data3=?, data4=?, " + "data5=?, data6=?, data7=?, data8=?, data9=?, data10=?, data11=?, data12=? WHERE id=%d", + contact_id, is_my_profile, extension->data1, extension->id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + __ctsvc_extension_bind_stmt(stmt, extension, 1); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_data_noti(); + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_extension_delete(int id) +{ + 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); + 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 index 0000000..e039f6a --- /dev/null +++ b/native/ctsvc_db_plugin_extension_helper.h @@ -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 contact_id, bool is_my_profile); +int ctsvc_db_extension_delete(int id); + +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__
\ No newline at end of file diff --git a/native/ctsvc_db_plugin_group.c b/native/ctsvc_db_plugin_group.c new file mode 100644 index 0000000..761cfd4 --- /dev/null +++ b/native/ctsvc_db_plugin_group.c @@ -0,0 +1,507 @@ +/* + * 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_query.h" +#include "ctsvc_db_init.h" +#include "ctsvc_record.h" +#include "ctsvc_notification.h" + +#define CTS_GROUP_IMAGE_LOCATION "/opt/usr/data/contacts-svc/img/group" + +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 int __ctsvc_db_group_insert_record( contacts_record_h record, int *id ) +{ + int ret; + int ver; + cts_stmt stmt; + ctsvc_group_s *group = (ctsvc_group_s *)record; + char query[CTS_SQL_MAX_LEN] = {0}; + char image[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {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(); + if( ret < CONTACTS_ERROR_NONE ) { + CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + + group->id = cts_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, image_thumbnail_path, system_id, is_read_only) " + "VALUES(%d, %d, ?, ?, ?, ?, ?, ?, ?, %d)", + group->id, group->addressbook_id, group->is_read_only); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("DB error : cts_query_prepare() Failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + cts_stmt_bind_text(stmt, 1, group->name); + + ver = ctsvc_get_next_ver(); + + cts_stmt_bind_int(stmt, 2, ver); + cts_stmt_bind_int(stmt, 3, ver); + + if (group->ringtone_path) + cts_stmt_bind_text(stmt, 4, group->ringtone_path); + if (group->vibration) + cts_stmt_bind_text(stmt, 5, group->vibration); + + if(group->image_thumbnail_path) { + ret = ctsvc_change_image(CTS_GROUP_IMAGE_LOCATION, group->id, group->image_thumbnail_path, + image, sizeof(image)); + if(CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_change_image() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + free(group->image_thumbnail_path); + group->image_thumbnail_path = strdup(image); + cts_stmt_bind_text(stmt, 6, group->image_thumbnail_path); + } + + if (group->system_id) + cts_stmt_bind_text(stmt, 7, group->system_id); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + + ctsvc_set_group_noti(); + + cts_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 ret; + ctsvc_group_s *group = (ctsvc_group_s *)record; + char image[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0}; + char query[CTS_SQL_MIN_LEN] = {0}; + cts_stmt stmt; + int len; + + 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(NULL == group->name, CONTACTS_ERROR_INVALID_PARAMETER, + "Invalid parameter : The name of group is empty."); + + len = snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_GROUPS" SET group_name=?, changed_ver=?, ringtone_path=?, vibration=? "); + + if (group->image_thumbnail_changed) + len += snprintf(query+len, sizeof(query)-len, ", image_thumbnail_path = ? "); + + snprintf(query+len, sizeof(query)-len, "WHERE group_id=%d", group->id); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("DB error : cts_query_prepare() Failed"); + return CONTACTS_ERROR_DB; + } + + ret = ctsvc_begin_trans(); + if( ret < CONTACTS_ERROR_NONE ) { + CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + cts_stmt_bind_text(stmt, 1, group->name); + cts_stmt_bind_int(stmt, 2, ctsvc_get_next_ver()); + + if (group->ringtone_path) + cts_stmt_bind_text(stmt, 3, group->ringtone_path); + + if (group->vibration) + cts_stmt_bind_text(stmt, 4, group->vibration); + + if (group->image_thumbnail_changed) { + ret = ctsvc_change_image(CTS_GROUP_IMAGE_LOCATION, group->id, group->image_thumbnail_path, + image, sizeof(image)); + if(CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_change_image() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + if (*image) { + free(group->image_thumbnail_path); + group->image_thumbnail_path = strdup(image); + cts_stmt_bind_text(stmt, 5, image); + } + } + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + cts_stmt_finalize(stmt); + + 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; +} + +static int __ctsvc_db_group_delete_record( int index ) +{ + int ret; + 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, index); + + ret = ctsvc_query_get_first_int_result(query, &addressbook_id); + if ( ret < CONTACTS_ERROR_NONE) { + CTS_ERR("DB error : The index(%d) is Invalid(%d)", index, addressbook_id); + 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, index); + + 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 = cts_db_change(); + if (ret <= 0) { + ctsvc_end_trans(false); + return CONTACTS_ERROR_NO_DATA; + } + + snprintf(query, sizeof(query), "INSERT INTO %s VALUES(%d, %d, %d)", + CTS_TABLE_GROUP_DELETEDS, index, addressbook_id, ctsvc_get_next_ver()); + 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_change_image(CTS_GROUP_IMAGE_LOCATION, index, NULL, NULL, 0); + if (ret < 0) { + CTS_ERR("DB error : ctsvc_change_image() 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; + } + + 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->system_id = 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++); + 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; + int len; + 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; + + len = snprintf(query, sizeof(query), + "SELECT group_id, addressbook_id, group_name, system_id, is_read_only, " + "ringtone_path, vibration, image_thumbnail_path " + "FROM "CTS_TABLE_GROUPS" WHERE group_id = %d", id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ret = __ctsvc_db_group_value_set(stmt, &record); + + cts_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, system_id, is_read_only, " + "ringtone_path, vibration, image_thumbnail_path " + "FROM "CTS_TABLE_GROUPS" ORDER BY addressbook_id, group_name COLLATE NOCASE"); + + 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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return ret; + } + __ctsvc_db_group_value_set(stmt, &record); + + ctsvc_list_prepend(list, record); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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_SYSTEM_ID: + temp = ctsvc_stmt_get_text(stmt, i); + group->system_id = 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); + } + cts_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_grouprelation.c b/native/ctsvc_db_plugin_grouprelation.c new file mode 100644 index 0000000..bb37b9d --- /dev/null +++ b/native/ctsvc_db_plugin_grouprelation.c @@ -0,0 +1,209 @@ +/* + * 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" + +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 update 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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step Failed(%d)", ret); + cts_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); + } + } + + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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->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); + } + cts_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 index 0000000..bd9acb3 --- /dev/null +++ b/native/ctsvc_db_plugin_image.c @@ -0,0 +1,360 @@ +/* + * 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_image_helper.h" +#include "ctsvc_db_plugin_contact_helper.h" +#include "ctsvc_record.h" +#include "ctsvc_db_query.h" +#include "ctsvc_list.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_insert_record( contacts_record_h record, int *id ) +{ + int ret; + int contact_id; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_image_s *image = (ctsvc_image_s *)record; + + 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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", image->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + 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; + } + + ret = ctsvc_db_contact_update_changed_time(image->contact_id); + 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; +} + +static int __ctsvc_db_image_get_record( int id, contacts_record_h* out_record ) +{ + int ret; + int len; + cts_stmt stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER); + *out_record = NULL; + + 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 id = %d AND datatype = %d ", + id, CTSVC_DATA_IMAGE); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ctsvc_db_image_get_value_from_stmt(stmt, out_record, 0); + + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_image_update_record( contacts_record_h record ) +{ + int ret; + int contact_id; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_image_s *image = (ctsvc_image_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", image->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + 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; + } + + ret = ctsvc_db_contact_update_changed_time(image->contact_id); + 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; +} + +static int __ctsvc_db_image_delete_record( int id ) +{ + int ret; + int contact_id; + 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 FROM "CTSVC_DB_VIEW_CONTACT " " + "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if( ret != CONTACTS_ERROR_NONE ) { + CTS_ERR("The id(%d) is Invalid(%d)", id, ret); + ctsvc_end_trans(false); + return contact_id; + } + + ret = ctsvc_db_image_delete(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(contact_id); + 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; +} + +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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB : cts_stmt_step fail(%d)", ret); + cts_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); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + } + cts_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 index 0000000..8e49099 --- /dev/null +++ b/native/ctsvc_db_plugin_image_helper.c @@ -0,0 +1,178 @@ +/* + * 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_plugin_image_helper.h" +#include "ctsvc_db_plugin_contact_helper.h" +#include "ctsvc_record.h" +#include "ctsvc_notification.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", CTS_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) + cts_stmt_bind_text(stmt, start_cnt, image->label); + if (image->path) + cts_stmt_bind_text(stmt, start_cnt+1, image->path); + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_image_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}; + char image_path[CTS_SQL_MAX_LEN] = {0}; + ctsvc_image_s *image = (ctsvc_image_s *)record; + + // These check should be done in client side +// RETVM_IF(image->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted image record"); + 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_contact_add_image_file(CTSVC_IMG_NORMAL, contact_id, image->path, + image_path, sizeof(image_path)); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("ctsvc_contact_add_image_file(NORMAL) Failed(%d)", ret); + return ret; + } + free(image->path); + image->path = strdup(image_path); + + 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_IMAGE, image->is_default, image->type); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + __ctsvc_image_bind_stmt(stmt, image, 1); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + //image->id = cts_db_get_last_insert_id(); + if (id) + *id = cts_db_get_last_insert_id(); + cts_stmt_finalize(stmt); + + 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 ret; + ctsvc_image_s *image = (ctsvc_image_s*)record; + char query[CTS_SQL_MAX_LEN] = {0}; + char image_path[CTS_SQL_MAX_LEN] = {0}; + cts_stmt stmt; + + RETVM_IF(!image->id, CONTACTS_ERROR_INVALID_PARAMETER, "image of contact has no ID."); + + ret = ctsvc_contact_update_image_file(CTSVC_IMG_NORMAL, contact_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); + } + + snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_DATA" SET contact_id=%d, is_my_profile=%d, is_default=%d, data1=%d, data2=?, data3=? WHERE id=%d", + contact_id, is_my_profile, image->is_default, image->type, image->id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + __ctsvc_image_bind_stmt(stmt, image, 1); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_image_noti(); + image->is_changed = false; + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_image_delete(int id) +{ + 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); + ctsvc_set_image_noti(); + + return CONTACTS_ERROR_NONE; +} + diff --git a/native/ctsvc_db_plugin_image_helper.h b/native/ctsvc_db_plugin_image_helper.h new file mode 100644 index 0000000..e06b54b --- /dev/null +++ b/native/ctsvc_db_plugin_image_helper.h @@ -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); + +int ctsvc_db_image_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_messenger.c b/native/ctsvc_db_plugin_messenger.c new file mode 100644 index 0000000..6eca202 --- /dev/null +++ b/native/ctsvc_db_plugin_messenger.c @@ -0,0 +1,357 @@ +/* + * 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_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 contact_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", messenger->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + 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_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; +} + +static int __ctsvc_db_messenger_get_record( int id, contacts_record_h* out_record ) +{ + int ret; + int len; + cts_stmt stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER); + *out_record = NULL; + + 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 id = %d AND datatype = %d ", + id, CTSVC_DATA_MESSENGER); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ctsvc_db_messenger_get_value_from_stmt(stmt, out_record, 0); + + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_messenger_update_record( contacts_record_h record ) +{ + int ret; + int contact_id; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_messenger_s *messenger = (ctsvc_messenger_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", messenger->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + ret = ctsvc_db_messenger_update(record, messenger->contact_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(messenger->contact_id); + 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; +} + +static int __ctsvc_db_messenger_delete_record( int id ) +{ + int ret; + int contact_id; + 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 FROM "CTSVC_DB_VIEW_CONTACT " " + "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if( ret != CONTACTS_ERROR_NONE ) { + CTS_ERR("The id(%d) is Invalid(%d)", id, ret); + ctsvc_end_trans(false); + return contact_id; + } + + ret = ctsvc_db_messenger_delete(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(contact_id); + 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; +} + +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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB : cts_stmt_step fail(%d)", ret); + cts_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); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + } + cts_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 index 0000000..204513c --- /dev/null +++ b/native/ctsvc_db_plugin_messenger_helper.c @@ -0,0 +1,147 @@ +/* + * 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_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}; + +// RETVM_IF(messenger->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted messenger record"); + 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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + 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 = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + //messenger->id = cts_db_get_last_insert_id(); + if (id) + *id = cts_db_get_last_insert_id(); + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_messenger_noti(); + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_messenger_update(contacts_record_h record, int contact_id, bool is_my_profile) +{ + int ret; + ctsvc_messenger_s *messenger = (ctsvc_messenger_s*)record; + char query[CTS_SQL_MAX_LEN] = {0}; + cts_stmt stmt; + + RETVM_IF(!messenger->id, CONTACTS_ERROR_INVALID_PARAMETER, "messenger of contact has no ID."); + + snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_DATA" SET contact_id=%d, is_my_profile=%d, data1=%d, data2=?, data3=? WHERE id=%d", + contact_id, is_my_profile, messenger->type, messenger->id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + if (messenger->label) + cts_stmt_bind_text(stmt, 1, messenger->label); + if (messenger->im_id) + cts_stmt_bind_text(stmt, 2, messenger->im_id); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_messenger_noti(); + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_messenger_delete(int id) +{ + 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); + 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 index 0000000..c501fed --- /dev/null +++ b/native/ctsvc_db_plugin_messenger_helper.h @@ -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_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, int contact_id, bool is_my_profile); +int ctsvc_db_messenger_delete(int id); + +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 index 0000000..248b739 --- /dev/null +++ b/native/ctsvc_db_plugin_my_profile.c @@ -0,0 +1,1089 @@ +/* + * 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.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, len; + 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}; + + len = 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", + ctsvc_get_display_column(), id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + 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", CTS_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); + cts_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, len; + int datatype; + cts_stmt stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + len = snprintf(query, sizeof(query), + "SELECT datatype, id, contact_id, is_default, data1, data2, " + "data3, data4, data5, data6, data7, data8, data9, data10 " + "FROM "CTS_TABLE_DATA" WHERE contact_id = %d AND is_my_profile = 1", id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE */!= ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + 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*/ == cts_stmt_step(stmt)); + + cts_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_get_data_info 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; + 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), "DELETE FROM %s WHERE my_profile_id = %d", CTS_TABLE_MY_PROFILES, 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_safe_strcmp(char *s1, char *s2) +{ + if (NULL == s1 || NULL == s2) + return !(s1 == s2); + else + return strcmp(s1, s2); +} + +static inline void __ctsvc_update_my_profile_display_name(ctsvc_my_profile_s *my_profile) +{ + char *temp_display_name = NULL; + char display[CTSVC_MY_PROFILE_DISPLAY_NAME_MAX_LEN] = {0}; + GList *cur; + int len=0; + + ctsvc_name_s *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) ) { + if (name->first && name->last){ + snprintf(display, sizeof(display), "%s %s",name->first,name->last); + temp_display_name = strdup(display); + } + else if (name->first) + temp_display_name = strdup(name->first); + else + temp_display_name = strdup(name->last); + + if (0 != __ctsvc_safe_strcmp(my_profile->display_name, temp_display_name)) { + // make display name + if(name->first) + len += snprintf(display + len, sizeof(display) - len, "%s", name->first); + + if(name->addition) { + if (*display) + len += snprintf(display + len, sizeof(display) - len, " "); + len += snprintf(display + len, sizeof(display) - len, "%s", name->addition); + } + + if(name->last) { + if (*display) + len += snprintf(display + len, sizeof(display) - len, " "); + len += snprintf(display + len, sizeof(display) - len, "%s", name->last); + } + + if(name->suffix) { + if (*display) + len += snprintf(display + len, sizeof(display) - len, " "); + len += snprintf(display + len, sizeof(display) - len, "%s", name->suffix); + } + my_profile->display_name = strdup(display); + } + free(temp_display_name); + } + else { + 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) { + if (__ctsvc_safe_strcmp(my_profile->display_name, company->name)) { + my_profile->display_name = SAFE_STRDUP(company->name); + break; + } + } + } + } + else if (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) { + if (__ctsvc_safe_strcmp(my_profile->display_name, nickname->nickname)) { + my_profile->display_name = SAFE_STRDUP(nickname->nickname); + break; + } + } + } + } + else if (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) { + if (__ctsvc_safe_strcmp(my_profile->display_name, number->number)) { + my_profile->display_name = SAFE_STRDUP(number->number); + break; + } + } + } + } + else if (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) { + if (__ctsvc_safe_strcmp(my_profile->display_name, email->email_addr)) { + my_profile->display_name = SAFE_STRDUP(email->email_addr); + break; + } + } + } + } + } + return; +} + +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); +} + +static int __ctsvc_db_my_profile_update_record( contacts_record_h record ) +{ + int ret, len; + int count; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_my_profile_s *my_profile = (ctsvc_my_profile_s*)record; + cts_stmt stmt; + + snprintf(query, sizeof(query), + "SELECT count(my_profile_id) FROM "CTS_TABLE_MY_PROFILES" WHERE my_profile_id = %d", my_profile->id); + ret = ctsvc_query_get_first_int_result(query, &count); + RETVM_IF(1 != count, CONTACTS_ERROR_NO_DATA, + "The index(%d) is Invalid. %d Record(s) is(are) found", my_profile->id, ret); + + ret = ctsvc_begin_trans(); + RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret); + + __ctsvc_update_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. + free(my_profile->image_thumbnail_path); + my_profile->image_thumbnail_path = NULL; + + if (my_profile->images) { + int ret = CONTACTS_ERROR_NONE; + contacts_record_h record = NULL; + unsigned int count = 0; + ctsvc_list_s *list = (ctsvc_list_s*)my_profile->images; + ctsvc_image_s *image; + GList *cursor; + + for(cursor = list->deleted_records;cursor;cursor=cursor->next) { + image = (ctsvc_image_s *)cursor->data; + my_profile->image_thumbnail_path = NULL; + } + + 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); + + 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; + + if ( image->path && *image->path && strstr(image->path, CTS_IMG_FULL_LOCATION) != NULL) + my_profile->image_thumbnail_path = SAFE_STRDUP( image->path + strlen(CTS_IMG_FULL_LOCATION) + 1); + else + my_profile->image_thumbnail_path = SAFE_STRDUP(image->path); + + } + } + // this code will be removed. + ////////////////////////////////////////////////////////////////////// + + len = snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_MY_PROFILES" SET changed_ver=%d, changed_time=%d, " + "display_name=?, uid=?, image_thumbnail_path=?", + ctsvc_get_next_ver(), (int)time(NULL)); + snprintf(query+len, sizeof(query)-len, " WHERE my_profile_id=%d", my_profile->id); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare() Failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + cts_stmt_bind_text(stmt, 1, my_profile->display_name); + if (my_profile->uid) + cts_stmt_bind_text(stmt, 2, my_profile->uid); + if (my_profile->image_thumbnail_path) + cts_stmt_bind_text(stmt, 3, my_profile->image_thumbnail_path); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + cts_stmt_finalize(stmt); + + 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 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 "CTS_TABLE_MY_PROFILES); + + 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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return CONTACTS_ERROR_NO_DATA; + } + ctsvc_list_prepend(list, record); + } + cts_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) { + s_query->projection = realloc(s_query->projection, s_query->projection_count+1); + 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); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE == ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + contacts_list_create(&list); + do { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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; + + 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", CTS_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_get_data_info Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return ret; + } + + ctsvc_list_prepend(list, record); + } while ((ret = cts_stmt_step(stmt))); + cts_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; +} + +void __ctsvc_make_my_profile_display_name(ctsvc_my_profile_s *my_profile) +{ + char display[CTS_SQL_MAX_LEN]={0}; + GList *cur; + int len; + + ctsvc_name_s *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) ) { + + // make display name + len=0; + if(name->first) + len += snprintf(display + len, sizeof(display) - len, "%s", name->first); + + if(name->addition) { + if (*display) + len += snprintf(display + len, sizeof(display) - len, " "); + len += snprintf(display + len, sizeof(display) - len, "%s", name->addition); + } + + if(name->last) { + if (*display) + len += snprintf(display + len, sizeof(display) - len, " "); + len += snprintf(display + len, sizeof(display) - len, "%s", name->last); + } + + if(name->suffix) { + if (*display) + len += snprintf(display + len, sizeof(display) - len, " "); + len += snprintf(display + len, sizeof(display) - len, "%s", name->suffix); + } + + my_profile->display_name = strdup(display); + } + else { + 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) { + my_profile->display_name = SAFE_STRDUP(company->name); + break; + } + } + } + + if (NULL == my_profile->display_name && 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) { + my_profile->display_name = SAFE_STRDUP(nickname->nickname); + break; + } + } + } + + if (NULL == my_profile->display_name && 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) { + my_profile->display_name = SAFE_STRDUP(number->number); + break; + } + } + } + + if (NULL == my_profile->display_name && 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) { + my_profile->display_name = SAFE_STRDUP(email->email_addr); + break; + } + } + } + } + return; +} + +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(my_profile->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted my_profile record"); + 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); + + ret = cts_db_get_next_id(CTS_TABLE_MY_PROFILES); + if (ret < CONTACTS_ERROR_NONE) { + CTS_ERR("cts_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; + unsigned 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, uid, image_thumbnail_path) " + "VALUES(%d, %d, %d, %d, %d, ?, ?, ?)", + my_profile->id, my_profile->addressbook_id, version, version, (int)time(NULL)); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare() Failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + if (my_profile->display_name) + cts_stmt_bind_text(stmt, 1, my_profile->display_name); + if (my_profile->uid) + cts_stmt_bind_text(stmt, 2, my_profile->uid); + if (my_profile->image_thumbnail_path) + cts_stmt_bind_text(stmt, 3, my_profile->image_thumbnail_path); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + cts_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 index 0000000..15ac142 --- /dev/null +++ b/native/ctsvc_db_plugin_name.c @@ -0,0 +1,382 @@ +/* + * 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_plugin_contact_helper.h" +#include "ctsvc_db_plugin_name_helper.h" +#include "ctsvc_record.h" +#include "ctsvc_list.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 contact_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", name->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_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; + } + + // TODO ; contact name update + ret = ctsvc_db_contact_update_changed_time(name->contact_id); + 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; +} + +static int __ctsvc_db_name_get_record( int id, contacts_record_h* out_record ) +{ + int ret; + int len; + cts_stmt stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER); + *out_record = NULL; + + 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 id = %d AND datatype = %d ", + id, CTSVC_DATA_NAME); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ctsvc_db_name_get_value_from_stmt(stmt, out_record, 0); + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_name_update_record( contacts_record_h record ) +{ + int ret; + int contact_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", name->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + ret = ctsvc_db_name_update(record, name->contact_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 display name update + ret = ctsvc_db_contact_update_changed_time(name->contact_id); + 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; +} + + +static int __ctsvc_db_name_delete_record( int id ) +{ + int ret; + int contact_id; + 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 FROM "CTSVC_DB_VIEW_CONTACT " " + "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if( ret != CONTACTS_ERROR_NONE ) { + CTS_ERR("The id(%d) is Invalid(%d)", id, ret); + ctsvc_end_trans(false); + return contact_id; + } + + ret = ctsvc_db_name_delete(id); + 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_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; +} + +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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step Failed(%d)", ret); + cts_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); + } + + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step Failed(%d)", ret); + cts_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); + } + cts_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 index 0000000..527b504 --- /dev/null +++ b/native/ctsvc_db_plugin_name_helper.c @@ -0,0 +1,385 @@ +/* + * 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_db_init.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); + 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); + 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) +{ + cts_stmt_bind_int(stmt, start_cnt, name->is_default); + cts_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) { + dest[CTSVC_NN_FIRST] = calloc(1, strlen(src->first)* 5); + ret = ctsvc_normalize_str(src->first, dest[CTSVC_NN_FIRST], strlen(src->first)*5); + RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "_cts_normalize_str() Failed(%d)", ret); + language_type = ret; + } + + if (src->last) { + dest[CTSVC_NN_LAST] = calloc(1, strlen(src->last)* 5); + ret = ctsvc_normalize_str(src->last, dest[CTSVC_NN_LAST], strlen(src->last)*5); + RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "_cts_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 *tmp_first, *tmp_last; + 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; + + RETV_IF(NULL == name, CONTACTS_ERROR_INVALID_PARAMETER); + +// RETVM_IF(name->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted name record"); + 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) { + 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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + tmp_first = name->first; + tmp_last = name->last; + + ret = __ctsvc_normalize_name(name, normal_name); + if (ret < CONTACTS_ERROR_NONE) { + CTS_ERR("__ctsvc_normalize_name() Failed(%d)", ret); + cts_stmt_finalize(stmt); + 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_default_language() == ret) + name->language_type = CTSVC_LANG_DEFAULT; + else if (ctsvc_get_secondary_language() == 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); + +// CTS_DBG("lookup=%s(%d), reverse_lookup=%s(%d)", +// lookup, strlen(lookup), reverse_lookup, strlen(reverse_lookup)); + + free(normal_name[CTSVC_NN_FIRST]); + free(normal_name[CTSVC_NN_LAST]); + + __ctsvc_name_bind_stmt(stmt, name, 1); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + //name->id = cts_db_get_last_insert_id(); + if (id) + *id = cts_db_get_last_insert_id(); + name->contact_id = contact_id; + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_name_noti(); + } + + + // update search index table + name->is_changed = false; + 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, int contact_id, bool is_my_profile) +{ + int ret, len=0; + ctsvc_name_s *name = (ctsvc_name_s*)record; + char *tmp_first, *tmp_last; + char query[CTS_SQL_MAX_LEN] = {0}; + char *normal_name[CTSVC_NN_MAX] = {NULL}; + char *temp_normal_first = NULL; + char *temp_normal_last = NULL; + cts_stmt stmt; + + RETV_IF(false == name->is_changed, CONTACTS_ERROR_NONE); + RETVM_IF(!name->id, CONTACTS_ERROR_INVALID_PARAMETER, "name of contact has no ID."); + + snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_DATA" SET contact_id=%d, is_my_profile=%d, is_default=?, data1=?, data2=?, data3=?, data4=?," + "data5=?, data6=?, data7=?, data8=?, data9=?, data10=?, data11=?, data12=? WHERE id=%d", contact_id, is_my_profile, name->id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + 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); + cts_stmt_finalize(stmt); + 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_default_language() == ret) + name->language_type = CTSVC_LANG_DEFAULT; + else if (ctsvc_get_secondary_language() == 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); + +// CTS_DBG("lookup=%s(%d), reverse_lookup=%s(%d)", +// lookup, strlen(lookup), reverse_lookup, strlen(reverse_lookup)); + + free(normal_name[CTSVC_NN_FIRST]); + free(normal_name[CTSVC_NN_LAST]); + + __ctsvc_name_bind_stmt(stmt, name, 1); + name->contact_id = contact_id; + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_name_noti(); + name->is_changed = false; + + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_name_delete(int id) +{ + 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); + 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 index 0000000..4539a0f --- /dev/null +++ b/native/ctsvc_db_plugin_name_helper.h @@ -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, int contact_id, bool is_my_profile); +int ctsvc_db_name_delete(int id); + +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 index 0000000..62b5be7 --- /dev/null +++ b/native/ctsvc_db_plugin_nickname.c @@ -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 "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_nickname_helper.h" +#include "ctsvc_record.h" +#include "ctsvc_db_query.h" +#include "ctsvc_list.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 contact_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", nickname->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + 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; + } + + ret = ctsvc_db_contact_update_changed_time(nickname->contact_id); + 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; +} + +static int __ctsvc_db_nickname_get_record( int id, contacts_record_h* out_record ) +{ + int ret; + int len; + cts_stmt stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER); + *out_record = NULL; + + 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 id = %d AND datatype = %d ", + id, CTSVC_DATA_NICKNAME); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ctsvc_db_nickname_get_value_from_stmt(stmt, out_record, 0); + + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_nickname_update_record( contacts_record_h record ) +{ + int ret; + int contact_id; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_nickname_s *nickname = (ctsvc_nickname_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", nickname->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + ret = ctsvc_db_nickname_update(record, nickname->contact_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(nickname->contact_id); + 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; +} + +static int __ctsvc_db_nickname_delete_record( int id ) +{ + int ret; + int contact_id; + 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 FROM "CTSVC_DB_VIEW_CONTACT " " + "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if( ret != CONTACTS_ERROR_NONE ) { + CTS_ERR("The id(%d) is Invalid(%d)", id, ret); + ctsvc_end_trans(false); + return contact_id; + } + + ret = ctsvc_db_nickname_delete(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(contact_id); + 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; +} + +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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB : cts_stmt_step fail(%d)", ret); + cts_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); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + } + cts_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 index 0000000..e1b59c0 --- /dev/null +++ b/native/ctsvc_db_plugin_nickname_helper.c @@ -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_db_init.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; + +// RETVM_IF(nickname->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted nickname 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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + if (nickname->label) + cts_stmt_bind_text(stmt, 1, nickname->label); + if (nickname->nickname) + cts_stmt_bind_text(stmt, 2, nickname->nickname); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + //nickname->id = cts_db_get_last_insert_id(); + if (id) + *id = cts_db_get_last_insert_id(); + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_nickname_noti(); + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_nickname_update(contacts_record_h record, int contact_id, bool is_my_profile) +{ + int ret; + ctsvc_nickname_s *nickname = (ctsvc_nickname_s*)record; + char query[CTS_SQL_MAX_LEN] = {0}; + cts_stmt stmt; + + RETVM_IF(!nickname->id, CONTACTS_ERROR_INVALID_PARAMETER, "nickname of contact has no ID."); + + snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_DATA" SET contact_id=%d, is_my_profile=%d, data1=%d, data2=?, data3=? WHERE id=%d", + contact_id, is_my_profile, nickname->type, nickname->id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + if (nickname->label) + cts_stmt_bind_text(stmt, 1, nickname->label); + if (nickname->nickname) + cts_stmt_bind_text(stmt, 2, nickname->nickname); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_nickname_noti(); + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_nickname_delete(int id) +{ + 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); + 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 index 0000000..f94fde4 --- /dev/null +++ b/native/ctsvc_db_plugin_nickname_helper.h @@ -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_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, int contact_id, bool is_my_profile); +int ctsvc_db_nickname_delete(int id); + +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 index 0000000..6b6702f --- /dev/null +++ b/native/ctsvc_db_plugin_note.c @@ -0,0 +1,352 @@ +/* + * 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_note_helper.h" +#include "ctsvc_db_query.h" +#include "ctsvc_list.h" +#include "ctsvc_record.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; + int len; + cts_stmt stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER); + *out_record = NULL; + + 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 id = %d AND datatype = %d ", + id, CTSVC_DATA_NOTE); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ctsvc_db_note_get_value_from_stmt(stmt, out_record, 0); + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_note_insert_record( contacts_record_h record, int *id ) +{ + int ret; + int contact_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", note->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + 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_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; +} + +static int __ctsvc_db_note_update_record( contacts_record_h record ) +{ + int ret; + int contact_id; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_note_s *note = (ctsvc_note_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", note->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + ret = ctsvc_db_note_update(record, note->contact_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 display note update + ret = ctsvc_db_contact_update_changed_time(note->contact_id); + 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; +} + + +static int __ctsvc_db_note_delete_record( int id ) +{ + int ret; + int contact_id; + 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 FROM "CTSVC_DB_VIEW_CONTACT " " + "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if( ret != CONTACTS_ERROR_NONE ) { + CTS_ERR("The id(%d) is Invalid(%d)", id, ret); + ctsvc_end_trans(false); + return contact_id; + } + + ret = ctsvc_db_note_delete(id); + 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_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; +} + +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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB : cts_stmt_step fail(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return ret; + } + ctsvc_db_note_get_value_from_stmt(stmt, (contacts_record_h*)¬e, 0); + ctsvc_list_prepend(list, (contacts_record_h)note); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + } + cts_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 index 0000000..d0d04f1 --- /dev/null +++ b/native/ctsvc_db_plugin_note_helper.c @@ -0,0 +1,136 @@ +/* + * 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_note_helper.h" +#include "ctsvc_notification.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 *)¬e); + 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}; + +// RETVM_IF(note->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted note record"); + 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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + sqlite3_bind_text(stmt, 1, note->note, + strlen(note->note), SQLITE_STATIC); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + if (id) + *id = cts_db_get_last_insert_id(); + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_note_noti(); + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_note_update(contacts_record_h record, int contact_id, bool is_my_profile) +{ + int ret; + ctsvc_note_s *note = (ctsvc_note_s*)record; + char query[CTS_SQL_MAX_LEN] = {0}; + cts_stmt stmt; + + RETVM_IF(!note->id, CONTACTS_ERROR_INVALID_PARAMETER, "note of contact has no ID."); + snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_DATA" SET contact_id=%d, is_my_profile=%d, data3=? WHERE id=%d", + contact_id, is_my_profile, note->id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + if (note->note) + sqlite3_bind_text(stmt, 1, note->note, + strlen(note->note), SQLITE_STATIC); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_note_noti(); + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_note_delete(int id) +{ + 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); + 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 index 0000000..f0b3407 --- /dev/null +++ b/native/ctsvc_db_plugin_note_helper.h @@ -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_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, int contact_id, bool is_my_profile); +int ctsvc_db_note_delete(int id); + +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 index 0000000..d6d8335 --- /dev/null +++ b/native/ctsvc_db_plugin_number.c @@ -0,0 +1,384 @@ +/* + * 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_plugin_number_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_insert_record( contacts_record_h record, int *id ) +{ + int ret; + int contact_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, + "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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", number->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + 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("cts_query_exec() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + + // should update person default number + ctsvc_set_contact_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, type, label, number, lookup " + "FROM "CTSVC_DB_VIEW_NUMBER" WHERE id = %d", id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ctsvc_db_number_get_value_from_stmt(stmt, out_record, 0); + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_number_update_record( contacts_record_h record ) +{ + int ret; + int contact_id; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_number_s *number = (ctsvc_number_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", number->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + ret = ctsvc_db_number_update(record, number->contact_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), + "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("cts_query_exec() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + + // should update person default number + ctsvc_set_contact_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 contact_id; + char query[CTS_SQL_MAX_LEN] = {0}; + bool has_phonenumber = false; + + 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 FROM "CTSVC_DB_VIEW_CONTACT " " + "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if( ret != CONTACTS_ERROR_NONE ) { + CTS_ERR("The id(%d) is Invalid(%d)", id, ret); + ctsvc_end_trans(false); + return ret; + } + + ret = ctsvc_db_number_delete(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), + "SELECT COUNT(id) FROM "CTS_TABLE_DATA" WHERE contact_id = %d AND is_my_profile = 0", contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_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("cts_query_exec() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + + // should update person default number + ctsvc_set_contact_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_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, contact_id, is_default, type, label, number, lookup FROM "CTSVC_DB_VIEW_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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step Failed (%d)", ret); + cts_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); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + } + cts_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 index 0000000..4a27b34 --- /dev/null +++ b/native/ctsvc_db_plugin_number_helper.c @@ -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 "contacts.h" +#include "ctsvc_internal.h" +#include "ctsvc_schema.h" +#include "ctsvc_sqlite.h" +#include "ctsvc_db_init.h" +#include "ctsvc_normalize.h" +#include "ctsvc_db_plugin_number_helper.h" +#include "ctsvc_record.h" +#include "ctsvc_notification.h" + +int ctsvc_db_number_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_number_s *number = (ctsvc_number_s *)record; + char normal_num[CTSVC_NUMBER_MAX_LEN] = {0}; + char clean_num[CTSVC_NUMBER_MAX_LEN] = {0}; + +// RETVM_IF(number->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted number 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) " + "VALUES(%d, %d, %d, %d, %d, ?, ?, ?)", + contact_id, is_my_profile, CTSVC_DATA_NUMBER, number->is_default, number->type); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + if (number->label) + cts_stmt_bind_text(stmt, 1, number->label); + + cts_stmt_bind_text(stmt, 2, number->number); + ret = ctsvc_clean_number(number->number, clean_num, sizeof(clean_num)); + if (0 < ret) { + ret = ctsvc_normalize_number(clean_num, normal_num, CTSVC_NUMBER_MAX_LEN); + if (CONTACTS_ERROR_NONE == ret) + cts_stmt_bind_text(stmt, 3, normal_num); + } + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + //number->id = cts_db_get_last_insert_id(); + if (id) + *id = cts_db_get_last_insert_id(); + cts_stmt_finalize(stmt); + + if (!is_my_profile) + 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); + + *record = (contacts_record_h)number; + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_number_update(contacts_record_h record, int contact_id, bool is_my_profile) +{ + int ret; + ctsvc_number_s *number = (ctsvc_number_s*)record; + char query[CTS_SQL_MAX_LEN] = {0}; + char normal_num[CTSVC_NUMBER_MAX_LEN] = {0}; + char clean_num[CTSVC_NUMBER_MAX_LEN] = {0}; + cts_stmt stmt; + + RETVM_IF(!number->id, CONTACTS_ERROR_INVALID_PARAMETER, "number of contact has no ID."); + + snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_DATA" SET contact_id=%d, is_my_profile=%d, data1=%d, data2=?, data3=?, data4=? WHERE id=%d", + contact_id, is_my_profile, number->type, number->id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + if (number->label) + cts_stmt_bind_text(stmt, 1, number->label); + + if (number->number) + cts_stmt_bind_text(stmt, 2, number->number); + ret = ctsvc_clean_number(number->number, clean_num, sizeof(clean_num)); + if (0 < ret) { + ret = ctsvc_normalize_number(clean_num, normal_num, CTSVC_NUMBER_MAX_LEN); + if (CONTACTS_ERROR_NONE == ret) + cts_stmt_bind_text(stmt, 3, normal_num); + } + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_number_noti(); + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_number_delete(int id) +{ + 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_NUMBER); + + ret = ctsvc_query_exec(query); + RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_query_exec() Failed(%d)", ret); + 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 index 0000000..fe07513 --- /dev/null +++ b/native/ctsvc_db_plugin_number_helper.h @@ -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, int contact_id, bool is_my_profile); +int ctsvc_db_number_delete(int id); + +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 index 0000000..b7e4eee --- /dev/null +++ b/native/ctsvc_db_plugin_person.c @@ -0,0 +1,609 @@ +/* + * 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_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, " + "status, " + "link_count, " + "account_id1, " + "account_id2, " + "account_id3, " + "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_display_column(), id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if( 1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + ret = ctsvc_db_person_create_record_from_stmt(stmt, &record); + cts_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 inline int __ctsvc_db_person_set_favorite(int person_id, bool set) +{ + 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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ == ret) { + prio = ctsvc_stmt_get_dbl(stmt, 0); + } + else if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + cts_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("cts_query_exec() Failed(%d)", ret); + return ret; + } + + ret = cts_db_change(); + if (0 < ret) + ctsvc_set_favor_noti(); + + 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("cts_query_exec() Failed(%d)", ret); + return ret; + } + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_person_update_record( contacts_record_h record ) +{ + int ret, i, len, len2; + cts_stmt stmt = NULL; + char query[CTS_SQL_MIN_LEN] = {0}; + char contact_query[CTS_SQL_MIN_LEN] = {0}; + ctsvc_person_s *person = (ctsvc_person_s *)record; + const char *display_name = NULL; + + 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); + + len = snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_PERSONS" SET changed_ver=%d ", ctsvc_get_next_ver()); + + len2 = snprintf(contact_query, sizeof(contact_query), + "UPDATE "CTS_TABLE_CONTACTS" SET changed_ver=%d ", ctsvc_get_next_ver()); + + if (person->name_contact_id_changed) { + // 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); + stmt = cts_query_prepare(check_query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare() Failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + ret = cts_stmt_step(stmt); + if ( 1 != ret) { + if ( CONTACTS_ERROR_NONE == ret) { + CTS_ERR("Invalid paramter : the name_contact_id(%d) is not linked with person_id(%d)", + person->name_contact_id, person->person_id); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + else { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + } + temp = ctsvc_stmt_get_text(stmt, 0); + display_name = SAFE_STRDUP(temp); + + len += snprintf(query + len, sizeof(query) - len, ", name_contact_id = %d ", person->name_contact_id); + + cts_stmt_finalize(stmt); + } + if (person->image_thumbnail_changed) + len += snprintf(query + len, sizeof(query) - len, ", image_thumbnail_path=? "); + if (person->ringtone_changed) { + len += snprintf(query + len, sizeof(query) - len, ", ringtone_path=? "); + len2 += snprintf(contact_query + len2, sizeof(contact_query) - len2, ", ringtone_path=? "); + } + if (person->vibration_changed) { + len += snprintf(query + len, sizeof(query) - len, ", vibration=? "); + len2 += snprintf(contact_query + len2, sizeof(contact_query) - len2, ", vibration=? "); + } + + snprintf(query+len, sizeof(query)-len, " WHERE person_id=%d", person->person_id); + snprintf(contact_query+len2, sizeof(contact_query)-len2, + " WHERE person_id=%d AND deleted = 0", person->person_id); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare() Failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + i = 1; + if (person->image_thumbnail_changed) { + if (person->image_thumbnail_path) + cts_stmt_bind_text(stmt, i, person->image_thumbnail_path); + i++; + } + + if (person->ringtone_changed) { + if (person->ringtone_path) + cts_stmt_bind_text(stmt, i, person->ringtone_path); + i++; + } + if (person->vibration_changed) { + if (person->vibration) + cts_stmt_bind_text(stmt, i, person->vibration); + i++; + } + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + cts_stmt_finalize(stmt); + + stmt = cts_query_prepare(contact_query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare() Failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + i = 1; + if (person->ringtone_changed) { + if (person->ringtone_path) + cts_stmt_bind_text(stmt, i, person->ringtone_path); + i++; + } + if (person->vibration_changed) { + if (person->vibration) + cts_stmt_bind_text(stmt, i, person->vibration); + i++; + } + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + cts_stmt_finalize(stmt); + + // update favorite + if (person->is_favorite_changed) { + ret = __ctsvc_db_person_set_favorite(person->person_id, person->is_favorite); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + } + + // update person display_name + if (display_name) { + char temp[CTS_SQL_MAX_LEN] = {0}; + person->display_name = SAFE_STRDUP(display_name); + ret = ctsvc_normalize_index(person->display_name, temp, sizeof(temp)); + if (0 <= ret) + person->display_name_index = strdup(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); + if (ret < CONTACTS_ERROR_NONE) + { + CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret); + return ret; + } + else { + person->name_contact_id_changed = false; + person->image_thumbnail_changed = false; + person->ringtone_changed = false; + person->vibration_changed = false; + person->is_favorite_changed = false; + return CONTACTS_ERROR_NONE; + } +} + +static int __ctsvc_db_person_delete_record( int id ) +{ + int ret, rel_changed; + 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), + "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)", + 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; + } + + rel_changed = cts_db_change(); + + // images are deleted by db trigger callback function in ctsvc_db_contact_delete_callback + snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_CONTACTS" 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; + } + + 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, " + "status, " + "link_count, " + "account_id1, " + "account_id2, " + "account_id3, " + "addressbook_ids, " + "has_phonenumber, " + "has_email, " + "is_favorite " + "FROM "CTSVC_DB_VIEW_PERSON" ORDER BY %s", + ctsvc_get_display_column(), ctsvc_get_display_column(), 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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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 : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return ret; + } + + ctsvc_list_prepend(list, record); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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", CTS_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_ACCOUNT_ID1: + person->account_id1 = ctsvc_stmt_get_int(stmt, i); + break; + case CTSVC_PROPERTY_PERSON_ACCOUNT_ID2: + person->account_id2 = ctsvc_stmt_get_int(stmt, i); + break; + case CTSVC_PROPERTY_PERSON_ACCOUNT_ID3: + person->account_id3 = 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; + default: + break; + } + } + ctsvc_list_prepend(list, record); + } + cts_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 index 0000000..e86cca8 --- /dev/null +++ b/native/ctsvc_db_plugin_person_helper.c @@ -0,0 +1,477 @@ +/* + * 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_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", CTS_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_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_ACCOUNT_ID1: + person->account_id1 = ctsvc_stmt_get_int(stmt, i); + break; + case CTSVC_PROPERTY_PERSON_ACCOUNT_ID2: + person->account_id2 = ctsvc_stmt_get_int(stmt, i); + break; + case CTSVC_PROPERTY_PERSON_ACCOUNT_ID3: + person->account_id3 = 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); + 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", CTS_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->status = SAFE_STRDUP(temp); + + person->link_count = ctsvc_stmt_get_int(stmt, i++); + person->account_id1 = ctsvc_stmt_get_int(stmt, i++); + person->account_id2 = ctsvc_stmt_get_int(stmt, i++); + person->account_id3 = 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* __cts_get_image_filename(const char* src) +{ + const char* dir = CTS_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_insert_person(contacts_record_h record) +{ + int ret, index; + cts_stmt stmt = NULL; + char query[CTS_SQL_MIN_LEN] = {0}; + contacts_record_h addressbook; + int account_id, version; + ctsvc_contact_s *contact = (ctsvc_contact_s*)record; + char *status = NULL; + + ret = contacts_db_get_record(_contacts_address_book._uri, contact->addressbook_id, &addressbook); + if(CONTACTS_ERROR_NONE != ret) { + CTS_ERR("contacts_svc_get_addressbook() Failed\n"); + return CONTACTS_ERROR_DB; + } + contacts_record_get_int(addressbook, _contacts_address_book.account_id, &account_id); + contacts_record_destroy(addressbook, true); + + snprintf(query, sizeof(query), + "SELECT status FROM %s " + "WHERE contact_id=%d " + "ORDER BY timestamp DESC LIMIT 1", + CTS_TABLE_ACTIVITIES, contact->id); + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare() Failed(%d)", ret); + return CONTACTS_ERROR_DB; + } + + if (1 == cts_stmt_step(stmt)) + status = SAFE_STRDUP(ctsvc_stmt_get_text(stmt, 0)); + + sqlite3_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, status, " + "image_thumbnail_path, link_count, account_id1, addressbook_ids) " + "VALUES(%d, %d, %d, %d, %d, ?, ?, ?, ?, 1, %d, '%d') ", + contact->id, version, version, + contact->has_phonenumber, contact->has_email, account_id, contact->addressbook_id); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare() Failed(%d)", ret); + free(status); + return CONTACTS_ERROR_DB; + } + if(contact->ringtone_path) + cts_stmt_bind_text(stmt, 1, contact->ringtone_path); + if(contact->vibration) + cts_stmt_bind_text(stmt, 2, contact->vibration); + if(status) + cts_stmt_bind_text(stmt, 3, status); + if(contact->image_thumbnail_path) + cts_stmt_bind_text(stmt, 4, __cts_get_image_filename(contact->image_thumbnail_path)); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + free(status); + return ret; + } + index = cts_db_get_last_insert_id(); + + cts_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("cts_query_exec(%s) Failed(%d)", query, ret); + free(status); + 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}; + + 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); + + CTS_DBG("%s", query); + ret = ctsvc_query_get_first_int_result(query, &data_id); + if (CONTACTS_ERROR_NO_DATA == ret ) { + 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 D.is_default=1 AND D.is_my_profile = 0 ORDER BY D.id", + person_id, datatype); + + CTS_DBG("%s", query); + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare() Failed"); + return CONTACTS_ERROR_DB; + } + + if ((ret = cts_stmt_step(stmt))) + { + 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); + + CTS_DBG("%s", query); + ret = ctsvc_query_exec(query); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_query_exec(%s) Failed(%d)", query, ret); + cts_stmt_finalize(stmt); + return ret; + } + } + cts_stmt_finalize(stmt); + } + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_update_person(contacts_record_h record) +{ + int ret, i=1, contact_count=0, 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; + + ret = ctsvc_begin_trans(); + RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret); + + snprintf(query, sizeof(query), + "SELECT count(contact_id) FROM "CTS_TABLE_CONTACTS" " + "WHERE person_id=%d AND has_phonenumber=1 AND deleted = 0", + contact->person_id); + + ret = ctsvc_query_get_first_int_result(query, &contact_count); + if (CONTACTS_ERROR_NONE != ret ) { + CTS_ERR("No Contacts : person_id (%d)", contact->person_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_NO_DATA; + } + + if(contact_count) + has_phonenumber = true; + + snprintf(query, sizeof(query), + "SELECT count(contact_id) FROM "CTS_TABLE_CONTACTS" " + "WHERE person_id=%d AND has_email=1 AND deleted = 0", + contact->person_id); + + ret = ctsvc_query_get_first_int_result(query, &contact_count); + if (CONTACTS_ERROR_NONE != ret ) { + CTS_ERR("No Contacts : person_id (%d)", contact->person_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_NO_DATA; + } + + if(contact_count) + has_email = true; + + 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 (contact->ringtone_changed) + len += snprintf(query+len, sizeof(query)-len, ", ringtone_path=?"); + if (contact->vibration_changed) + len += snprintf(query+len, sizeof(query)-len, ", vibration=?"); + if (contact->image_thumbnail_changed) + len += snprintf(query+len, sizeof(query)-len, ", image_thumbnail_path=?"); + + snprintf(query+len, sizeof(query)-len, + " WHERE person_id=%d", contact->person_id); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare() Failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + if (contact->ringtone_changed) + cts_stmt_bind_text(stmt, i++, SAFE_STR(contact->ringtone_path)); + if (contact->vibration_changed) + cts_stmt_bind_text(stmt, i++, SAFE_STR(contact->vibration)); + if (contact->image_thumbnail_changed) + cts_stmt_bind_text(stmt, i++, SAFE_STR(contact->image_thumbnail_path)); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + + cts_stmt_finalize(stmt); + + __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); + + 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; +} + +void ctsvc_db_normalize_str_callback(sqlite3_context * context, + int argc, sqlite3_value ** argv) +{ + int ret; + const char *display_name; + char dest[CTS_SQL_MAX_LEN] = {0}; + + if (argc < 1) { + sqlite3_result_null(context); + return; + } + + display_name = (const char *)sqlite3_value_text(argv[0]); + if (display_name) { + ret = ctsvc_normalize_index(display_name, dest, sizeof(dest)); + if (ret < CONTACTS_ERROR_NONE) { + CTS_ERR("ctsvc_normalize_index() Failed(%d)", ret); + sqlite3_result_null(context); + return; + } + CTS_VERBOSE("normalize index : %s, %s", display_name, dest); + } + + + sqlite3_result_text(context, dest, strlen(dest), SQLITE_STATIC); + return; +} + diff --git a/native/ctsvc_db_plugin_person_helper.h b/native/ctsvc_db_plugin_person_helper.h new file mode 100755 index 0000000..15ff251 --- /dev/null +++ b/native/ctsvc_db_plugin_person_helper.h @@ -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_DB_PLUGIN_PERSON_HELPER_H__ +#define __CTSVC_DB_PLUGIN_PERSON_HELPER_H__ + +#include "contacts.h" +#include "ctsvc_sqlite.h" + +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); + +#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 index 0000000..b5bc50a --- /dev/null +++ b/native/ctsvc_db_plugin_phonelog.c @@ -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. + * + */ +#include <stdio.h> + +#include "contacts.h" +#include "ctsvc_internal.h" +#include "ctsvc_schema.h" +#include "ctsvc_sqlite.h" +#include "ctsvc_normalize.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 "badge.h" + +#ifdef _CONTACTS_IPC_SERVER +#include "ctsvc_server_change_subject.h" +#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); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_phonelog_get_record( int id, contacts_record_h* out_record ) +{ + int ret; + int len; + 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; + + len = snprintf(query, sizeof(query), + "SELECT id, number, person_id, log_type, log_time, data1, data2 " + "FROM "CTS_TABLE_PHONELOGS" WHERE id = %d", id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ret = __ctsvc_db_phonelog_value_set(stmt, &record); + + cts_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 ret; +// cts_stmt stmt; + char query[CTS_SQL_MIN_LEN] = {0}; + ctsvc_phonelog_s *phonelog = (ctsvc_phonelog_s *)record; + + RETVM_IF(NULL == record, CONTACTS_ERROR_INVALID_PARAMETER, "Invaild 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, + "Invaild parameter : the type is can not updated(%d)", phonelog->log_type); + + ret = ctsvc_begin_trans(); + RETVM_IF(ret, ret, "ctsvc_begin_trans() Failed(%d)", ret); + + snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_PHONELOGS" SET log_type = %d WHERE id = %d", + phonelog->log_type, phonelog->id); + + ret = ctsvc_query_exec(query); + if (CONTACTS_ERROR_NONE != ret ) { + CTS_ERR("DB error : ctsvc_query_exec() Failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + if (cts_db_change()) { + ctsvc_set_phonelog_noti(); + ctsvc_set_missed_call_noti(); +#ifdef _CONTACTS_IPC_SERVER + // add id for subscribe + ctsvc_change_subject_add_changed_phone_log_id(CONTACTS_CHANGE_UPDATED, phonelog->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; +} + +static int __ctsvc_db_phonelog_delete_record( int id ) +{ + int ret; + 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), "DELETE FROM %s WHERE id = %d", + CTS_TABLE_PHONELOGS, id); + + ret = ctsvc_query_exec(query); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_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 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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return CONTACTS_ERROR_NO_DATA; + } + __ctsvc_db_phonelog_value_set(stmt, &record); + + ctsvc_list_prepend(list, record); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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; + default: + break; + } + } + ctsvc_list_prepend(list, record); + } + + cts_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_cb_phonelog_increase_outgoing_count(int person_id) +{ + int ret; + int id; + char query[CTS_SQL_MIN_LEN] = {0}; + + snprintf(query, sizeof(query), + "SELECT person_id FROM %s WHERE person_id = %d and usage_type = %d ", + CTS_TABLE_CONTACT_STAT, person_id, CONTACTS_USAGE_STAT_TYPE_OUTGOING_CALL); + + 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, person_id, CONTACTS_USAGE_STAT_TYPE_OUTGOING_CALL); + } + 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, person_id, CONTACTS_USAGE_STAT_TYPE_OUTGOING_CALL); + } + + ret = ctsvc_query_exec(query); + RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "DB error : cts_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 clean_num[CTSVC_NUMBER_MAX_LEN] = {0}; + char query[CTS_SQL_MAX_LEN] = {0}; + char normal_num[CTSVC_NUMBER_MAX_LEN] = {0}; + + RETVM_IF(phonelog->log_type <= CONTACTS_PLOG_TYPE_NONE + || CONTACTS_PLOG_TYPE_MAX <= 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, person_id, log_type, log_time, data1, data2) " + "VALUES(?, ?, ?, %d, %d, %d, ?)", + phonelog->log_type, phonelog->log_time, phonelog->extra_data1); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + if (phonelog->address) { + cts_stmt_bind_text(stmt, 1, phonelog->address); + if (phonelog->log_type < CONTACTS_PLOG_TYPE_EMAIL_RECEIVED) { + ret = ctsvc_clean_number(phonelog->address, clean_num, sizeof(clean_num)); + if (0 < ret) { + ret = ctsvc_normalize_number(clean_num, normal_num, CTSVC_NUMBER_MAX_LEN); + cts_stmt_bind_text(stmt, 2, normal_num); + } + } + } + + if (0 < phonelog->person_id) + cts_stmt_bind_int(stmt, 3, phonelog->person_id); + + if (phonelog->extra_data2) + cts_stmt_bind_text(stmt, 4, phonelog->extra_data2); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) + { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + if (id) + *id = cts_db_get_last_insert_id(); + cts_stmt_finalize(stmt); + + if (CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN == phonelog->log_type || + CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN == phonelog->log_type) + ctsvc_set_missed_call_noti(); + + 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, "Invaild 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_cb_phonelog_increase_outgoing_count(phonelog->person_id); + WARN_IF(CONTACTS_ERROR_NONE != ret, "cts_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); + + // set missed call Badge number to Apptray + if(phonelog-> log_type == CONTACTS_PLOG_TYPE_VOICE_INCOMMING_UNSEEN || phonelog-> log_type == CONTACTS_PLOG_TYPE_VIDEO_INCOMMING_UNSEEN) { + + #define PHONE_PACKAGE_NAME "org.tizen.phone" + int call_cnt = 0; + bool bBadgeExist = FALSE; + + badge_is_existing(PHONE_PACKAGE_NAME, &bBadgeExist); + if(bBadgeExist == FALSE) + badge_create(PHONE_PACKAGE_NAME, PHONE_PACKAGE_NAME); + + badge_get_count(PHONE_PACKAGE_NAME, &call_cnt); + call_cnt++; + badge_set_count(PHONE_PACKAGE_NAME, call_cnt); + } + + + if (ret < CONTACTS_ERROR_NONE) + { + CTS_ERR("DB error : ctsvc_end_trans() Failed(%d)", ret); + return ret; + } + else + return CONTACTS_ERROR_NONE; +} + diff --git a/native/ctsvc_db_plugin_profile.c b/native/ctsvc_db_plugin_profile.c new file mode 100644 index 0000000..0b65642 --- /dev/null +++ b/native/ctsvc_db_plugin_profile.c @@ -0,0 +1,386 @@ +/* + * 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_profile_helper.h" +#include "ctsvc_record.h" +#include "ctsvc_db_query.h" +#include "ctsvc_list.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 contact_id; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_profile_s *profile = (ctsvc_profile_s *)record; + + RETVM_IF(NULL == profile->appsvc_operation, CONTACTS_ERROR_INVALID_PARAMETER, + "Invalid parameter : profile uid 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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", profile->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + 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_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; +} + +static int __ctsvc_db_profile_get_record( int id, contacts_record_h* out_record ) +{ + int ret; + int len; + cts_stmt stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER); + *out_record = NULL; + + 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 id = %d AND datatype = %d ", + id, CTSVC_DATA_PROFILE); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ctsvc_db_profile_get_value_from_stmt(stmt, out_record, 0); + + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_profile_update_record( contacts_record_h record ) +{ + int ret; + int contact_id; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_profile_s *profile = (ctsvc_profile_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", profile->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + ret = ctsvc_db_profile_update(record, profile->contact_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(profile->contact_id); + 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; +} + +static int __ctsvc_db_profile_delete_record( int id ) +{ + int ret; + int contact_id; + 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 FROM "CTSVC_DB_VIEW_CONTACT " " + "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if( ret != CONTACTS_ERROR_NONE ) { + CTS_ERR("The id(%d) is Invalid(%d)", id, ret); + ctsvc_end_trans(false); + return contact_id; + } + + ret = ctsvc_db_profile_delete(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(contact_id); + 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; +} + +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 " + "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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB : cts_stmt_step fail(%d)", ret); + cts_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); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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_TYPE: + profile->type = ctsvc_stmt_get_int(stmt, i); + break; + case CTSVC_PROPERTY_PROFILE_LABEL: + temp = ctsvc_stmt_get_text(stmt, i); + profile->label = SAFE_STRDUP(temp); + 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_APPSVC_OPERATION: + temp = ctsvc_stmt_get_text(stmt, i); + profile->appsvc_operation = SAFE_STRDUP(temp); + break; + case CTSVC_PROPERTY_PROFILE_DATA1: + temp = ctsvc_stmt_get_text(stmt, i); + profile->data1 = SAFE_STRDUP(temp); + break; + case CTSVC_PROPERTY_PROFILE_DATA2: + temp = ctsvc_stmt_get_text(stmt, i); + profile->data2 = SAFE_STRDUP(temp); + break; + case CTSVC_PROPERTY_PROFILE_DATA3: + temp = ctsvc_stmt_get_text(stmt, i); + profile->data3 = SAFE_STRDUP(temp); + break; + case CTSVC_PROPERTY_PROFILE_DATA4: + temp = ctsvc_stmt_get_text(stmt, i); + profile->data4 = SAFE_STRDUP(temp); + break; + default: + break; + } + } + ctsvc_list_prepend(list, record); + } + cts_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 index 0000000..083de56 --- /dev/null +++ b/native/ctsvc_db_plugin_profile_helper.c @@ -0,0 +1,178 @@ +/* + * 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_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++; + temp = ctsvc_stmt_get_text(stmt, start_count++); + profile->label = SAFE_STRDUP(temp); + 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->appsvc_operation = SAFE_STRDUP(temp); + temp = ctsvc_stmt_get_text(stmt, start_count++); + profile->data1 = SAFE_STRDUP(temp); + temp = ctsvc_stmt_get_text(stmt, start_count++); + profile->data2 = SAFE_STRDUP(temp); + temp = ctsvc_stmt_get_text(stmt, start_count++); + profile->data3 = SAFE_STRDUP(temp); + temp = ctsvc_stmt_get_text(stmt, start_count++); + profile->data4 = 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->label) + cts_stmt_bind_text(stmt, start_cnt, profile->label); + if (profile->uid) + cts_stmt_bind_text(stmt, start_cnt+1, profile->uid); + if (profile->text) + cts_stmt_bind_text(stmt, start_cnt+2, profile->text); + cts_stmt_bind_int(stmt, start_cnt+3, profile->order); + if (profile->appsvc_operation) + cts_stmt_bind_text(stmt, start_cnt+4, profile->appsvc_operation); + if (profile->data1) + cts_stmt_bind_text(stmt, start_cnt+5, profile->data1); + if (profile->data2) + cts_stmt_bind_text(stmt, start_cnt+6, profile->data2); + if (profile->data3) + cts_stmt_bind_text(stmt, start_cnt+7, profile->data3); + if (profile->data4) + cts_stmt_bind_text(stmt, start_cnt+8, profile->data4); + 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; + +// RETVM_IF(profile->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted profile record"); + RETV_IF(NULL == profile->appsvc_operation, 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, data1, data2, data3, data4, data5, " + "data6, data7, data8, data9, data10) " + "VALUES(%d, %d, %d, %d, ?, ?, ?, ?, ?, ?, ?, ?, ?)", + contact_id, is_my_profile, CTSVC_DATA_PROFILE, profile->type); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + __ctsvc_profile_bind_stmt(stmt, profile, 1); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + //profile->id = cts_db_get_last_insert_id(); + if (id) + *id = cts_db_get_last_insert_id(); + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_profile_noti(); + + return CONTACTS_ERROR_NONE; + +} + +int ctsvc_db_profile_update(contacts_record_h record, int contact_id, bool is_my_profile) +{ + int ret; + ctsvc_profile_s *profile = (ctsvc_profile_s*)record; + char query[CTS_SQL_MAX_LEN] = {0}; + cts_stmt stmt; + + RETVM_IF(!profile->id, CONTACTS_ERROR_INVALID_PARAMETER, "profile of contact has no ID."); + + snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_DATA" SET contact_id=%d, is_my_profile=%d, data1=%d, data2=?, data3=?, data4=?, data5=?, " + "data6=?, data7=?, data8=?, data9=?, data10=?, data11=?, data12=? WHERE id=%d", + contact_id, is_my_profile, profile->type, profile->id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + __ctsvc_profile_bind_stmt(stmt, profile, 1); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_profile_noti(); + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_profile_delete(int id) +{ + 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); + 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 index 0000000..0b93afd --- /dev/null +++ b/native/ctsvc_db_plugin_profile_helper.h @@ -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_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, int contact_id, bool is_my_profile); +int ctsvc_db_profile_delete(int id); + +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 index 0000000..cbffc51 --- /dev/null +++ b/native/ctsvc_db_plugin_relationship.c @@ -0,0 +1,357 @@ +/* + * 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_relationship_helper.h" +#include "ctsvc_db_plugin_contact_helper.h" +#include "ctsvc_record.h" +#include "ctsvc_db_query.h" +#include "ctsvc_list.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 contact_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", relationship->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + 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_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; +} + +static int __ctsvc_db_relationship_get_record( int id, contacts_record_h* out_record ) +{ + int ret; + int len; + cts_stmt stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER); + *out_record = NULL; + + 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 id = %d AND datatype = %d ", + id, CTSVC_DATA_RELATIONSHIP); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ctsvc_db_relationship_get_value_from_stmt(stmt, out_record, 0); + + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_relationship_update_record( contacts_record_h record ) +{ + int ret; + int contact_id; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_relationship_s *relationship = (ctsvc_relationship_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", relationship->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + ret = ctsvc_db_relationship_update(record, relationship->contact_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(relationship->contact_id); + 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; +} + +static int __ctsvc_db_relationship_delete_record( int id ) +{ + int ret; + int contact_id; + 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 FROM "CTSVC_DB_VIEW_CONTACT " " + "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if( ret != CONTACTS_ERROR_NONE ) { + CTS_ERR("The id(%d) is Invalid(%d)", id, ret); + ctsvc_end_trans(false); + return contact_id; + } + + ret = ctsvc_db_relationship_delete(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(contact_id); + 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; +} + +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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB : cts_stmt_step fail(%d)", ret); + cts_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); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + } + cts_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 index 0000000..1186fa2 --- /dev/null +++ b/native/ctsvc_db_plugin_relationship_helper.c @@ -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_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) + cts_stmt_bind_text(stmt, start_cnt, relationship->label); + if (relationship->name) + cts_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 +// RETVM_IF(relationship->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted relationship record"); + 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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + __ctsvc_relationship_bind_stmt(stmt, relationship, 1); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + //relationship->id = cts_db_get_last_insert_id(); + if (id) + *id = cts_db_get_last_insert_id(); + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_relationship_noti(); + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_relationship_update(contacts_record_h record, int contact_id, bool is_my_profile) +{ + int ret; + ctsvc_relationship_s *relationship = (ctsvc_relationship_s*)record; + char query[CTS_SQL_MAX_LEN] = {0}; + cts_stmt stmt; + + RETVM_IF(!relationship->id, CONTACTS_ERROR_INVALID_PARAMETER, "relationship of contact has no ID."); + + snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_DATA" SET contact_id=%d, is_my_profile=%d, data1=%d, data2=?, data3=? WHERE id=%d", + contact_id, is_my_profile, relationship->type, relationship->id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + __ctsvc_relationship_bind_stmt(stmt, relationship, 1); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_relationship_noti(); + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_relationship_delete(int id) +{ + 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); + 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 index 0000000..c112431 --- /dev/null +++ b/native/ctsvc_db_plugin_relationship_helper.h @@ -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_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, int contact_id, bool is_my_profile); +int ctsvc_db_relationship_delete(int id); + +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 index 0000000..409c7d2 --- /dev/null +++ b/native/ctsvc_db_plugin_sdn.c @@ -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_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" + +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 = __ctsvc_db_sdn_insert_record, + .get_record = __ctsvc_db_sdn_get_record, + .update_record = __ctsvc_db_sdn_update_record, + .delete_record = __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); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_sdn_get_record( int id, contacts_record_h* out_record ) +{ + int ret; + int len; + 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; + + len = snprintf(query, sizeof(query), + "SELECT id, name, number FROM "CTS_TABLE_SDN" WHERE id = %d", id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ret = __ctsvc_db_sdn_value_set(stmt, &record); + + cts_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; +} + + +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) VALUES(?, ?)"); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("DB error : cts_query_prepare() Failed"); + return CONTACTS_ERROR_DB; + } + + cts_stmt_bind_text(stmt, 1, sdn->name); + cts_stmt_bind_text(stmt, 2, sdn->number); + + ret = ctsvc_begin_trans(); + if( ret < CONTACTS_ERROR_NONE ) { + CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + + //sdn->id = cts_db_get_last_insert_id(); + if (id) + *id = cts_db_get_last_insert_id(); + cts_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 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_MIN_LEN] = {0}; + + snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_SDN" SET name=?, number=? WHERE id = %d", sdn->id); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("DB error : cts_query_prepare() Failed"); + return CONTACTS_ERROR_DB; + } + + cts_stmt_bind_text(stmt, 1, sdn->name); + cts_stmt_bind_text(stmt, 2, sdn->number); + + ret = ctsvc_begin_trans(); + if( ret < CONTACTS_ERROR_NONE ) { + CTS_ERR("DB error : ctsvc_begin_trans() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + + cts_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_delete_record( int sdn_id ) +{ + int ret; + + char query[CTS_SQL_MAX_LEN] = {0}; + snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_SDN" WHERE id = %d", sdn_id); + + ret = ctsvc_begin_trans(); + RETVM_IF(CONTACTS_ERROR_NONE > 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 = cts_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; +} + +static int __ctsvc_db_sdn_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, name, number 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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return CONTACTS_ERROR_NO_DATA; + } + __ctsvc_db_sdn_value_set(stmt, &record); + + ctsvc_list_prepend(list, record); + } + cts_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 ) +{ + 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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return CONTACTS_ERROR_NO_DATA; + } + + 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; + default: + break; + } + } + ctsvc_list_prepend(list, record); + } + cts_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 diff --git a/native/ctsvc_db_plugin_sdn.h b/native/ctsvc_db_plugin_sdn.h new file mode 100644 index 0000000..0b29b7d --- /dev/null +++ b/native/ctsvc_db_plugin_sdn.h @@ -0,0 +1,24 @@ +/* + * 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_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 index 0000000..e68f4d7 --- /dev/null +++ b/native/ctsvc_db_plugin_simple_contact.c @@ -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. + * + */ +#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" + +static int __ctsvc_db_simple_contact_insert_record( contacts_record_h record, int *id ); +static int __ctsvc_db_simple_contact_get_record( int id, contacts_record_h* out_record ); +static int __ctsvc_db_simple_contact_update_record( contacts_record_h record ); +static int __ctsvc_db_simple_contact_delete_record( int id ); +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 = __ctsvc_db_simple_contact_insert_record, + .get_record = __ctsvc_db_simple_contact_get_record, + .update_record = __ctsvc_db_simple_contact_update_record, + .delete_record = __ctsvc_db_simple_contact_delete_record, + .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", CTS_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->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; + int len; + 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; +// if (0 == id) +// return ctsvc_get_myprofile(contact); + + len = snprintf(query, sizeof(query), + "SELECT contact_id, addressbook_id, person_id, changed_time, %s, " + "display_name_source, image_thumbnail_path, " + "ringtone_path, vibration, uid, is_favorite, has_phonenumber, has_email " + "FROM "CTS_TABLE_CONTACTS" WHERE contact_id = %d AND deleted = 0", + ctsvc_get_display_column(), id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ret = __ctsvc_db_simple_contact_value_set(stmt, &record); + + cts_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_update_record( contacts_record_h record ) +{ + int ret; + int len; + int i; + int id; + char query[CTS_SQL_MAX_LEN] = {0}; + char image[CTS_SQL_MAX_LEN] = {0}; + ctsvc_simple_contact_s *contact = (ctsvc_simple_contact_s*)record; + cts_stmt stmt; + + // These check should be done in client side +// RETVM_IF(contact->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted contact record"); + 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(contact->contact_id < 0, CONTACTS_ERROR_INVALID_PARAMETER, + "Invalid parameter : ide(%d), This record is already inserted", contact->contact_id); + + ret = ctsvc_begin_trans(); + RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_begin_trans() Failed(%d)", ret); + + snprintf(query, sizeof(query), + "SELECT contact_id FROM "CTS_TABLE_CONTACTS" " + "WHERE contact_id = %d AND deleted = 0", contact->contact_id); + ret = ctsvc_query_get_first_int_result(query, &id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("Invalid Parameter : contact_id (%d) is not exist", contact->contact_id); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + len = snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_CONTACTS" SET changed_ver=%d, changed_time=%d ", + ctsvc_get_next_ver(), (int)time(NULL)); + + if (contact->uid_changed) + len += snprintf(query+len, sizeof(query)-len, ", uid=?"); + + if (contact->ringtone_changed) + len += snprintf(query+len, sizeof(query)-len, ", ringtone_path=?"); + + if (contact->vibration_changed) + len += snprintf(query+len, sizeof(query)-len, ", vibration=?"); + + if (contact->image_thumbnail_changed) + len += snprintf(query+len, sizeof(query)-len, ", image_thumbnail_path=?"); + + len += snprintf(query+len, sizeof(query)-len, " WHERE contact_id=%d", contact->contact_id); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare() Failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + i = 0; + if (contact->uid_changed) { + if(contact->uid) + cts_stmt_bind_text(stmt, i++, contact->uid); + i++; + } + if (contact->ringtone_changed) { + if (contact->ringtone_path) + cts_stmt_bind_text(stmt, i, contact->ringtone_path); + i++; + } + if (contact->vibration_changed) { + if (contact->vibration) + cts_stmt_bind_text(stmt, i, contact->vibration); + i++; + } + + if (contact->image_thumbnail_changed) { + image[0] = '\0'; + ret = ctsvc_contact_update_image_file(CTSVC_IMG_NORMAL, contact->contact_id, + contact->image_thumbnail_path, image, sizeof(image)); + + if (*image) { + free(contact->image_thumbnail_path); + contact->image_thumbnail_path = strdup(image); + if (CONTACTS_ERROR_NONE == ret && contact->image_thumbnail_path) + cts_stmt_bind_text(stmt, i, contact->image_thumbnail_path); + } + i++; + } + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + cts_stmt_finalize(stmt); + + ctsvc_set_contact_noti(); + //ctsvc_update_person(contact); + 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_simple_contact_delete_record( int id ) +{ + int ret; + 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), "DELETE FROM %s WHERE contact_id = %d AND deleted = 0", + CTS_TABLE_CONTACTS, id); + + ret = ctsvc_query_exec(query); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_query_exec() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + + ctsvc_set_contact_noti(); + ret = ctsvc_end_trans(true); + if (ret < CONTACTS_ERROR_NONE) + return ret; + else + 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, 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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return ret; + } + __ctsvc_db_simple_contact_value_set(stmt, &record); + + ctsvc_list_prepend(list, record); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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", CTS_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_CHANGED_TIME: + contact->changed_time = ctsvc_stmt_get_int(stmt, i); + break; + default: + break; + } + } + ctsvc_list_prepend(list, record); + } + cts_stmt_finalize(stmt); + ctsvc_list_reverse(list); + + *out_list = (contacts_list_h)list; + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_simple_contact_insert_record( contacts_record_h record, int *id) +{ + int version; + int ret; + char query[CTS_SQL_MAX_LEN] = {0}; + char image[CTS_SQL_MAX_LEN] = {0}; + ctsvc_simple_contact_s *contact = (ctsvc_simple_contact_s*)record; + cts_stmt stmt; + + // These check should be done in client side +// RETVM_IF(contact->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted contact record"); + 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->contact_id, CONTACTS_ERROR_INVALID_PARAMETER, +// "Invalid parameter : ide(%d), This record is already inserted", contact->contact_id); + + ret = ctsvc_begin_trans(); + RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_begin_trans() Failed(%d)", ret); + + ret = cts_db_get_next_id(CTS_TABLE_CONTACTS); + if (ret < CONTACTS_ERROR_NONE) { + CTS_ERR("cts_db_get_next_id() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + contact->contact_id = ret; + if (id) + *id = ret; + + if (contact->image_thumbnail_path) { + image[0] = '\0'; + ret = ctsvc_contact_add_image_file(CTSVC_IMG_NORMAL, contact->contact_id, contact->image_thumbnail_path, + image, sizeof(image)); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("ctsvc_contact_add_image_file(NORMAL) Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + free(contact->image_thumbnail_path); + contact->image_thumbnail_path = strdup(image); + } + + version = ctsvc_get_next_ver(); + + ret = ctsvc_db_insert_person((contacts_record_h)contact); + 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_restricted, " + "created_ver, changed_ver, changed_time, " + "uid, ringtone_path, vibration, image_thumbnail_path) " + "VALUES(%d, %d, %d, %d, %d, %d, %d, ?, ?, ?, ?)", + contact->contact_id, contact->person_id, contact->addressbook_id, contact->is_restricted, + version, version, (int)time(NULL)); + + stmt = cts_query_prepare(query); + if(NULL == stmt){ + CTS_ERR("cts_query_prepare() Failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + if (contact->uid) + cts_stmt_bind_text(stmt, 1, contact->uid); + if (contact->ringtone_path) + cts_stmt_bind_text(stmt, 2, contact->ringtone_path); + if (contact->vibration) + cts_stmt_bind_text(stmt, 3, contact->vibration); + if (contact->image_thumbnail_path) + cts_stmt_bind_text(stmt, 4, contact->image_thumbnail_path); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + cts_stmt_finalize(stmt); + + 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_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 index 0000000..13bec0b --- /dev/null +++ b/native/ctsvc_db_plugin_speeddial.c @@ -0,0 +1,400 @@ +/* + * 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; + 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); + + 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 = cts_db_change(); + if (0 < ret) { + if (id) + *id = cts_db_get_last_insert_id(); + 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", CTS_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++); + + 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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + ret = __ctsvc_db_speeddial_value_set(stmt, &record); + + cts_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; + 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, + "Invaild parameter : dial number (%d)", speeddial->dial_number); + RETVM_IF (speeddial->number_id < 0, CONTACTS_ERROR_INVALID_PARAMETER, + "Invaild parameter : number id (%d)", speeddial->number_id); + + snprintf(query, sizeof(query), "UPDATE "CTS_TABLE_SPEEDDIALS" " + "SET number_id = %d WHERE speed_number = %d", + speeddial->number_id, speeddial->dial_number); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = ctsvc_begin_trans(); + if (ret) { + cts_stmt_finalize(stmt); + CTS_ERR("contacts_svc_begin_trans() Failed(%d)", ret); + return ret; + } + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + ret = cts_db_change(); + cts_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; + cts_stmt stmt; + char query[CTS_SQL_MIN_LEN] = {0}; + + snprintf(query, sizeof(query), "DELETE FROM %s WHERE speed_number = %d", + CTS_TABLE_SPEEDDIALS, id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = ctsvc_begin_trans(); + if (ret) { + cts_stmt_finalize(stmt); + CTS_ERR("ctsvc_begin_trans() Failed(%d)", ret); + return ret; + } + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + ctsvc_end_trans(false); + return ret; + } + ret = cts_db_change(); + cts_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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return ret; + } + __ctsvc_db_speeddial_value_set(stmt, &record); + + ctsvc_list_prepend(list, record); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + 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", CTS_IMG_FULL_LOCATION, temp); + speeddial->image_thumbnail_path = strdup(full_path); + } + break; + default: + break; + } + } + ctsvc_list_prepend(list, record); + } + cts_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 index 0000000..ae798b6 --- /dev/null +++ b/native/ctsvc_db_plugin_url.c @@ -0,0 +1,365 @@ +/* + * 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" + +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 contact_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", url->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + 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; + } + + snprintf(query, sizeof(query), + "SELECT contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", url->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + ret = ctsvc_db_contact_update_changed_time(url->contact_id); + 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; +} + +static int __ctsvc_db_url_get_record( int id, contacts_record_h* out_record ) +{ + int ret; + int len; + cts_stmt stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + RETV_IF(NULL == out_record, CONTACTS_ERROR_INVALID_PARAMETER); + *out_record = NULL; + + 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 id = %d AND datatype = %d ", + id, CTSVC_DATA_URL); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return CONTACTS_ERROR_NO_DATA; + } + + ctsvc_db_url_get_value_from_stmt(stmt, out_record, 0); + + cts_stmt_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_url_update_record( contacts_record_h record ) +{ + int ret; + int contact_id; + char query[CTS_SQL_MAX_LEN] = {0}; + ctsvc_url_s *url = (ctsvc_url_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 contact_id FROM "CTSVC_DB_VIEW_CONTACT" WHERE contact_id = %d", url->contact_id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("No data : contact_id (%d) is not exist", contact_id); + ctsvc_end_trans(false); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + ret = ctsvc_db_url_update(record, url->contact_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(url->contact_id); + 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; +} + +static int __ctsvc_db_url_delete_record( int id ) +{ + int ret; + int contact_id; + 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 FROM "CTSVC_DB_VIEW_CONTACT " " + "WHERE contact_id = (SELECT contact_id FROM "CTS_TABLE_DATA" WHERE id = %d)", id); + ret = ctsvc_query_get_first_int_result(query, &contact_id); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("The id(%d) is Invalid(%d)", id, ret); + ctsvc_end_trans(false); + return contact_id; + } + + ret = ctsvc_db_url_delete(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(contact_id); + 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; +} + +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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB : cts_stmt_step fail(%d)", ret); + cts_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); + } + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 /*CTS_TRUE */ != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + } + cts_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 index 0000000..eaff3fe --- /dev/null +++ b/native/ctsvc_db_plugin_url_helper.c @@ -0,0 +1,147 @@ +/* + * 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_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; + +// RETVM_IF(url->deleted, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid parameter : deleted url 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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + if (url->label) + cts_stmt_bind_text(stmt, 1, url->label); + if (url->url) + cts_stmt_bind_text(stmt, 2, url->url); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("DB error : ctsvc_query_exec() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + //url->id = cts_db_get_last_insert_id(); + if (id) + *id = cts_db_get_last_insert_id(); + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_url_noti(); + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_url_update(contacts_record_h record, int contact_id, bool is_my_profile) +{ + int ret; + ctsvc_url_s *url = (ctsvc_url_s*)record; + char query[CTS_SQL_MAX_LEN] = {0}; + cts_stmt stmt; + + RETVM_IF(!url->id, CONTACTS_ERROR_INVALID_PARAMETER, "url of contact has no ID."); + + snprintf(query, sizeof(query), + "UPDATE "CTS_TABLE_DATA" SET contact_id=%d, is_my_profile=%d, data1=%d, data2=?, data3=? WHERE id=%d", + contact_id, is_my_profile, url->type, url->id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + if (url->label) + cts_stmt_bind_text(stmt, 1, url->label); + if (url->url) + cts_stmt_bind_text(stmt, 2, url->url); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + return ret; + } + + cts_stmt_finalize(stmt); + + if (!is_my_profile) + ctsvc_set_url_noti(); + return CONTACTS_ERROR_NONE; +} + +int ctsvc_db_url_delete(int id) +{ + 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); + ctsvc_set_url_noti(); + + return CONTACTS_ERROR_NONE; +} + diff --git a/native/ctsvc_db_plugin_url_helper.h b/native/ctsvc_db_plugin_url_helper.h new file mode 100644 index 0000000..1e06795 --- /dev/null +++ b/native/ctsvc_db_plugin_url_helper.h @@ -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_URL_HELPER_H__ +#define __CTSVC_DB_PLUGIN_URL_HELPER_H__ + +#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, int contact_id, bool is_my_profile); +int ctsvc_db_url_delete(int id); + +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 index 0000000..11a57d7 --- /dev/null +++ b/native/ctsvc_db_query.c @@ -0,0 +1,2119 @@ +/* + * 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_sqlite.h" +#include "ctsvc_schema.h" +#include "ctsvc_list.h" +#include "ctsvc_record.h" +#include "ctsvc_utils.h" +#include "ctsvc_normalize.h" +#include "ctsvc_restriction.h" +#include "ctsvc_db_init.h" +#include "ctsvc_view.h" +#include "ctsvc_inotify.h" + +#include "ctsvc_db_plugin_person_helper.h" + +typedef enum { + QUERY_SORTKEY, + QUERY_FILTER, + QUERY_PROJECTION, +}db_query_property_type_e; + +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; +} + +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 p->type; + } + } + 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); + + 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; +} + +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}; + + *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); + + if (filter->property_id == CTSVC_PROPERTY_NUMBER_NUMBER_FILTER) + filter->match = CONTACTS_MATCH_EXACTLY; + + switch(filter->match) { + case CONTACTS_MATCH_EXACTLY: + snprintf(out_cond, sizeof(out_cond), "%s = ?", field_name); + break; + case CONTACTS_MATCH_FULLSTRING: + snprintf(out_cond, sizeof(out_cond), "%s LIKE ?", field_name); + break; + case CONTACTS_MATCH_CONTAINS: + snprintf(out_cond, sizeof(out_cond), "%s LIKE ('%%' || ? || '%%')", field_name); + break; + case CONTACTS_MATCH_STARTSWITH: + snprintf(out_cond, sizeof(out_cond), "%s LIKE ( ? || '%%')", field_name); + break; + case CONTACTS_MATCH_ENDSWITH: + snprintf(out_cond, sizeof(out_cond), "%s LIKE ('%%' || ?)", field_name); + break; + case CONTACTS_MATCH_EXISTS: + 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", filter->match); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + if (filter->value.s) { + if (filter->property_id == CTSVC_PROPERTY_NUMBER_NUMBER_FILTER) { + char dest[strlen(filter->value.s)+1]; + ret = ctsvc_normalize_number(filter->value.s, dest, sizeof(dest)); + if (CONTACTS_ERROR_NONE == ret) + *bind_text = g_slist_append(*bind_text, strdup(dest)); + else + return CONTACTS_ERROR_INVALID_PARAMETER; + } + else + *bind_text = g_slist_append(*bind_text, strdup(filter->value.s)); + } + *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; +} + +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; + char *cond, out_cond[CTS_SQL_MAX_LEN] = {0}; + 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; + + RETV_IF(NULL == filters, CONTACTS_ERROR_INVALID_PARAMETER); + + 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); + + cursor_filter = filters->next; + + len = 0; + len = snprintf(out_cond, sizeof(out_cond), "(%s)", cond); + free(cond); + + 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) + len += snprintf(out_cond+len, sizeof(out_cond)-len, " AND (%s)", cond); + else + len += snprintf(out_cond+len, sizeof(out_cond)-len, " OR (%s)", cond); + if (bind) + *bind_text = g_slist_concat(*bind_text, bind); + free(cond); + } + } + *condition = strdup(out_cond); + + return CONTACTS_ERROR_NONE; +} + +static int __ctsvc_db_create_projection(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_display_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 { + for (i=0;i<ids_count;i++) { + if (CTSVC_VIEW_DATA_TYPE_REC == properties[i].type) + 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_display_column()); + field_name = temp; + CTS_DBG("field_name : %s", field_name); + } + 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; + if (0 == strcmp(view_uri, _contacts_person_phone_log._uri)) + return false; + + 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; +} + +int ctsvc_db_make_get_records_query_stmt(ctsvc_query_s *s_query, int offset, int limit, cts_stmt *stmt) +{ + char query[CTS_SQL_MAX_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->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(%s)", ret); + return ret; + } + + if (s_query->distinct) + len = snprintf(query, sizeof(query), "SELECT DISTINCT %s FROM %s", projection, table); + else + len = snprintf(query, sizeof(query), "SELECT %s FROM %s", projection, table); + + 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) + len += snprintf(query+len, sizeof(query)-len, " WHERE %s", condition); + } + + 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: + len += snprintf(query+len, sizeof(query)-len, " ORDER BY %s %s", sortkey, s_query->sort_asc?"":"DESC"); + 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) { + len += snprintf(query+len, sizeof(query)-len, " ORDER BY %s", field_name); +// if (sortkey) +// len += snprintf(query+len, sizeof(query)-len, ", %s", sortkey); + if (false == s_query->sort_asc) + len += snprintf(query+len, sizeof(query)-len, " DESC"); + } + else if (sortkey) + len += snprintf(query+len, sizeof(query)-len, " ORDER BY %s", sortkey); + break; + } + } + else if (sortkey) + len += snprintf(query+len, sizeof(query)-len, " ORDER BY %s", sortkey); + + 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); + } + + free(condition); + free(projection); + + CTS_DBG("query : %s", query); + *stmt = cts_query_prepare(query); + if(NULL == *stmt) { + CTS_ERR("DB error : cts_query_prepare() Failed"); + for (cursor=bind_text;cursor;cursor=cursor->next) + free(cursor->data); + g_slist_free(bind_text); + return CONTACTS_ERROR_DB; + } + + for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++) + cts_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 = cts_stmt_step(stmt))) { + contacts_record_h record; + int field_count; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + } + cts_stmt_finalize(stmt); + ctsvc_list_reverse(list); + + *out_list = (contacts_list_h)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; + ctsvc_record_type_e r_type; + 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 %s", projection, 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); + } + + 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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + r_type = ctsvc_view_get_record_type(view_uri); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return CONTACTS_ERROR_NO_DATA; + } + + contacts_record_create(view_uri, &record); + for(i=0;i<ids_count;i++) { + type = properties[i].type; + 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); + } + cts_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(p, count, NULL, 0, &projection); + RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_db_create_projection is failed(%s)", 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_GROUP)) { + return true; + } + return false; +} + +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, 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; + ctsvc_record_type_e r_type; + char remake_val[CTS_SQL_MIN_LEN] = {0}; + 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); + + ret = ctsvc_normalize_str(keyword, remake_val, sizeof(remake_val)); + + if (CONTACTS_ERROR_NONE <= ret) { + if (0 == strcmp(view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_CONTACT) + || 0 == strcmp(view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP)) { + len = snprintf(query, sizeof(query), "SELECT %s FROM %s, %s " + "ON %s.contact_id = %s.contact_id " + "WHERE (%s MATCH 'name:%s* OR number:%s* OR data:%s*') ", + projection, table, CTS_TABLE_SEARCH_INDEX, + table, CTS_TABLE_SEARCH_INDEX, + CTS_TABLE_SEARCH_INDEX, remake_val, keyword, keyword); + } + else { // CTSVC_VIEW_URI_PERSON + len = snprintf(query, sizeof(query), "SELECT %s FROM %s, " + "(SELECT person_id person_id_in_contact " + "FROM "CTS_TABLE_CONTACTS", "CTS_TABLE_SEARCH_INDEX" " + "ON contacts.contact_id = search_index.contact_id AND deleted = 0 " + "WHERE ("CTS_TABLE_SEARCH_INDEX" MATCH 'name:%s* OR number:%s* OR data:%s*') " + "GROUP BY person_id_in_contact) temp_contacts " + "ON %s.person_id = temp_contacts.person_id_in_contact", + projection, table, remake_val, keyword, keyword, table); + + } +/* + len += snprintf(query+len, sizeof(query)-len, "FROM %s, %s " + "LEFT JOIN (SELECT contact_id, person_id person_id_in_contact FROM %s) temp_contacts " + "ON %s.person_id = temp_contacts.person_id_in_contact AND " + "temp_contacts.contact_id = %s.contact_id", + table, CTS_TABLE_SEARCH_INDEX, CTS_TABLE_CONTACTS, table, CTS_TABLE_SEARCH_INDEX); +*/ + + } + else { + if (0 == strcmp(view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_CONTACT) + || 0 == strcmp(view_uri, CTSVC_VIEW_URI_READ_ONLY_PERSON_GROUP)) { + len = snprintf(query, sizeof(query), "SELECT %s FROM %s, %s " + "ON %s.contact_id = %s.contact_id " + "WHERE (%s MATCH 'name:%s* OR number:%s* OR data:%s*') ", + projection, table, CTS_TABLE_SEARCH_INDEX, + table, CTS_TABLE_SEARCH_INDEX, + CTS_TABLE_SEARCH_INDEX, keyword, keyword, keyword); + } + else { // CTSVC_VIEW_URI_PERSON + len = snprintf(query, sizeof(query), + "SELECT %s FROM %s, "CTS_TABLE_SEARCH_INDEX", " + "(SELECT contact_id, person_id person_id_in_contact FROM "CTS_TABLE_CONTACTS") temp_contacts " + "ON %s.person_id = temp_contacts.person_id_in_contact " + "AND temp_contacts.contact_id = "CTS_TABLE_SEARCH_INDEX".contact_id " + "AND temp_contacts.deleted = 0 " + "WHERE ("CTS_TABLE_SEARCH_INDEX" MATCH 'name:%s* OR number:%s* OR data:%s*') ", + projection, table, table, keyword, keyword, keyword); + } + } + + 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); + } + + 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); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + +/* + sqlite3_bind_text(stmt, 1, keyword, strlen(keyword), SQLITE_STATIC); + if (CONTACTS_ERROR_NONE <= ret) + sqlite3_bind_text(stmt, 2, remake_val, strlen(remake_val), SQLITE_STATIC); +*/ + + r_type = ctsvc_view_get_record_type(view_uri); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return CONTACTS_ERROR_NO_DATA; + } + + if( r_type == CTSVC_RECORD_PERSON ) + { + unsigned int *project = malloc(sizeof(unsigned int)*ids_count); + int i; + 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].type; + 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); + } + cts_stmt_finalize(stmt); + ctsvc_list_reverse(list); + *out_list = (contacts_list_h)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; + + 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(p, count, NULL, 0, &projection); + RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_db_create_projection is failed(%s)", ret); + + __ctsvc_db_search_records_exec(view_uri, p, count, projection, keyword, offset, limit, out_list); + free(projection); + + return CONTACTS_ERROR_NONE; +} + +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[CTS_SQL_MAX_LEN] = {0}; + 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; + char remake_val[CTS_SQL_MIN_LEN] = {0}; + + 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); + + if (s_query->distinct) + len = snprintf(query, sizeof(query), "SELECT DISTINCT %s ", projection); + else + len = snprintf(query, sizeof(query), "SELECT %s ", projection); + + 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)) { + len += snprintf(query+len, sizeof(query)-len, "FROM %s, %s " + "ON %s.contact_id = %s.contact_id ", + table, CTS_TABLE_SEARCH_INDEX, + table, CTS_TABLE_SEARCH_INDEX); + } + else { // CTSVC_VIEW_URI_PERSON + len += snprintf(query+len, sizeof(query)-len, "FROM %s, %s, " + "(SELECT contact_id, person_id person_id_in_contact FROM %s WHERE deleted = 0) temp_contacts " + "ON %s.person_id = temp_contacts.person_id_in_contact " + "AND temp_contacts.contact_id = %s.contact_id", + table, CTS_TABLE_SEARCH_INDEX, CTS_TABLE_CONTACTS, table, CTS_TABLE_SEARCH_INDEX); + } +/* len += snprintf(query+len, sizeof(query)-len, "FROM %s, "CTS_TABLE_SEARCH_INDEX" " + "ON %s.contact_id = "CTS_TABLE_SEARCH_INDEX".contact_id", table, table);*/ + + ret = ctsvc_normalize_str(keyword, remake_val, sizeof(remake_val)); + + if (CONTACTS_ERROR_NONE <= ret) { + len += snprintf(query+len, sizeof(query)-len, + " WHERE ("CTS_TABLE_SEARCH_INDEX" MATCH 'name:%s* OR number:%s* OR data:%s*') ", remake_val, keyword, keyword); + } + else + len += snprintf(query+len, sizeof(query)-len, + " WHERE ("CTS_TABLE_SEARCH_INDEX" MATCH 'name:%s* OR number:%s* OR data:%s*') ", keyword, keyword, keyword); + + if (condition && *condition) + len += snprintf(query+len, sizeof(query)-len, " AND (%s)", condition); + + 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: + len += snprintf(query+len, sizeof(query)-len, " ORDER BY %s %s", sortkey, s_query->sort_asc?"":"DESC"); + 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) { + len += snprintf(query+len, sizeof(query)-len, " ORDER BY %s", field_name); +// if (sortkey) +// len += snprintf(query+len, sizeof(query)-len, ", %s", sortkey); + if (false == s_query->sort_asc) + len += snprintf(query+len, sizeof(query)-len, " DESC"); + } + else if (sortkey) + len += snprintf(query+len, sizeof(query)-len, " ORDER BY %s", sortkey); + break; + } + } + else if (sortkey) + len += snprintf(query+len, sizeof(query)-len, " ORDER BY %s", sortkey); + + 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); + } + + CTS_DBG("%s", query); + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + i = 1; +// sqlite3_bind_text(stmt, i++, keyword, strlen(keyword), SQLITE_STATIC); +// if (*remake_val) +// sqlite3_bind_text(stmt, i++, remake_val, strlen(remake_val), SQLITE_STATIC); + + len = g_slist_length(bind); + for (cursor=bind; cursor;cursor=cursor->next, i++) + sqlite3_bind_text(stmt, i, cursor->data, strlen(cursor->data), SQLITE_STATIC); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + } + cts_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"); + + 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(%s)", ret); + } + + ret = __ctsvc_db_create_projection(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(%s)", ret); + + ret = __ctsvc_db_search_records_with_query_exec(s_query, projection, condition, bind_text, keyword, offset, limit, out_list); + RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_db_search_records_with_query_exec is failed(%s)", 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; + unsigned 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; + unsigned 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_server_db_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); + 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 { + unsigned 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_server_db_begin_trans is failed(%d)", ret); + + index = 0; + do { + ret = contacts_db_delete_record(view_uri, ids[index++]); + 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; + unsigned 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_server_db_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 %s)", projection, table); + + ret = ctsvc_query_get_first_int_result(query, out_count); + + 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(p, count, NULL, 0, &projection); + RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_db_create_projection is failed(%s)", 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[CTS_SQL_MAX_LEN] = {0}; + 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); + + if (s_query->distinct) + len = snprintf(query, sizeof(query), "SELECT COUNT(*) FROM (SELECT DISTINCT %s FROM %s", projection, table); + else + len = snprintf(query, sizeof(query), "SELECT COUNT(*) FROM (SELECT %s FROM %s", projection, table); + + if (condition && *condition) + len += snprintf(query+len, sizeof(query)-len, " WHERE %s)", condition); + else + len += snprintf(query+len, sizeof(query)-len, ")"); + + if (bind_text) { + cts_stmt stmt; + GSList *cursor; + int i; + stmt = cts_query_prepare(query); + if(NULL == stmt) { + CTS_ERR("DB error : cts_query_prepare() Failed"); + return CONTACTS_ERROR_DB; + } + + for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++) + cts_stmt_bind_copy_text(stmt, i, cursor->data, strlen(cursor->data)); + ret = ctsvc_stmt_get_first_int_result(stmt, out_count); + } + else + ret = ctsvc_query_get_first_int_result(query, out_count); + return ret; +} + +static int __ctsvc_db_get_count_with_query( contacts_query_h query, int *out_count) +{ + int ret; + char *condition = NULL; + char *projection; + ctsvc_query_s *query_s; + GSList *bind_text = NULL; + GSList *cursor; + + RETV_IF(NULL == query, CONTACTS_ERROR_INVALID_PARAMETER); + query_s = (ctsvc_query_s *)query; + + if (query_s->filter) { + ret = __ctsvc_db_create_composite_condition(query_s->filter, &condition, &bind_text); + RETVM_IF (CONTACTS_ERROR_NONE != ret, ret, "__ctsvc_db_create_composite_condition is failed(%s)", ret); + } + + ret = __ctsvc_db_create_projection(query_s->properties, query_s->property_count, + query_s->projection, query_s->projection_count, &projection); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("__ctsvc_db_create_projection is failed(%s)", ret); + for (cursor=bind_text;cursor;cursor=cursor->next) + free(cursor->data); + g_slist_free(bind_text); + return ret; + } + + ret = __ctsvc_db_get_count_with_query_exec(query_s, 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; + + 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_update_info_create_record_from_stmt(const char *view_uri, + cts_stmt stmt, int version, contacts_record_h* record) +{ + int ret = contacts_record_create(view_uri, record); + RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "contacts_record_create is failed(%d)", ret); + + ctsvc_updated_info_s *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); + + 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}; + contacts_list_h list; + cts_stmt stmt; + + len = snprintf(query, sizeof(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 ", CONTACTS_CHANGE_INSERTED, version); + if (0 <= addressbook_id) { + len += snprintf(query + len , sizeof(query) - len , + "AND addressbook_id = %d ", addressbook_id); + } + + len += snprintf(query + len, sizeof(query) - len, + "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_DELETED, version); + if (0 <= addressbook_id) { + len += snprintf(query + len , sizeof(query) - len , + "AND addressbook_id = %d ", addressbook_id); + } + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + } + cts_stmt_finalize(stmt); + ctsvc_list_reverse(list); + + *out_list = list; + snprintf(query, sizeof(query), "SELECT ver FROM "CTS_TABLE_VERSION); + ret = ctsvc_query_get_first_int_result(query, out_current_version); + + 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, version, addressbook_id " + "FROM "CTSVC_DB_VIEW_GROUPS_MEMBER_UPDATED_INFO" WHERE version > %d", version); + + if (0 <= addressbook_id) + len += snprintf(query+len, sizeof(query)-len, " AND addressbook_id = %d ", addressbook_id); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + contacts_list_create(&list); + while ((ret = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_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); + } + cts_stmt_finalize(stmt); + ctsvc_list_reverse(list); + + *out_list = list; + snprintf(query, sizeof(query), "SELECT ver FROM "CTS_TABLE_VERSION); + ret = ctsvc_query_get_first_int_result(query, out_current_version); + + 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; + + char query[CTS_SQL_MAX_LEN] = {0}; + if (0 == strcmp(view_uri, _contacts_contact_updated_info._uri)) + { + if (0 <= addressbook_id) + { + snprintf(query, sizeof(query), + "SELECT %d, contact_id, changed_ver, created_ver, addressbook_id FROM %s " + "WHERE changed_ver > %d AND addressbook_id = %d AND deleted = 0 " + "UNION " + "SELECT %d, contact_id, deleted_ver, -1, addressbook_id FROM %s " + "WHERE deleted_ver > %d AND addressbook_id = %d " + "UNION " + "SELECT %d, contact_id, changed_ver, -1, addressbook_id FROM %s " + "WHERE changed_ver > %d AND addressbook_id = %d AND deleted = 1", + CONTACTS_CHANGE_UPDATED, CTS_TABLE_CONTACTS, version, addressbook_id, + CONTACTS_CHANGE_DELETED, CTS_TABLE_DELETEDS, version, addressbook_id, + CONTACTS_CHANGE_DELETED, CTS_TABLE_CONTACTS, version, addressbook_id); + } + else { + snprintf(query, sizeof(query), + "SELECT %d, contact_id, changed_ver, created_ver, addressbook_id FROM %s " + "WHERE changed_ver > %d AND deleted = 0 " + "UNION " + "SELECT %d, contact_id, deleted_ver, -1, addressbook_id FROM %s " + "WHERE deleted_ver > %d " + "UNION " + "SELECT %d, contact_id, changed_ver, -1, addressbook_id FROM %s " + "WHERE changed_ver > %d AND deleted = 1", + CONTACTS_CHANGE_UPDATED, CTS_TABLE_CONTACTS, version, + CONTACTS_CHANGE_DELETED, CTS_TABLE_DELETEDS, version, + CONTACTS_CHANGE_DELETED, CTS_TABLE_CONTACTS, version); + } + } + else if(0 == strcmp(view_uri, _contacts_group_updated_info._uri)) + { + 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 addressbook_id = %d", + CONTACTS_CHANGE_UPDATED, CTS_TABLE_GROUPS, version, addressbook_id, + CONTACTS_CHANGE_DELETED, CTS_TABLE_GROUP_DELETEDS, 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 ", + CONTACTS_CHANGE_UPDATED, CTS_TABLE_GROUPS, version, + CONTACTS_CHANGE_DELETED, CTS_TABLE_GROUP_DELETEDS, version); + } + } + 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, CTSVC_VIEW_URI_PERSON_UPDATED_INFO)) + { + + } +*/ + else + { + CTS_ERR("Invalid parameter : this API does not support uri(%s)", view_uri); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + + cts_stmt stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB , "DB error : cts_query_prepare() Failed"); + + contacts_list_h list; + contacts_list_create(&list); + + while ((ret = cts_stmt_step(stmt))) { + contacts_record_h record; + if (1 != ret) { + CTS_ERR("DB error : cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return ret; + } + + ret = __ctsvc_db_update_info_create_record_from_stmt(view_uri, stmt, version, &record); + if( ret != CONTACTS_ERROR_NONE ) + { + CTS_ERR("DB error : __ctsvc_db_update_info_create_record_from_stmt() Failed(%d)", ret); + cts_stmt_finalize(stmt); + contacts_list_destroy(list, true); + return CONTACTS_ERROR_DB; + } + + ctsvc_list_prepend(list, record); + } + cts_stmt_finalize(stmt); + ctsvc_list_reverse(list); + + *out_list = (contacts_list_h)list; + + // why should be return with current_version ?? + const char *version_query = "SELECT ver FROM "CTS_TABLE_VERSION; + ret = ctsvc_query_get_first_int_result(version_query, out_current_version); + + return CONTACTS_ERROR_NONE; +} + +API int contacts_db_get_current_version( int* out_current_version ) +{ + RETVM_IF(NULL == out_current_version, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid paramter"); + + 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 paramter"); + + return __ctsvc_db_search_records(view_uri, keyword, offset, limit, 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 paramter"); + + 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 paramter"); + + 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 paramter"); + s_query = (ctsvc_query_s*)query; + + 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 paramter"); + + 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"); + + 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 paramter"); + + 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"); + + 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 paramter"); + + 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"); + + 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 paramter"); + + 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"); + + 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 paramter : 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"); + + 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 paramter"); + + 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, 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 paramter"); + + 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 paramter"); + +#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 paramter"); + + 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 paramter"); + +#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 paramter"); + RETVM_IF(NULL == ids, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid paramter"); + +#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; + unsigned 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_server_db_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 paramter"); + RETVM_IF(NULL == ids, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid paramter"); + + 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[], unsigned int count, + contacts_db_result_cb callback, void *user_data ) +{ + RETVM_IF(NULL == list, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid paramter"); + RETVM_IF(NULL == ids, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid paramter"); + +#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, unsigned 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[], unsigned int count ) +{ + return ctsvc_db_replace_records(list, record_id_array, count); +} + diff --git a/native/ctsvc_db_query.h b/native/ctsvc_db_query.h new file mode 100644 index 0000000..b8031ae --- /dev/null +++ b/native/ctsvc_db_query.h @@ -0,0 +1,38 @@ +/* + * 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 "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); + +#endif /* __TIZEN_SOCIAL_CTSVC_DB_QUERY_H__ */ + diff --git a/native/ctsvc_group.c b/native/ctsvc_group.c new file mode 100644 index 0000000..c7f33a4 --- /dev/null +++ b/native/ctsvc_group.c @@ -0,0 +1,223 @@ +/* + * 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" + +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, contact_acc; + int exist; + + 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 (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 == grp_acc, 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( 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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + WARN_IF(CONTACTS_ERROR_NONE != ret, "cts_stmt_step() Failed(%d)", ret); + + rel_changed = cts_db_change(); + cts_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) +{ + 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 */ + int ret = ctsvc_begin_trans(); + RETVM_IF(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret); + + /* 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_contact_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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB Error: cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + WARN_IF(CONTACTS_ERROR_NONE != ret, "DB Error: cts_stmt_step() Failed(%d)", ret); + + int rel_changed = cts_db_change(); + cts_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) +{ + 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 */ + int ret = ctsvc_begin_trans(); + RETVM_IF(ret, ret, "contacts_svc_begin_trans() Failed(%d)", ret); + + /* 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_contact_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_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 index 0000000..9b1bcf1 --- /dev/null +++ b/native/ctsvc_group.h @@ -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_notification.c b/native/ctsvc_notification.c new file mode 100644 index 0000000..702ffa9 --- /dev/null +++ b/native/ctsvc_notification.c @@ -0,0 +1,557 @@ +/*
+ * 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 <errno.h>
+//#include <dirent.h>
+#include <sys/stat.h>
+
+#include "contacts.h"
+#include "ctsvc_internal.h"
+//#include "ctsvc_utils.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 missed_change = false;
+static TLS bool favor_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 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;
+
+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_missed_call_change(void)
+{
+ int fd = open(CTSVC_NOTI_MISSED_CALL_CHANGED, O_TRUNC | O_RDWR);
+ if (0 <= fd) {
+ close(fd);
+ missed_change = false;
+ }
+}
+
+static inline void __ctsvc_noti_publish_favor_change(void)
+{
+ int fd = open(CTSVC_NOTI_FAVORITE_CHANGED, O_TRUNC | O_RDWR);
+ if (0 <= fd) {
+ close(fd);
+ favor_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_simple_contact_change(void)
+{
+ int fd = open(CTSVC_NOTI_SIMPLE_CONTACT_CHANGED, O_TRUNC | O_RDWR);
+ if (0 <= fd) {
+ close(fd);
+ contact_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;
+ }
+}
+
+void ctsvc_nofitication_cancel(void)
+{
+ contact_change = false;
+ my_profile_change = false;
+ phonelog_change = false;
+ missed_change = false;
+ favor_change = false;
+ speed_change = false;
+ addressbook_change = false;
+ group_change = false;
+ group_rel_change = false;
+ person_change = false;
+ activity_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_missed_call_noti(void)
+{
+ missed_change = true;
+}
+
+void ctsvc_set_favor_noti(void)
+{
+ favor_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_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 (missed_change) __ctsvc_noti_publish_missed_call_change();
+ if (favor_change) __ctsvc_noti_publish_favor_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 (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();
+ if (company_change) __ctsvc_noti_publish_company_change();
+}
+
+void ctsvc_db_data_delete_callback(sqlite3_context * context,
+ int argc, sqlite3_value ** argv)
+{
+ CTS_FN_CALL;
+ int id;
+ int datatype;
+
+ if (argc > 2) {
+ sqlite3_result_null(context);
+ return;
+ }
+
+ id = sqlite3_value_int(argv[0]);
+ datatype = sqlite3_value_int(argv[1]);
+ CTS_DBG("id : %d, datatype : %d", id, datatype);
+
+ 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;
+}
+
diff --git a/native/ctsvc_notification.h b/native/ctsvc_notification.h new file mode 100644 index 0000000..92e4e57 --- /dev/null +++ b/native/ctsvc_notification.h @@ -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_missed_call_noti(void);
+void ctsvc_set_favor_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_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_db_data_delete_callback(sqlite3_context * context,
+ int argc, sqlite3_value ** argv);
+
+#endif /* __TIZEN_SOCIAL_CTSVC_NOTIFICATION_H__ */
diff --git a/native/ctsvc_person.c b/native/ctsvc_person.c new file mode 100644 index 0000000..1eb5240 --- /dev/null +++ b/native/ctsvc_person.c @@ -0,0 +1,1269 @@ +/* + * 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" + +#ifdef _CONTACTS_IPC_SERVER +#include "ctsvc_server_change_subject.h" +#endif + +#define DISPLAY_ACCOUNT_MAX 3 + +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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + cts_stmt_finalize(stmt); + CTS_ERR("No data : person(%d) has no default phone", id); + return CONTACTS_ERROR_NO_DATA; + } + + 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"); + + cts_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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + + if (1 /*CTS_TRUE*/ != ret) { + cts_stmt_finalize(stmt); + CTS_ERR("person(%d) has no default email", id); + return CONTACTS_ERROR_NO_DATA; + } + + 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"); + + cts_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); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ != ret) { + cts_stmt_finalize(stmt); + ERR("person(%d) has no default image", id); + return CONTACTS_ERROR_NO_DATA; + } + + 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 + ERR("contacts_record_create() Failed"); + + cts_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); + stmt = cts_query_prepare(query); + if (NULL == stmt) { + CTS_ERR("cts_query_prepare failed"); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + ret = cts_stmt_step(stmt); + if (1 != ret) { + cts_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)); + cts_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); + stmt = cts_query_prepare(query); + if( NULL == stmt ) { + CTS_ERR( "cts_query_prepare() Failed()"); + free(image_path); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + cts_stmt_bind_text(stmt, 1, image_path); + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + free(image_path); + ctsvc_end_trans(false); + return ret; + } + cts_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); + stmt = cts_query_prepare(query); + if( NULL == stmt ) { + CTS_ERR( "cts_query_prepare() Failed"); + free(image_path); + ctsvc_end_trans(false); + return CONTACTS_ERROR_DB; + } + + cts_stmt_bind_text(stmt, 1, image_path); + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + free(image_path); + ctsvc_end_trans(false); + return ret; + } + cts_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; + char query[CTS_SQL_MAX_LEN] = {0}; + + snprintf(query, sizeof(query), + "SELECT D.is_default 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_get_first_int_result(query, &is_default); + RETVM_IF(ret < CONTACTS_ERROR_NONE, ret, "ctsvc_query_get_first_int_result() Failed(%d)", ret); + + 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; + } + + 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); + + sqlite3_result_null(context); + return; +#endif +} + +inline static const char* __cts_get_image_filename(const char* src) +{ + const char* dir = CTS_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; + int account_ids[DISPLAY_ACCOUNT_MAX] = {0}; + char addressbook_ids[100] = {0}; + 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 *status = NULL; + const char *temp; + cts_stmt stmt; + ctsvc_person_s *person; + bool person_is_favorite = false; + + ret = contacts_db_get_record( _contacts_person._uri, person_id, (contacts_record_h*)&person); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("contacts_db_get_record() Failed\n"); + return CONTACTS_ERROR_INTERNAL; + } + + 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; + } + + if (person->image_thumbnail_path) { + temp = __cts_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; + } + + 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); + stmt = cts_query_prepare(query); + if (NULL == stmt) { + ERR("DB error : cts_query_prepare() Failed"); + free(image_thumbnail_path); + contacts_record_destroy((contacts_record_h)person, true); + return CONTACTS_ERROR_DB; + } + + if (1 == cts_stmt_step(stmt)) { + temp = ctsvc_stmt_get_text(stmt, 0); + status = SAFE_STRDUP(temp); + } + cts_stmt_finalize(stmt); + + if (person->ringtone_path) + ringtone_path = SAFE_STRDUP(person->ringtone_path); + if (person->vibration) + vibration = SAFE_STRDUP(person->vibration); + contacts_record_destroy((contacts_record_h)person, true); + + snprintf(query, sizeof(query), + "SELECT contact_id, contacts.addressbook_id, %s, display_name_source, " + "image_thumbnail_path, ringtone_path, vibration, account_id, is_favorite " + "FROM %s, %s " + "ON contacts.addressbook_id = addressbooks.addressbook_id AND contacts.deleted = 0 " + "WHERE person_id = %d " + "ORDER BY contact_id", + ctsvc_get_display_column(), CTS_TABLE_CONTACTS, CTS_TABLE_ADDRESSBOOKS, person_id); + stmt = cts_query_prepare(query); + if (NULL == stmt) { + ERR("DB error : cts_query_prepare() Failed"); + free(image_thumbnail_path); + free(ringtone_path); + free(vibration); + return CONTACTS_ERROR_DB; + } + + link_count = 0; + while ((ret = cts_stmt_step(stmt))) { + const char *temp_str; + int i = 0; + int account_id; + int contact_id; + int addressbook_id; + int contact_display_name_source_type = CONTACTS_DISPLAY_NAME_SOURCE_TYPE_INVALID; + char *contact_display_name = NULL; + char *contact_ringtone_path = NULL; + char *contact_image_thumbnail_path = NULL; + char *contact_vibration = NULL; + bool is_favorite = false; + + contact_id = ctsvc_stmt_get_int(stmt, i++); + addressbook_id = ctsvc_stmt_get_int(stmt, i++); + temp = ctsvc_stmt_get_text(stmt, i++); + contact_display_name = SAFE_STRDUP(temp); + 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); + account_id = ctsvc_stmt_get_int(stmt, i++); + is_favorite = ctsvc_stmt_get_int(stmt, i++); + + link_count++; + + for( i=0; i<DISPLAY_ACCOUNT_MAX; i++) { + if (0 == account_ids[i]){ + account_ids[i] = account_id; + break; + } + else if (account_ids[i] == account_id) { + break; + } + } + 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) + name_contact_id = person_name_contact_id; + } + + len += snprintf(addressbook_ids + len, sizeof(addressbook_ids)-len, "%d ", addressbook_id ); + + if (contact_image_thumbnail_path && *contact_image_thumbnail_path) { + temp = __cts_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); + + temp_str = contact_vibration; + if (!vibration && temp_str && strlen(temp_str)) + vibration = SAFE_STRDUP(temp_str); + + if (is_favorite) + person_is_favorite = true; + } + cts_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, account_id1 = %d, account_id2 = %d, account_id3 = %d, " + "addressbook_ids = ?, ringtone_path=?, vibration=?, status=?, image_thumbnail_path=? " + "WHERE person_id = %d ", + name_contact_id, version, person_id, + person_id, link_count, account_ids[0], account_ids[1], account_ids[2], person_id); + + stmt = cts_query_prepare(query); + if (NULL == stmt) { + ERR("DB error : cts_query_prepare() Failed"); + free(image_thumbnail_path); + free(ringtone_path); + free(vibration); + return CONTACTS_ERROR_DB; + } + + cts_stmt_bind_text(stmt, 1, addressbook_ids); + + if(ringtone_path) + cts_stmt_bind_text(stmt, 2, ringtone_path); + if(vibration) + cts_stmt_bind_text(stmt, 3, vibration); + if(status) + cts_stmt_bind_text(stmt, 4, status); + if(image_thumbnail_path) + cts_stmt_bind_text(stmt, 5, image_thumbnail_path); + + ret = cts_stmt_step(stmt); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("cts_stmt_step() Failed(%d)", ret); + cts_stmt_finalize(stmt); + free(image_thumbnail_path); + free(ringtone_path); + free(vibration); + return ret; + } + + cts_stmt_finalize(stmt); + + free(image_thumbnail_path); + free(ringtone_path); + free(vibration); + + 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); + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + ret = cts_stmt_step(stmt); + if (1 == ret) { + *priority = ctsvc_stmt_get_dbl(stmt, 0); + cts_stmt_finalize(stmt); + return true; + } + cts_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(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); + + 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; + } + + 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); + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "cts_query_prepare fail(%d)", CONTACTS_ERROR_DB); + + while (1 == cts_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); + + stmt_number = cts_query_prepare(query); + + if( 1 == cts_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); + cts_stmt_finalize(stmt_number); + break; + } + cts_stmt_finalize(stmt_number); + } + cts_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); + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "cts_query_prepare fail(%d)", CONTACTS_ERROR_DB); + + while (1 == cts_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); + + stmt_email = cts_query_prepare(query); + + if( 1 == cts_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); + cts_stmt_finalize(stmt_email); + break; + } + cts_stmt_finalize(stmt_email); + } + cts_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); + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "cts_query_prepare fail(%d)", CONTACTS_ERROR_DB); + + while ( 1 == cts_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); + + stmt_image = cts_query_prepare(query); + if( 1 == cts_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); + cts_stmt_finalize(stmt_image); + break; + } + cts_stmt_finalize(stmt_image); + } + cts_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; + char query[CTS_SQL_MIN_LEN] = {0}; + contacts_record_h record = NULL; + bool is_favorite = false; + double priority = 0.0; + + RETVM_IF(person_id <= 0 || contact_id <= 0 , CONTACTS_ERROR_INVALID_PARAMETER, + "Invalid parameter : person_id(%d), person_id(%d)", person_id, person_id); + RETVM_IF(out_person_id == NULL , CONTACTS_ERROR_INVALID_PARAMETER, + "Invalid parameter : out_person_id is NULL"); + + *out_person_id = 0; + + 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_id); + ret = ctsvc_query_get_first_int_result(query, &id); + if (CONTACTS_ERROR_NONE != ret) { + ctsvc_end_trans(false); + return ret; + } + + ret = contacts_db_get_record(_contacts_contact._uri, contact_id, &record); + if (CONTACTS_ERROR_NONE != ret) { + CTS_ERR("contacts_db_get_record() Failed(%d)", ret); + ctsvc_end_trans(false); + return ret; + } + + *out_person_id = ctsvc_db_insert_person(record); + if (CONTACTS_ERROR_NONE > *out_person_id) { + CTS_ERR("ctsvc_db_insert_person() Failed(%d)", *out_person_id); + ctsvc_end_trans(false); + return *out_person_id; + } + + 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, *out_person_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); + return ret; + } + + is_favorite = __ctsvc_get_person_favorite_info(person_id, &priority); + + snprintf(query, sizeof(query), + "UPDATE %s SET person_id = %d WHERE contact_id = %d", + CTS_TABLE_CONTACTS, *out_person_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); + return ret; + } + + 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); + return ret; + } + + if (is_favorite && ((ctsvc_contact_s*)record)->is_favorite) { + snprintf(query, sizeof(query), + "INSERT INTO "CTS_TABLE_FAVORITES" values(%d, %f)", *out_person_id, priority); + 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_update_primary_default_data(person_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) +{ + 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"); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "DB error : cts_query_prepare() Failed"); + + while ( 1 /*CTS_TRUE*/ == cts_stmt_step(stmt)) { + int person_id; + person_id = ctsvc_stmt_get_int(stmt, 0); + ctsvc_person_aggregate(person_id); + } + cts_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(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}; + + snprintf(query, sizeof(query), "SELECT favorite_prio FROM "CTS_TABLE_FAVORITES" WHERE person_id = ?"); + + stmt = cts_query_prepare(query); + RETVM_IF(NULL == stmt, CONTACTS_ERROR_DB, "cts_query_prepare() Failed"); + + cts_stmt_bind_int(stmt, 1, front_person_id); + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ == ret) + front_prio = ctsvc_stmt_get_dbl(stmt, 0); + cts_stmt_reset(stmt); + cts_stmt_bind_int(stmt, 1, back_person_id); + ret = cts_stmt_step(stmt); + if (1 /*CTS_TRUE*/ == ret) + back_prio = ctsvc_stmt_get_dbl(stmt, 0); + cts_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_favor_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; + + 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, 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}; + + 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 index 0000000..677b98d --- /dev/null +++ b/native/ctsvc_person.h @@ -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 index 0000000..b8017b0 --- /dev/null +++ b/native/ctsvc_phonelog.c @@ -0,0 +1,107 @@ +/* + * 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_notification.h" + +#ifdef _CONTACTS_IPC_SERVER +#include "ctsvc_server_change_subject.h" +#endif + +API int contacts_phone_log_reset_statistics() +{ + char query[CTS_SQL_MIN_LEN] = {0}; + 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; + + 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 +} diff --git a/native/ctsvc_phonelog.h b/native/ctsvc_phonelog.h new file mode 100644 index 0000000..f03dba7 --- /dev/null +++ b/native/ctsvc_phonelog.h @@ -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_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); + +#endif // __TIZEN_SOCIAL_CTSVC_PHONELOG_H__
\ No newline at end of file diff --git a/native/ctsvc_restriction.c b/native/ctsvc_restriction.c new file mode 100755 index 0000000..bc8f27d --- /dev/null +++ b/native/ctsvc_restriction.c @@ -0,0 +1,82 @@ +/* + * 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 "contacts.h" +#include "ctsvc_internal.h" +#include "ctsvc_sqlite.h" +#include "ctsvc_schema.h" + +static const char *CTS_RESTRICTION_CHECK_FILE="/opt/usr/data/contacts-svc/.CONTACTS_SVC_RESTRICTION_CHECK"; +static TLS int ctsvc_restriction_permit; + +int ctsvc_restriction_init(void) +{ + if (!ctsvc_restriction_permit) { + int fd = open(CTS_RESTRICTION_CHECK_FILE, O_RDONLY); + if (0 <= fd) { + close(fd); + ctsvc_restriction_permit = TRUE; + } else { + CTS_ERR("Restriction Mode"); + } + } + if (!ctsvc_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 AND is_my_profile = 0"; + + ret = ctsvc_query_exec(query); + RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "cts_query_exec() Failed(%d)", ret); + } + return CONTACTS_ERROR_NONE; +} + +void ctsvc_restriction_deinit(void) +{ + ctsvc_restriction_permit = FALSE; +} + +int ctsvc_restriction_get_permit(void) +{ + return ctsvc_restriction_permit; +} +#if 0 +/** + * 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 == ctsvc_restriction_permit, CTS_ERR_ENV_INVALID); + + record->is_restricted = TRUE; + + return CONTACTS_ERROR_NONE; +} +#endif diff --git a/native/ctsvc_restriction.h b/native/ctsvc_restriction.h new file mode 100755 index 0000000..0e4ac6b --- /dev/null +++ b/native/ctsvc_restriction.h @@ -0,0 +1,30 @@ +/* + * Contacts Service + * + * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngjae Shin <yj99.shin@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#ifndef __TIZEN_SOCIAL_CTSVC_RESTRICTION_H__ +#define __TIZEN_SOCIAL_CTSVC_RESTRICTION_H__ + +int ctsvc_restriction_init(void); +void ctsvc_restriction_deinit(void); + +int ctsvc_restriction_get_permit(void); + +#endif //__TIZEN_SOCIAL_CTSVC_RESTRICTION_H__ + diff --git a/native/ctsvc_schema.h b/native/ctsvc_schema.h new file mode 100755 index 0000000..58cf8e1 --- /dev/null +++ b/native/ctsvc_schema.h @@ -0,0 +1,119 @@ +/* + * 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 6005 +#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_SEARCH_INDEX "search_index" +#define CTS_TABLE_ACTIVITIES "activities" +#define CTS_TABLE_ACTIVITY_PHOTOS "activity_photos" + +#define CTS_TABLE_RESTRICTED_DATA_VIEW "restricted_data" + +// DB views ///////////////////////////////////////////////////////////////////// +#define CTSVC_DB_VIEW_PERSON "view_person" +#define CTSVC_DB_VIEW_CONTACT "view_contact" + +#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_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_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 CTSVC_DB_VIEW_PHONELOG_NUMBER "view_phonelog_number" + +///////////////////////////////////////////////////////////////////////////////// + +#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 index 0000000..391b6c5 --- /dev/null +++ b/native/ctsvc_service.c @@ -0,0 +1,195 @@ +/* + * 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 "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" + +#ifndef _CONTACTS_IPC_CLIENT +static int ctsvc_connection = 0; +static __thread int thread_connection = 0; +#endif + +API int contacts_connect2() +{ + CTS_FN_CALL; + int ret; + +#ifndef _CONTACTS_IPC_CLIENT + ctsvc_mutex_lock(CTS_MUTEX_CONNECTION); + if (0 == ctsvc_connection) { + 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_db_plugin_init(); + ctsvc_view_uri_init(); + ctsvc_register_vconf(); + } + else + CTS_DBG("System : Contacts service has been already connected"); + + ctsvc_connection++; + ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION); +#endif + + if (0 == thread_connection) { + ret = ctsvc_db_init(); + if (ret != CONTACTS_ERROR_NONE) { + CTS_ERR("ctsvc_db_init() Failed(%d)", ret); + return ret; + } + } + thread_connection++; + + return CONTACTS_ERROR_NONE; +} + +API int contacts_connect_with_flags(unsigned int flags) +{ + CTS_FN_CALL; + int ret = CONTACTS_ERROR_NONE; + + ret = contacts_connect2(); + if (ret == CONTACTS_ERROR_NONE) + return ret; + + if (flags & CONTACTS_CONNECT_FLAG_RETRY) { + int i; + int waiting_time = 500; + for (i=0;i<6;i++) { + usleep(waiting_time * 1000); + DBG("retry cnt=%d, ret=%x, %d",(i+1), ret, waiting_time); + ret = contacts_connect2(); + if (ret == CONTACTS_ERROR_NONE) + break; + waiting_time *= 2; + } + } + + return ret; +} + +API int contacts_disconnect2() +{ + if (1 == thread_connection) + ctsvc_db_deinit(); + else if (thread_connection <= 0) { + CTS_DBG("System : please call contacts_connect_on_thread(), thread_connection count is (%d)", thread_connection); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + thread_connection--; + +#ifndef _CONTACTS_IPC_CLIENT + ctsvc_mutex_lock(CTS_MUTEX_CONNECTION); + if (1 == ctsvc_connection) { + ctsvc_socket_final(); + ctsvc_inotify_close(); + ctsvc_deregister_vconf(); + ctsvc_view_uri_deinit(); + ctsvc_db_plugin_deinit(); + } + else if (1 < ctsvc_connection) + CTS_DBG("System : connection count is %d", ctsvc_connection); + else { + CTS_DBG("System : please call contacts_connect2(), 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); +#endif + + + return CONTACTS_ERROR_NONE; +} + +API int contacts_connect_on_thread() +{ + int ret; + + ctsvc_mutex_lock(CTS_MUTEX_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; + } + } + 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() +{ + ctsvc_mutex_lock(CTS_MUTEX_CONNECTION); + + if (1 == thread_connection) + { + ctsvc_db_deinit(); + } + 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; +} diff --git a/native/ctsvc_service.h b/native/ctsvc_service.h new file mode 100644 index 0000000..52af4fc --- /dev/null +++ b/native/ctsvc_service.h @@ -0,0 +1,29 @@ +/*
+ * 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__
+
+
+#endif /* __TIZEN_SOCIAL_CTSVC_SERVICE_H__ */
+
diff --git a/native/ctsvc_sqlite.c b/native/ctsvc_sqlite.c new file mode 100755 index 0000000..f2bfdad --- /dev/null +++ b/native/ctsvc_sqlite.c @@ -0,0 +1,270 @@ +/* + * 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 <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_db_init.h" +#include "ctsvc_db_plugin_contact_helper.h" +#include "ctsvc_db_plugin_person_helper.h" + +#include "ctsvc_phonelog.h" +#include "ctsvc_person.h" + +static __thread sqlite3 *ctsvc_db = NULL; + +static inline int __ctsvc_db_busyhandler(void *pData, int count) +{ + if(10 - count > 0) { + CTS_DBG("Busy Handler Called! : PID(%d) / CNT(%d)\n", getpid(), count+1); + usleep(20000); + return 1; + } else { + CTS_DBG("Busy Handler will be returned SQLITE_BUSY error : PID(%d) \n", getpid()); + return 0; + } +} + +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, "_CONTACT_DELETE_", 3, SQLITE_UTF8, NULL, + ctsvc_db_contact_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_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, "_NORMALIZE_INDEX_", 1, SQLITE_UTF8, NULL, + ctsvc_db_normalize_str_callback, NULL, NULL); + RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB, + "sqlite3_create_function() Failed(%d)", ret); + 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); + 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); + + /* Register Busy handler */ + ret = sqlite3_busy_handler(ctsvc_db, __ctsvc_db_busyhandler, NULL); + RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB, + "sqlite3_busy_handler() 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 cts_db_change(void) { + return sqlite3_changes(ctsvc_db); +} + +int cts_db_get_last_insert_id(void) { + return sqlite3_last_insert_rowid(ctsvc_db); +} + +int cts_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; + cts_stmt stmt = NULL; + RETVM_IF(NULL == ctsvc_db, CONTACTS_ERROR_DB /*CTS_ERR_DB_NOT_OPENED*/, "DB error : Database is not opended"); + + ret = sqlite3_prepare_v2(ctsvc_db, query, strlen(query), &stmt, NULL); + RETVM_IF(SQLITE_OK != ret, CONTACTS_ERROR_DB, + "DB error : sqlite3_prepare_v2(%s) Failed(%s)", query, sqlite3_errmsg(ctsvc_db)); + + ret = sqlite3_step(stmt); + if (SQLITE_ROW != ret) { + sqlite3_finalize(stmt); + if (SQLITE_DONE == ret) { + INFO("sqlite3_step() return with SQLITE_DONE (it means NO_DATA) (%s, %d, %s)", + query, ret, sqlite3_errmsg(ctsvc_db)); + + return CONTACTS_ERROR_NO_DATA /*CONTACTS_ERR_DB_RECORD_NOT_FOUND*/; + } + + CTS_ERR("sqlite3_step() Failed(%s, %d, %s)", + query, ret, sqlite3_errmsg(ctsvc_db)); + + 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; + char *err_msg = NULL; + + RETVM_IF(NULL == ctsvc_db, CONTACTS_ERROR_DB /*CTS_ERR_DB_NOT_OPENED*/, "DB error : Database is not opended"); + CTS_DBG("query : %s", query); + + ret = sqlite3_exec(ctsvc_db, query, NULL, NULL, &err_msg); + if (SQLITE_OK != ret) { + CTS_ERR("sqlite3_exec(%s) Failed(%d, %s)", query, ret, err_msg); + sqlite3_free(err_msg); + switch (ret) { + case SQLITE_BUSY: + case SQLITE_LOCKED: + return CONTACTS_ERROR_DB /*CTS_ERR_DB_LOCK*/; + case SQLITE_IOERR: + return CONTACTS_ERROR_DB /*CTS_ERR_IO_ERR*/; + case SQLITE_FULL: + return CONTACTS_ERROR_FILE_NO_SPACE /*CTS_ERR_NO_SPACE*/; + default: + return CONTACTS_ERROR_DB; + } + } + + return CONTACTS_ERROR_NONE /*CTS_SUCCESS*/; +} + +cts_stmt cts_query_prepare(char *query) { + int ret = -1; + cts_stmt stmt = NULL; + + RETVM_IF(NULL == ctsvc_db, NULL, "DB error : Database is not opended"); + CTS_DBG("prepare query : %s", query); + + ret = sqlite3_prepare_v2(ctsvc_db, query, strlen(query), &stmt, NULL); + RETVM_IF(SQLITE_OK != ret, NULL, "DB error : sqlite3_prepare_v2(%s) Failed(%s)", + query, sqlite3_errmsg(ctsvc_db)); + + return stmt; +} + +int ctsvc_stmt_get_first_int_result(cts_stmt stmt, int *result) { + int ret; + RETVM_IF(NULL == ctsvc_db, CONTACTS_ERROR_DB /*CTS_ERR_DB_NOT_OPENED*/, "DB error : Database is not opended"); + + ret = sqlite3_step(stmt); + if (SQLITE_ROW != ret) { + CTS_ERR("sqlite3_step() Failed(%d, %s)", ret, sqlite3_errmsg(ctsvc_db)); + sqlite3_finalize(stmt); + if (SQLITE_DONE == ret) + return CONTACTS_ERROR_NO_DATA /*CONTACTS_ERR_DB_RECORD_NOT_FOUND*/; + return CONTACTS_ERROR_DB; + } + + *result = sqlite3_column_int(stmt, 0); + sqlite3_finalize(stmt); + + return CONTACTS_ERROR_NONE; +} + +int cts_stmt_step(cts_stmt stmt) { + int ret; + ret = sqlite3_step(stmt); + switch (ret) { + case SQLITE_BUSY: + case SQLITE_LOCKED: + ret = CONTACTS_ERROR_DB /*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 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(ctsvc_db)); +} + diff --git a/native/ctsvc_sqlite.h b/native/ctsvc_sqlite.h new file mode 100755 index 0000000..696b36d --- /dev/null +++ b/native/ctsvc_sqlite.h @@ -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 cts_db_change(); +int cts_db_get_last_insert_id(void); +int cts_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); +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 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 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); + + +#endif //__TIZEN_SOCIAL_CTSVC_SQLITE_H__ diff --git a/native/ctsvc_utils.c b/native/ctsvc_utils.c new file mode 100644 index 0000000..2fb1051 --- /dev/null +++ b/native/ctsvc_utils.c @@ -0,0 +1,428 @@ +/* + * 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 <errno.h> +#include <dirent.h> +#include <sys/stat.h> +#include <sys/vfs.h> +#include <image_util.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" + +#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_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"); //taken 600ms + 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); + } + + 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; + } + 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_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_language, sortkey"; + else + return "display_name_language, reverse_sortkey"; +} + +// This function is for MY profile and group image. +char* ctsvc_get_image(const char *dir, int index, char *dest, int dest_size) +{ + DIR *dp; + char *ret_val; + struct dirent *file_info; + char tmp_path[CTSVC_IMG_FULL_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; +} + +static inline bool ctsvc_check_available_image_space(void){ + int ret; + struct statfs buf; + long long size; + ret = statfs(CTS_IMG_FULL_LOCATION, &buf); + + RETVM_IF(ret!=0, false, "statfs Failed(%d)", ret); + + size = 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 int image_size = 480; +static int __ctsvc_resize_and_copy_image(const char *src, const char *dest) +{ + 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; + const image_util_colorspace_e colorspace = IMAGE_UTIL_COLORSPACE_I420; + + // load jpeg sample file + CTS_DBG("src : %s, dest : %s", src, dest); + ret = image_util_decode_jpeg( src, colorspace, &img_source, &width, &height, &size_decode ); + RETVM_IF(ret!=IMAGE_UTIL_ERROR_NONE, CONTACTS_ERROR_INTERNAL, "image_util_decode_jpeg failed(%d)", ret); + +#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) { + if (image_size<=0 || width <=0 || height <= 0) { + free(img_source); + CTS_ERR("image size error(%d)", image_size); + return CONTACTS_ERROR_INTERNAL; + } + + if (width>height) { + resized_width = image_size; + resized_height = height*image_size/width; + } + else { + resized_height = image_size; + resized_width = width*image_size/height; + } + 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 ); + return CONTACTS_ERROR_INTERNAL; + } + + ret = image_util_encode_jpeg(img_target, resized_width, resized_height, colorspace, 100, dest ); + free( img_target ); + free( img_source ); + RETVM_IF(ret!=IMAGE_UTIL_ERROR_NONE, CONTACTS_ERROR_INTERNAL, "image_util_encode_jpeg failed(%d)", ret); + } + else { + resized_width = width; + resized_height = height; + + ret = image_util_encode_jpeg(img_source, resized_width, resized_height, colorspace, 100, dest ); + free( img_source ); + RETVM_IF(ret!=IMAGE_UTIL_ERROR_NONE, CONTACTS_ERROR_INTERNAL, "image_util_encode_jpeg failed(%d)", ret); + } + + return CONTACTS_ERROR_NONE; +} + +#define CTSVC_COPY_SIZE_MAX 4096 +int ctsvc_copy_image(const char *src, const char *dest) +{ + int ret; + int size; + int src_fd, dest_fd; + char buf[CTSVC_COPY_SIZE_MAX] = {0}; + + 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; + + 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(dest:%s) Failed(%d)", dest, 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_SYSTEM; // 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(%s) Failed(%d)", dest, ret); + ret = fchmod(dest_fd, CTS_SECURITY_DEFAULT_PERMISSION); + if (0 != ret) + CTS_ERR("fchmod(%s) Failed(%d)", dest, ret); + close(src_fd); + close(dest_fd); + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_change_image(const char *dir, int index, const char *path, char *image, int image_len) +{ + int ret; + char dest[CTSVC_IMG_FULL_PATH_SIZE_MAX] = {0}; + + if (ctsvc_get_image(dir, index, dest, sizeof(dest))) { + if (path && 0 == strcmp(dest, path)) + return CONTACTS_ERROR_NONE; + ret = unlink(dest); + RETVM_IF(ret < 0, CONTACTS_ERROR_SYSTEM, "System : unlink(%s) Failed(%d)", dest, errno); + } + + if (path) { + char *ext; + int len; + ext = strrchr(path, '.'); + if (NULL == ext || strchr(ext, '/')) + ext = ""; + + snprintf(dest, sizeof(dest), "%s/%d%s", + dir, index, ext); + ret = ctsvc_copy_image(path, dest); + RETVM_IF(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_copy_image() Failed(%d)", ret); + len = strlen(dest) - strlen(dir); + if (image_len < len) { + CTS_ERR("The image_len is too short. It should be greater than %d", len); + return CONTACTS_ERROR_INVALID_PARAMETER; + } + snprintf(image, image_len, "%d%s", index, ext); + } + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_get_next_ver(void) +{ + const char *query; + int version; + + if (0 < transaction_count) { + version_up = true; + return transaction_ver + 1; + } + + query = "SELECT ver FROM "CTS_TABLE_VERSION; + ctsvc_query_get_first_int_result(query, &version); + 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); + *out_current_version = version; + } + else + *out_current_version = transaction_ver; + return CONTACTS_ERROR_NONE; +} + + diff --git a/native/ctsvc_utils.h b/native/ctsvc_utils.h new file mode 100644 index 0000000..adbe165 --- /dev/null +++ b/native/ctsvc_utils.h @@ -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_UTILS_H__
+#define __TIZEN_SOCIAL_CTSVC_UTILS_H__
+
+const char* ctsvc_get_display_column(void);
+const char* ctsvc_get_sort_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 );
+
+char* ctsvc_get_image(const char *dir, int index, char *dest, int dest_size);
+int ctsvc_change_image(const char *dir, int index, const char *path, char *image, int image_len);
+int ctsvc_copy_image(const char *src, const char *dest);
+
+#endif /* __TIZEN_SOCIAL_CTSVC_UTILS_H__ */
diff --git a/packaging/contacts-service.service b/packaging/contacts-service.service new file mode 100644 index 0000000..6eabc36 --- /dev/null +++ b/packaging/contacts-service.service @@ -0,0 +1,13 @@ +[Unit] +Description=Start the Contacts service helper service + +[Service] +ExecStart=/usr/bin/contacts-service-ipcd +Nice=5 +OOMScoreAdjust=-100 +Restart=always +RestartSec=2 + +[Install] +WantedBy=tizen-middleware.target + diff --git a/packaging/contacts-service.spec b/packaging/contacts-service.spec index f86c8e3..dfd2c38 100644 --- a/packaging/contacts-service.spec +++ b/packaging/contacts-service.spec @@ -1,14 +1,11 @@ Name: contacts-service Summary: Contacts Service -Version: 0.4.2 +Version: 0.9.24.8 Release: 1 Group: TO_BE/FILLED_IN -License: Apache 2.0 +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 BuildRequires: cmake BuildRequires: vconf-keys-devel BuildRequires: pkgconfig(db-util) @@ -18,17 +15,33 @@ BuildRequires: pkgconfig(sqlite3) BuildRequires: pkgconfig(tapi) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(icu-i18n) +BuildRequires: pkgconfig(capi-base-common) +BuildRequires: pkgconfig(capi-media-image-util) +BuildRequires: pkgconfig(pims-ipc) +BuildRequires: pkgconfig(badge) +Requires(post): /usr/bin/sqlite3, /bin/chmod, /bin/chown +Requires(post): /usr/bin/vconftool +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig %description Contacts Service Library -%package devel -Summary: Contacts Service (devel) +%package -n contacts-service2 +Summary: New Contacts service library +Group: Development/Libraries + +%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 @@ -38,47 +51,73 @@ Contacts Service Library (devel) cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -make %{?jobs:-j%jobs} +make %{?_smp_mflags} %install rm -rf %{buildroot} %make_install -%post -/sbin/ldconfig -contacts-svc-helper schema -chown :6005 /opt/dbspace/.contacts-svc.db -chown :6005 /opt/dbspace/.contacts-svc.db-journal +mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc3.d/ +mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc5.d/ +ln -s ../init.d/contacts-service-ipcd.sh %{buildroot}%{_sysconfdir}/rc.d/rc3.d/S50contacts-svc-helper +ln -s ../init.d/contacts-service-ipcd.sh %{buildroot}%{_sysconfdir}/rc.d/rc5.d/S50contacts-svc-helper -vconftool set -t int db/service/contacts/default_lang 1 -vconftool set -t int db/service/contacts/name_sorting_order 0 -g 6005 -vconftool set -t int db/service/contacts/name_display_order 0 -g 6005 +mkdir -p %{buildroot}%{_libdir}/systemd/user/tizen-middleware.target.wants +install -m 0644 %SOURCE1 %{buildroot}%{_libdir}/systemd/user/contacts-service.service +ln -s ../contacts-service.service %{buildroot}%{_libdir}/systemd/user/tizen-middleware.target.wants/contacts-service.service -#mkdir -p %{buildroot}%{_sysconfdir}/rc.d/ -#mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc3.d/ -#mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc5.d/ -#ln -s %{buildroot}/%{_sysconfdir}/init.d/contacts-svc-helper.sh %{buildroot}%/{_sysconfdir}/rc.d/rc3.d/S50contacts-svc-helper -#ln -s %{buildroot}/%{_sysconfdir}/init.d/contacts-svc-helper.sh %{buildroot}%/{_sysconfdir}/rc.d/rc5.d/S50contacts-svc-helper -mkdir -p /etc/rc.d/ -mkdir -p /etc/rc.d/rc3.d/ -mkdir -p /etc/rc.d/rc5.d/ -ln -s /etc/init.d/contacts-svc-helper.sh /etc/rc.d/rc3.d/S50contacts-svc-helper -ln -s /etc/init.d/contacts-svc-helper.sh /etc/rc.d/rc5.d/S50contacts-svc-helper +%post -n contacts-service2 +/sbin/ldconfig +# from contacts-service-bin.postinst +contacts-service-ipcd schema +chown :6005 /opt/usr/data/contacts-svc +chown :6005 /opt/usr/dbspace/.contacts-svc.db +chown :6005 /opt/usr/dbspace/.contacts-svc.db-journal +if [ -f /usr/lib/rpm-plugins/msm.so ] +then + chsmack -a 'contacts-service::db' /opt/usr/dbspace/.contacts-svc.db* +fi +chown :6005 -R /opt/usr/data/contacts-svc/img +chown :6005 /opt/usr/data/contacts-svc/.CONTACTS_SVC_*_CHANGED + +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_* +vconftool set -t int file/private/contacts-service/default_lang 1 -g 6005 +vconftool set -t int file/private/contacts-service/secondary_lang 2 -g 6005 +vconftool set -t string db/contacts-svc/secondary_lang en_US -g 6005 + +# from libcontacts-service.postinst +chown :6016 /opt/usr/data/contacts-svc/.CONTACTS_SVC_RESTRICTION_CHECK +vconftool set -t int db/contacts-svc/name_sorting_order 0 -g 6005 +vconftool set -t int db/contacts-svc/name_display_order 0 -g 6005 %postun -p /sbin/ldconfig -%files +%files -n contacts-service2 +%manifest contacts-service2.manifest %defattr(-,root,root,-) -%attr(0660,root,db_contact)/opt/data/contacts-svc/.CONTACTS_SVC_* -%{_libdir}/libcontacts-service.so* -%{_bindir}/contacts-svc-helper -%attr(0755,root,root) /etc/rc.d/init.d/contacts-svc-helper.sh - -%files devel +%{_libdir}/libcontacts-service2.so.* +%{_libdir}/libcontacts-service3.so.* +%{_bindir}/contacts-service-ipcd* +/etc/rc.d/rc*.d/S50contacts-svc-helper +/opt/usr/data/contacts-svc/.CONTACTS_SVC_* +/opt/usr/data/contacts-svc/img/* +%attr(0755,root,root) /etc/rc.d/init.d/contacts-service-ipcd.sh +%{_libdir}/systemd/user/contacts-service.service +%{_libdir}/systemd/user/tizen-middleware.target.wants/contacts-service.service + + +%files -n contacts-service2-devel %defattr(-,root,root,-) -%{_libdir}/*.so -%{_libdir}/pkgconfig/contacts-service.pc -%{_includedir}/contacts-svc/*.h +%{_libdir}/libcontacts-service2.so +%{_libdir}/libcontacts-service3.so +%{_libdir}/pkgconfig/contacts-service2.pc +%{_libdir}/pkgconfig/contacts-service3.pc +%{_includedir}/contacts-svc/contacts.h +%{_includedir}/contacts-svc/contacts_*.h diff --git a/res/.CONTACTS_SVC_AB_CHANGED b/res/.CONTACTS_SVC_AB_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_AB_CHANGED diff --git a/res/.CONTACTS_SVC_ACTIVITY_CHANGED b/res/.CONTACTS_SVC_ACTIVITY_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_ACTIVITY_CHANGED diff --git a/res/.CONTACTS_SVC_ADDRESS_CHANGED b/res/.CONTACTS_SVC_ADDRESS_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_ADDRESS_CHANGED diff --git a/res/.CONTACTS_SVC_COMPANY_CHANGED b/res/.CONTACTS_SVC_COMPANY_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_COMPANY_CHANGED diff --git a/res/.CONTACTS_SVC_DATA_CHANGED b/res/.CONTACTS_SVC_DATA_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_DATA_CHANGED diff --git a/res/.CONTACTS_SVC_DB_CHANGED b/res/.CONTACTS_SVC_DB_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_DB_CHANGED diff --git a/res/.CONTACTS_SVC_EMAIL_CHANGED b/res/.CONTACTS_SVC_EMAIL_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_EMAIL_CHANGED diff --git a/res/.CONTACTS_SVC_EVENT_CHANGED b/res/.CONTACTS_SVC_EVENT_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_EVENT_CHANGED diff --git a/res/.CONTACTS_SVC_FAVOR_CHANGED b/res/.CONTACTS_SVC_FAVOR_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_FAVOR_CHANGED diff --git a/res/.CONTACTS_SVC_GROUP_CHANGED b/res/.CONTACTS_SVC_GROUP_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_GROUP_CHANGED diff --git a/res/.CONTACTS_SVC_GROUP_RELATION_CHANGED b/res/.CONTACTS_SVC_GROUP_RELATION_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_GROUP_RELATION_CHANGED diff --git a/res/.CONTACTS_SVC_GROUP_REL_CHANGED b/res/.CONTACTS_SVC_GROUP_REL_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_GROUP_REL_CHANGED diff --git a/res/.CONTACTS_SVC_IMAGE_CHANGED b/res/.CONTACTS_SVC_IMAGE_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_IMAGE_CHANGED diff --git a/res/.CONTACTS_SVC_MESSENGER_CHANGED b/res/.CONTACTS_SVC_MESSENGER_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_MESSENGER_CHANGED diff --git a/res/.CONTACTS_SVC_MISSED_CHANGED b/res/.CONTACTS_SVC_MISSED_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_MISSED_CHANGED diff --git a/res/.CONTACTS_SVC_MY_PROFILE_CHANGED b/res/.CONTACTS_SVC_MY_PROFILE_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_MY_PROFILE_CHANGED diff --git a/res/.CONTACTS_SVC_NAME_CHANGED b/res/.CONTACTS_SVC_NAME_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_NAME_CHANGED diff --git a/res/.CONTACTS_SVC_NICKNAME_CHANGED b/res/.CONTACTS_SVC_NICKNAME_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_NICKNAME_CHANGED diff --git a/res/.CONTACTS_SVC_NOTE_CHANGED b/res/.CONTACTS_SVC_NOTE_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_NOTE_CHANGED diff --git a/res/.CONTACTS_SVC_NUMBER_CHANGED b/res/.CONTACTS_SVC_NUMBER_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_NUMBER_CHANGED diff --git a/res/.CONTACTS_SVC_PERSON_CHANGED b/res/.CONTACTS_SVC_PERSON_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_PERSON_CHANGED diff --git a/res/.CONTACTS_SVC_PLOG_CHANGED b/res/.CONTACTS_SVC_PLOG_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_PLOG_CHANGED diff --git a/res/.CONTACTS_SVC_PROFILE_CHANGED b/res/.CONTACTS_SVC_PROFILE_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_PROFILE_CHANGED diff --git a/res/.CONTACTS_SVC_RELATIONSHIP_CHANGED b/res/.CONTACTS_SVC_RELATIONSHIP_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_RELATIONSHIP_CHANGED diff --git a/res/.CONTACTS_SVC_RESTRICTION_CHECK b/res/.CONTACTS_SVC_RESTRICTION_CHECK new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_RESTRICTION_CHECK diff --git a/res/.CONTACTS_SVC_SDN_CHANGED b/res/.CONTACTS_SVC_SDN_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_SDN_CHANGED diff --git a/res/.CONTACTS_SVC_SIMPLE_CONTACT_CHANGED b/res/.CONTACTS_SVC_SIMPLE_CONTACT_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_SIMPLE_CONTACT_CHANGED diff --git a/res/.CONTACTS_SVC_SPEED_CHANGED b/res/.CONTACTS_SVC_SPEED_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_SPEED_CHANGED diff --git a/res/.CONTACTS_SVC_URL_CHANGED b/res/.CONTACTS_SVC_URL_CHANGED new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/.CONTACTS_SVC_URL_CHANGED diff --git a/res/Not empty folder b/res/Not empty folder new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/res/Not empty folder @@ -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. @@ -21,113 +21,166 @@ --PRAGMA journal_mode = PERSIST; --PRAGMA journal_mode = TRUNCATE; +CREATE TABLE persons +( + 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, + image_thumbnail_path TEXT, + image_path TEXT, + link_count INTEGER, + account_id1 INTEGER, + account_id2 INTEGER, + account_id3 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 -); ---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; + addressbook_id INTEGER PRIMARY KEY AUTOINCREMENT, + addressbook_name TEXT NOT NULL, + account_id INTEGER, + mode INTEGER, -- permission + last_sync_ver INTEGER, + UNIQUE(addressbook_name) +); + +insert into addressbooks(addressbook_id, addressbook_name, mode, account_id) values(0, 'http://tizen.org/addressbook/phone', 0, 0); + 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 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, -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, -outgoing_count INTEGER DEFAULT 0, -uid TEXT, -ringtone TEXT, -note TEXT, -image0 TEXT, -- normal image -image1 TEXT, -- full image -person_id INTEGER -); -CREATE INDEX contacts_ver_idx ON contacts(changed_ver); -CREATE INDEX contacts_person_idx ON contacts(person_id); + 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_restricted INTEGER DEFAULT 0, + is_favorite INTEGER DEFAULT 0, + deleted INTEGER DEFAULT 0, + display_name TEXT, + reverse_display_name TEXT, + display_name_source INTEGER, + display_name_language INTEGER, + sortkey TEXT COLLATE NOCASE, + reverse_sortkey TEXT COLLATE NOCASE, + created_ver INTEGER NOT NULL, + changed_ver INTEGER NOT NULL, + changed_time INTEGER NOT NULL, + uid TEXT, + ringtone_path TEXT, + vibration TEXT, + image_thumbnail_path TEXT, + image_path TEXT +); + +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(display_name_language, reverse_sortkey); + 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 + SELECT _CONTACT_DELETE_(old.contact_id, old.image_thumbnail_path, old.image_path); + 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; + UPDATE persons SET dirty=1 WHERE person_id = old.person_id AND link_count > 1; + END; + +CREATE TRIGGER trg_contacts_del2 AFTER DELETE ON contacts + WHEN old.addressbook_id IN (SELECT addressbook_id from addressbooks WHERE addressbook_id = old.addressbook_id) + BEGIN + INSERT INTO contact_deleteds VALUES(old.contact_id, old.addressbook_id, (SELECT ver FROM cts_version) + 1); + END; -CREATE TABLE deleteds +CREATE TRIGGER trg_contacts_update AFTER UPDATE ON contacts + WHEN new.deleted = 1 + BEGIN + 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; + END; + +CREATE TABLE contact_deleteds ( -contact_id INTEGER, -addrbook_id INTEGER, -deleted_ver INTEGER + contact_id INTEGER PRIMARY KEY, + addressbook_id INTEGER, + deleted_ver INTEGER ); -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 -( -id INTEGER PRIMARY KEY AUTOINCREMENT, -type INTEGER, -name TEXT, -number TEXT -); +INSERT INTO cts_version VALUES(0); -CREATE TABLE custom_types +CREATE TABLE sdn ( -id INTEGER PRIMARY KEY AUTOINCREMENT, -class INTEGER, -name TEXT, -UNIQUE(class, name) + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT, + number TEXT ); -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, -datatype INTEGER NOT NULL, -data1 INTEGER, -data2 TEXT, -data3 TEXT, -data4 TEXT, -data5 TEXT, -data6 TEXT, -data7 TEXT, -data8 TEXT, -data9 TEXT, -data10 TEXT, -person_id INTEGER + 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_del AFTER DELETE ON data + BEGIN + SELECT _DATA_DELETE_(old.id, old.datatype); + 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); @@ -139,82 +192,191 @@ CREATE INDEX data_idx7 ON data(data7); CREATE INDEX data_idx8 ON data(data8); CREATE INDEX data_idx9 ON data(data9); CREATE INDEX data_idx10 ON data(data10); -CREATE INDEX data_person_idx ON data(person_id); CREATE TABLE groups ( -group_id INTEGER PRIMARY KEY AUTOINCREMENT, -addrbook_id INTEGER, -group_name TEXT, -ringtone TEXT, -UNIQUE(addrbook_id, group_name) + group_id INTEGER PRIMARY KEY AUTOINCREMENT, + addressbook_id INTEGER, + group_name TEXT, + system_id 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, + member_changed_ver INTEGER ); + +INSERT INTO groups(addressbook_id, group_name, system_id, is_read_only, created_ver, changed_ver) + VALUES(0, 'family', 'family', 1, 0, 0); +INSERT INTO groups(addressbook_id, group_name, system_id, is_read_only, created_ver, changed_ver) + VALUES(0, 'friends', 'friends',1, 0, 0); +INSERT INTO groups(addressbook_id, group_name, system_id, is_read_only, created_ver, changed_ver) + VALUES(0, 'coworkers', 'coworkers', 1, 0, 0); + CREATE TRIGGER trg_groups_del AFTER DELETE ON groups BEGIN DELETE FROM group_relations WHERE group_id = old.group_id; END; +CREATE TABLE group_deleteds +( + group_id INTEGER PRIMARY KEY, + addressbook_id INTEGER, + deleted_ver INTEGER +); + +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 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 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 contact_id = old.related_id; - END; -CREATE TRIGGER trg_favorite_insert AFTER INSERT ON favorites - BEGIN - UPDATE data SET data3 = 1 WHERE new.type = 1 AND id = new.related_id AND datatype = 8; - UPDATE contacts SET is_favorite = 1 WHERE new.type = 0 AND contact_id = new.related_id; - END; +CREATE INDEX favorites_idx1 ON favorites(favorite_prio); +CREATE INDEX favorites_idx2 ON favorites(person_id); + + +--CREATE TRIGGER trg_favorites_del BEFORE DELETE ON favorites +-- BEGIN +-- UPDATE contacts SET is_favorite = 0 WHERE person_id = old.person_id; +-- END; +--CREATE TRIGGER trg_favorites_insert AFTER INSERT ON favorites +-- BEGIN +-- UPDATE contacts SET is_favorite = 1 WHERE person_id = new.person_id; +-- END; + CREATE TABLE phonelogs ( -id INTEGER PRIMARY KEY AUTOINCREMENT, -number TEXT, -normal_num TEXT, -related_id INTEGER, --contact_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); + id INTEGER PRIMARY KEY AUTOINCREMENT, + number TEXT, + normal_num TEXT, + person_id INTEGER, --person_id + log_type INTEGER, + log_time INTEGER, + data1 INTEGER, --duration, message_id + data2 TEXT -- short message +); + +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 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; + +--CREATE TABLE phonelog_accumulation +--( +-- id INTEGER PRIMARY KEY AUTOINCREMENT, +-- log_cnt INTEGER, +-- log_time INTEGER, +-- duration INTEGER +--); +--INSERT INTO phonelog_accumulation VALUES(1, 0, NULL, 0); +--INSERT INTO phonelog_accumulation VALUES(2, 0, NULL, 0); --total + +CREATE TABLE phonelog_stat +( + log_type INTEGER PRIMARY KEY, + log_count INTEGER +); + +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 phonelog_accumulation +CREATE TABLE contact_stat ( -id INTEGER PRIMARY KEY AUTOINCREMENT, -log_cnt INTEGER, -log_time INTEGER, -duration INTEGER + id INTEGER PRIMARY KEY AUTOINCREMENT, + person_id INTEGER, + usage_type INTEGER, + times_used INTEGER ); -INSERT INTO phonelog_accumulation VALUES(1, 0, NULL, 0); -INSERT INTO phonelog_accumulation VALUES(2, 0, NULL, 0); --total + +CREATE TABLE activities +( + id INTEGER PRIMARY KEY AUTOINCREMENT, + contact_id INTEGER NOT NULL, + source_name TEXT, + status TEXT, + timestamp INTEGER, + sync_data1 TEXT, + sync_data2 TEXT, + sync_data3 TEXT, + sync_data4 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 my_profiles +( + my_profile_id INTEGER PRIMARY KEY AUTOINCREMENT, + addressbook_id INTEGER NOT NULL DEFAULT 0, + display_name TEXT, + created_ver INTEGER NOT NULL, + changed_ver INTEGER NOT NULL, + changed_time INTEGER NOT NULL, + uid TEXT, + image_thumbnail_path TEXT, + UNIQUE(addressbook_id) +); + +CREATE TRIGGER trg_my_profiles_del AFTER DELETE ON my_profiles + BEGIN +-- It should be implemented SELECT _MY_PROFILE_DELETE_(old.my_profile_id); + 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 index 0000000..c752343 --- /dev/null +++ b/server/CMakeLists.txt @@ -0,0 +1,175 @@ +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_phonelog.c + ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_result.c + ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_sdn.c + ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_simple_contact.c + ${CMAKE_SOURCE_DIR}/common/ipc/ctsvc_ipc_speeddial.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.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_localize_ch.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_normalize.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_phonelog.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_record_result.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_record_sdn.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_record_speeddial.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_record_updated_info.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_setting.c + ${CMAKE_SOURCE_DIR}/common/ctsvc_sim.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_init.c + ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_activity.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_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_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_phonelog.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_sdn.c + + ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_simple_contact.c + ${CMAKE_SOURCE_DIR}/native/ctsvc_db_plugin_speeddial.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_phonelog.c + ${CMAKE_SOURCE_DIR}/native/ctsvc_restriction.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_notification.c + + ctsvc_ipc_server.c + ctsvc_ipc_server2.c + ctsvc_ipc_server_sim.c + ctsvc_server_socket.c + ctsvc_server_sim.c + ctsvc_server_sqlite.c + ctsvc_server_utils.c + ctsvc_server_change_subject.c + ctsvc_schema_recovery.c + ctsvc_server_bg.c + ctsvc_server.c +) + +INCLUDE(FindPkgConfig) +pkg_check_modules(ctsvc_server_pkgs REQUIRED glib-2.0 pims-ipc gobject-2.0 tapi dlog capi-media-image-util badge) + +FOREACH(flag ${ctsvc_server_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +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) +INSTALL(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/contacts-service-ipcd.sh DESTINATION /etc/rc.d/init.d) diff --git a/server/contacts-service-ipcd.sh b/server/contacts-service-ipcd.sh new file mode 100755 index 0000000..98626bf --- /dev/null +++ b/server/contacts-service-ipcd.sh @@ -0,0 +1,3 @@ +#dlogutil -v threadtime -f /var/log/contacts-service-ipcd.log -r 1000 -n 10 CONTACTS_SERVICE & + +/usr/bin/contacts-service-ipcd & diff --git a/server/ctsvc_ipc_server.c b/server/ctsvc_ipc_server.c new file mode 100644 index 0000000..fa38d82 --- /dev/null +++ b/server/ctsvc_ipc_server.c @@ -0,0 +1,1562 @@ +/* + * 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 "ctsvc_service.h" +#include "ctsvc_db_init.h" +#include "ctsvc_db_query.h" + +#include "ctsvc_ipc_marshal.h" +#include "ctsvc_internal.h" +#include "ctsvc_ipc_server.h" + +void ctsvc_ipc_server_connect(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata) +{ + int ret = CONTACTS_ERROR_NONE; + + ret = contacts_connect2(); + + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + ERR("pims_ipc_data_put fail"); + return; + } + } + else + { + ERR("outdata is NULL"); + } + return; +} + +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_disconnect2(); + + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + ERR("pims_ipc_data_put fail"); + return; + } + } + else + { + ERR("outdata is NULL"); + } + 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) + { + ERR("ctsvc_ipc_unmarshal_record fail"); + record = NULL; + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + if (ret == CONTACTS_ERROR_NONE) + { + if (ctsvc_ipc_marshal_int(id,*outdata) != CONTACTS_ERROR_NONE) + { + pims_ipc_data_destroy(*outdata); + ERR("ctsvc_ipc_marshal fail"); + ret = CONTACTS_ERROR_INVALID_PARAMETER; + goto ERROR_RETURN; + } + } + } + else + { + ERR("outdata is NULL"); + } + goto DATA_FREE; + // goto 주의.. +ERROR_RETURN: + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_string fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata,&id); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else + { + ERR("ctsvc_ipc_server_db_insert_record fail"); + goto ERROR_RETURN; + } + + ret = contacts_db_get_record(view_uri,id,&record); + + // goto 주의.. +ERROR_RETURN: + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + 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; + ERR("ctsvc_ipc_marshal_record fail"); + goto DATA_FREE; + } + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_record fail"); + goto ERROR_RETURN; + } + } + else + { + ERR("ctsvc_ipc_server_db_insert_record fail"); + goto ERROR_RETURN; + } + + ret = contacts_db_update_record(record); + + // goto 주의.. +ERROR_RETURN: + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_record fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata,&id); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else + { + ERR("ctsvc_ipc_server_db_insert_record fail"); + goto ERROR_RETURN; + } + + ret = contacts_db_delete_record(view_uri,id); + + // goto 주의.. +ERROR_RETURN: + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else + { + 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) { + ERR("ctsvc_ipc_unmarshal_record fail"); + record = NULL; + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata, &id); + if (ret != CONTACTS_ERROR_NONE) { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else { + ERR("ctsvc_ipc_server_db_replace_record fail"); + goto ERROR_RETURN; + } + + ret = contacts_db_replace_record(record, id); + +ERROR_RETURN: + if (outdata) { + *outdata = pims_ipc_data_create(0); + if (!*outdata) { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else { + 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) + { + ERR("ctsvc_ipc_unmarshal_record fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata,&offset); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata,&limit); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + 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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto DATA_FREE; + } + } + + } + else + { + ERR("outdata is NULL"); + } + + goto DATA_FREE; + + // goto 주의.. +ERROR_RETURN: + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_record fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata,&offset); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata,&limit); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + 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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto DATA_FREE; + } + } + } + else + { + ERR("outdata is NULL"); + } + goto DATA_FREE; + + // goto 주의.. +ERROR_RETURN: + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_record fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + 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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto DATA_FREE; + } + } + } + else + { + ERR("outdata is NULL"); + } + goto DATA_FREE; + + // goto 주의.. +ERROR_RETURN: + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_record fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + 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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto DATA_FREE; + } + } + } + else + { + ERR("outdata is NULL"); + } + goto DATA_FREE; + + // goto 주의.. +ERROR_RETURN: + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_list fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + + if(ret == CONTACTS_ERROR_NONE) + { + contacts_record_h record = NULL; + // 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; + ERR("pims_ipc_data_put fail"); + ret = CONTACTS_ERROR_INVALID_PARAMETER; + goto ERROR_RETURN; + } + for(i=0;i<id_count;i++) + { + record = NULL; + // marshal ids + if (pims_ipc_data_put(*outdata,(void*)&ids[i],sizeof(int)) != 0) + { + pims_ipc_data_destroy(*outdata); + *outdata = NULL; + ERR("pims_ipc_data_put fail"); + ret = CONTACTS_ERROR_INVALID_PARAMETER; + goto ERROR_RETURN; + } + } + } + } + else + { + ERR("outdata is NULL"); + } + goto DATA_FREE; + + // goto 주의.. +ERROR_RETURN: + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_list fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else + { + ERR("outdata is NULL"); + } + goto DATA_FREE; + + // goto 주의.. +ERROR_RETURN: + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_string fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata,&count); + if (ret != CONTACTS_ERROR_NONE) + { + 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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + } + else + { + 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) + { + ERR("pims_ipc_data_create fail"); + } + if (pims_ipc_data_put(*outdata,(void*)&ret,sizeof(int)) != 0) + { + pims_ipc_data_destroy(*outdata); + *outdata = NULL; + ERR("pims_ipc_data_put fail"); + } + } + else + { + ERR("outdata is NULL"); + } + + goto DATA_FREE; + + // goto 주의.. +ERROR_RETURN: + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else + { + 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; + unsigned int count = 0; + int *ids = NULL; + int i=0; + + if (indata) { + ret = ctsvc_ipc_unmarshal_list(indata, &list); + if (ret != CONTACTS_ERROR_NONE) { + ERR("ctsvc_ipc_unmarshal_list fail"); + goto ERROR_RETURN; + } + + ret = ctsvc_ipc_unmarshal_unsigned_int(indata, &count); + if (ret != CONTACTS_ERROR_NONE) { + 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) { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + } + else { + 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) { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else { + ERR("outdata is NULL"); + } + goto DATA_FREE; + +ERROR_RETURN: + if (outdata) { + *outdata = pims_ipc_data_create(0); + if (!*outdata) { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else { + 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) + { + ERR("ctsvc_ipc_unmarshal_string fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata, &address_book_id); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata,&contacts_db_version); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else + { + 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,¤t_contacts_db_version); + + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + 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) + { + ERR("ctsvc_ipc_unmarshal_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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + pims_ipc_data_destroy(*outdata); + *outdata = NULL; + ret = CONTACTS_ERROR_OUT_OF_MEMORY; + goto ERROR_RETURN; + } + } + } + else + { + ERR("outdata is NULL"); + } + goto DATA_FREE; + + // goto 주의.. +ERROR_RETURN: + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else + { + 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) + { + 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; + 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) + { + ERR("ctsvc_ipc_marshal_int fail"); + return; + } + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_record fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_string(indata,&keyword); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_record fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata,&offset); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata,&limit); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + 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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto DATA_FREE; + } + } + } + else + { + ERR("outdata is NULL"); + } + goto DATA_FREE; + + // goto 주의.. +ERROR_RETURN: + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else + { + 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_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) + { + ERR("ctsvc_ipc_unmarshal_record fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_string(indata,&keyword); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_record fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata,&offset); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata,&limit); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + 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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto DATA_FREE; + } + } + } + else + { + ERR("outdata is NULL"); + } + goto DATA_FREE; + + // goto 주의.. +ERROR_RETURN: + if (outdata) + { + *outdata = pims_ipc_data_create(0); + if (!*outdata) + { + 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; + ERR("pims_ipc_data_put fail"); + goto DATA_FREE; + } + } + else + { + ERR("outdata is NULL"); + } +DATA_FREE: + + if (list) + { + contacts_list_destroy(list,true); + } + if (query) + { + contacts_query_destroy(query); + } + CONTACTS_FREE(keyword); + + return; +} + diff --git a/server/ctsvc_ipc_server.h b/server/ctsvc_ipc_server.h new file mode 100644 index 0000000..852e47b --- /dev/null +++ b/server/ctsvc_ipc_server.h @@ -0,0 +1,52 @@ +/* + * Calendar 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); + +// 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_query(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 index 0000000..f737743 --- /dev/null +++ b/server/ctsvc_ipc_server2.c @@ -0,0 +1,661 @@ +/* + * 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 "ctsvc_service.h" +#include "ctsvc_db_init.h" + +#include "ctsvc_ipc_marshal.h" +#include "ctsvc_internal.h" +#include "ctsvc_ipc_server.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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + ERR("pims_ipc_data_put fail"); + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + ERR("pims_ipc_data_put fail"); + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata, &contact_id); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + ERR("pims_ipc_data_put fail"); + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata, &contact_id); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + ERR("pims_ipc_data_put fail"); + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata, &person_id); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + ERR("pims_ipc_data_put fail"); + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata, &contact_id); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + ERR("pims_ipc_data_put fail"); + return; + } + if (pims_ipc_data_put(*outdata, (void*)&unlinked_person_id, sizeof(int)) != 0) + { + pims_ipc_data_destroy(*outdata); + *outdata = NULL; + ERR("pims_ipc_data_put fail"); + } + + } + else + { + 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) + { + 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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + ERR("pims_ipc_data_put fail"); + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata, &previous_person_id); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata, &next_person_id); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + ERR("pims_ipc_data_put fail"); + } + } + else + { + 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) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_unsigned_int(indata, &property); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_int(indata, &id); + if (ret != CONTACTS_ERROR_NONE) + { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else + { + 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) + { + 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; + ERR("pims_ipc_data_put fail"); + } + } + else + { + 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) { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + ret = ctsvc_ipc_unmarshal_unsigned_int(indata, &op); + if (ret != CONTACTS_ERROR_NONE) { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + } + else { + 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) { + 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; + 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; + ERR("pims_ipc_data_put fail (id)"); + return; + } + } + else { + ERR("outdata is NULL"); + } + + return; +} + +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) + { + 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; + ERR("pims_ipc_data_put fail"); + } + } + else + { + 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) { + 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) { + 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) { + ERR("ctsvc_ipc_unmarshal_int fail"); + goto ERROR_RETURN; + } + ret = contacts_phone_log_delete(op, extra_data1); + break; + default: + 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) { + 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; + ERR("pims_ipc_data_put fail"); + } + } +} + diff --git a/server/ctsvc_ipc_server2.h b/server/ctsvc_ipc_server2.h new file mode 100644 index 0000000..a5486f9 --- /dev/null +++ b/server/ctsvc_ipc_server2.h @@ -0,0 +1,41 @@ +/* + * Calendar 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_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); + +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 /*__CTSVC_IPC_SERVER2_H__*/ diff --git a/server/ctsvc_ipc_server_sim.c b/server/ctsvc_ipc_server_sim.c new file mode 100644 index 0000000..c50ee4f --- /dev/null +++ b/server/ctsvc_ipc_server_sim.c @@ -0,0 +1,43 @@ +/* + * 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 "ctsvc_service.h" +#include "ctsvc_db_init.h" + +#include "ctsvc_ipc_marshal.h" +#include "ctsvc_internal.h" +#include "ctsvc_ipc_server_sim.h" + +void ctsvc_ipc_sim_insert_contact(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata) +{ + return; +} + +void ctsvc_ipc_sim_update_contact(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata) +{ + return; +} + +void ctsvc_ipc_sim_delete_contact(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata) +{ + return; +} + diff --git a/server/ctsvc_ipc_server_sim.h b/server/ctsvc_ipc_server_sim.h new file mode 100644 index 0000000..5ef8f5d --- /dev/null +++ b/server/ctsvc_ipc_server_sim.h @@ -0,0 +1,28 @@ +/* + * Calendar 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_SIM_H__ +#define __CTSVC_IPC_SERVER_SIM_H__ + +#include <pims-ipc-data.h> + +void ctsvc_ipc_sim_insert_contact(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata); +void ctsvc_ipc_sim_update_contact(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata); +void ctsvc_ipc_sim_delete_contact(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata); + +#endif /*__CTSVC_IPC_SERVER_SIM_H__*/ diff --git a/server/ctsvc_schema_recovery.c b/server/ctsvc_schema_recovery.c new file mode 100755 index 0000000..e4e9642 --- /dev/null +++ b/server/ctsvc_schema_recovery.c @@ -0,0 +1,91 @@ +/* + * Contacts Service Helper + * + * 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 "internal.h" +#include "ctsvc_server_sqlite.h" +#include "schema.h" +#include "ctsvc_schema_recovery.h" +#include "ctsvc_schema.h" + +static inline int __ctsvc_server_check_db_file(void) +{ + int fd = open(CTSVC_DB_PATH, O_RDONLY); + h_retvm_if(-1 == fd, CTSVC_ERR_NO_DB_FILE, + "DB file(%s) is not exist", CTSVC_DB_PATH); + + 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); + h_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) { + 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); + h_retvm_if(-1 == fd, CONTACTS_ERROR_SYSTEM, "open Failed"); + + ret = fchown(fd, getuid(), CTS_SECURITY_FILE_GROUP); + if (0 != ret) + ERR("fchown(%s) Failed(%d)", CTSVC_DB_PATH, ret); + ret = fchmod(fd, CTS_SECURITY_DEFAULT_PERMISSION); + if (0 != ret) + ERR("fchown(%s) Failed(%d)", CTSVC_DB_PATH, ret); + close(fd); + + fd = open(CTSVC_DB_JOURNAL_PATH, O_CREAT | O_RDWR, 0660); + h_retvm_if(-1 == fd, CONTACTS_ERROR_SYSTEM, "open Failed"); + + ret = fchown(fd, getuid(), CTS_SECURITY_FILE_GROUP); + if (0 != ret) + ERR("fchown(%s) Failed(%d)", CTSVC_DB_JOURNAL_PATH, ret); + ret = fchmod(fd, CTS_SECURITY_DEFAULT_PERMISSION); + if (0 != ret) + ERR("fchown(%s) Failed(%d)", CTSVC_DB_JOURNAL_PATH, ret); + close(fd); + + 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(); + + return CONTACTS_ERROR_NONE; +} + diff --git a/server/ctsvc_schema_recovery.h b/server/ctsvc_schema_recovery.h new file mode 100755 index 0000000..fa4f8b2 --- /dev/null +++ b/server/ctsvc_schema_recovery.h @@ -0,0 +1,26 @@ +/* + * Contacts Service Helper + * + * 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_SCHEMA_RECOVERY_H__ +#define __CTSVC_SERVER_SCHEMA_RECOVERY_H__ + +int ctsvc_server_check_schema(); + +#endif // __CTSVC_SERVER_SCHEMA_RECOVERY_H__ + + diff --git a/server/ctsvc_server.c b/server/ctsvc_server.c new file mode 100644 index 0000000..593c1fc --- /dev/null +++ b/server/ctsvc_server.c @@ -0,0 +1,146 @@ +/* + * 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 <unistd.h> //getuid +#include <pims-ipc.h> +#include <pims-ipc-svc.h> + +#include "internal.h" // DBG +#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_ipc_define.h" +#include "ctsvc_ipc_server.h" +#include "ctsvc_ipc_server2.h" +#include "ctsvc_ipc_server_sim.h" + +//static GMainLoop *loop; + +static int __server_main(); + +static int __server_main(void) +{ + int ret; + pims_ipc_svc_init(CTSVC_IPC_SOCKET_PATH, CTS_SECURITY_FILE_GROUP, 0777); + + do { + 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_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_QUERY, ctsvc_ipc_server_db_search_records_with_query, 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_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; + + 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; + + /* + if (pims_ipc_svc_register(CTSVC_IPC_SIM_MODULE, CTSVC_IPC_SERVER_SIM_IMPORT_ALL_CONTACTS, ctsvc_ipc_sim_import_all_contacts, NULL) != 0) break; + if (pims_ipc_svc_register(CTSVC_IPC_SIM_MODULE, CTSVC_IPC_SERVER_SIM_EXPORT_PERSON, ctsvc_ipc_sim_export_person, NULL) != 0) break; + */ + if (pims_ipc_svc_register(CTSVC_IPC_SIM_MODULE, CTSVC_IPC_SERVER_SIM_INSERT_CONTACT, ctsvc_ipc_sim_insert_contact, NULL) != 0) break; + if (pims_ipc_svc_register(CTSVC_IPC_SIM_MODULE, CTSVC_IPC_SERVER_SIM_UPDATE_CONTACT, ctsvc_ipc_sim_update_contact, NULL) != 0) break; + if (pims_ipc_svc_register(CTSVC_IPC_SIM_MODULE, CTSVC_IPC_SERVER_SIM_DELETE_CONTACT, ctsvc_ipc_sim_delete_contact, NULL) != 0) break; + + pims_ipc_svc_init_for_publish(CTSVC_IPC_SOCKET_PATH_FOR_CHANGE_SUBSCRIPTION, CTS_SECURITY_FILE_GROUP, 0660); + + ret = contacts_connect2(); + if (CONTACTS_ERROR_NONE != ret) {
+ SERVER_DBG("contacts_connect2 fail(%d)", ret); + break; + } + + ctsvc_server_bg_add_cb(); + ctsvc_server_bg_delete_start(); + + ret = ctsvc_server_init_configuration(); + SERVER_DBG("%d", ret); + + pims_ipc_svc_run_main_loop(NULL); + + ctsvc_server_final_configuration(); + + ctsvc_server_bg_remove_cb(); + + ret = contacts_disconnect2(); + if (CONTACTS_ERROR_NONE != ret)
+ SERVER_DBG("%d", ret); + + pims_ipc_svc_deinit_for_publish(); + + pims_ipc_svc_deinit(); + + return 0; + + } while(0); + + ERR("pims_ipc_svc_register error"); + return -1; +} + +int main(int argc, char *argv[]) +{ + SERVER_FN_CALL; + int ret; + ctsvc_server_check_schema(); + if (2 <= argc && !strcmp(argv[1], "schema")) + return CONTACTS_ERROR_NONE; + + ret = ctsvc_server_socket_init(); + SERVER_DBG("%d", ret); + + __server_main(); + + return 0; +} + diff --git a/server/ctsvc_server_bg.c b/server/ctsvc_server_bg.c new file mode 100644 index 0000000..eefa170 --- /dev/null +++ b/server/ctsvc_server_bg.c @@ -0,0 +1,383 @@ +/*
+ * 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
+
+#include "contacts.h"
+#include "internal.h"
+#include "ctsvc_schema.h"
+#include "ctsvc_sqlite.h"
+#include "ctsvc_server_bg.h"
+#include "ctsvc_utils.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"
+
+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;
+
+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");
+ stmt = cts_query_prepare(query);
+ if (NULL == stmt) {
+ ERR("cts_query_prepare() Failed");
+ return CONTACTS_ERROR_DB;
+ }
+
+ while(1 == (ret = cts_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));
+ }
+ cts_stmt_finalize(stmt);
+ }
+
+ count = g_slist_length(data->contact_ids);
+ if (count <= 0)
+ return CONTACTS_ERROR_DB;
+
+ 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)
+{
+ SERVER_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);
+
+ stmt = cts_query_prepare(query);
+ if (NULL == stmt) {
+ ERR("cts_query_prepare() Failed");
+ return CONTACTS_ERROR_DB;
+ }
+
+ while(1 == (ret = cts_stmt_step(stmt))) {
+ int id = 0;
+ id = ctsvc_stmt_get_int(stmt, 0);
+ list = g_slist_append(list, GINT_TO_POINTER(id));
+ }
+ cts_stmt_finalize(stmt);
+
+ count = g_slist_length(list);
+ if (count <= 0)
+ return CONTACTS_ERROR_NO_DATA;
+
+ ret = ctsvc_begin_trans();
+ h_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);
+ SERVER_DBG("%s",query);
+ if (ret != CONTACTS_ERROR_NONE) {
+ ERR("DB failed");
+ ctsvc_end_trans(false);
+ g_slist_free(list);
+ return CONTACTS_ERROR_DB;
+ }
+ 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)
+{
+ SERVER_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);
+
+ stmt = cts_query_prepare(query);
+ if (NULL == stmt) {
+ ERR("cts_query_prepare() Failed");
+ return CONTACTS_ERROR_DB;
+ }
+
+ while(1 == (ret = cts_stmt_step(stmt))) {
+ int id = 0;
+ id = ctsvc_stmt_get_int(stmt, 0);
+ list = g_slist_append(list, GINT_TO_POINTER(id));
+ }
+ cts_stmt_finalize(stmt);
+
+ count = g_slist_length(list);
+ if (count <= 0)
+ return CONTACTS_ERROR_NO_DATA;
+
+ ret = ctsvc_begin_trans();
+ h_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);
+ SERVER_DBG("%s",query);
+ if (ret != CONTACTS_ERROR_NONE) {
+ ERR("DB failed");
+ ctsvc_end_trans(false);
+ g_slist_free(list);
+ return CONTACTS_ERROR_DB;
+ }
+ 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();
+ h_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);
+ SERVER_DBG("%s",query);
+ if (CONTACTS_ERROR_NONE != ret) {
+ ERR("DB failed");
+ ctsvc_end_trans(false);
+ return CONTACTS_ERROR_DB;
+ }
+
+ snprintf(query, sizeof(query), "DELETE FROM "CTS_TABLE_CONTACTS" WHERE contact_id = %d",
+ data->current_contact_id);
+ ret = ctsvc_query_exec(query);
+ SERVER_DBG("%s",query);
+ if (CONTACTS_ERROR_NONE != ret) {
+ ERR("DB failed");
+ ctsvc_end_trans(false);
+ return CONTACTS_ERROR_DB;
+ }
+
+ 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);
+ 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);
+ 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)
+{
+ SERVER_FN_CALL;
+ int ret = CONTACTS_ERROR_NONE;
+
+ if(data == NULL) {
+ ERR("data is NULL");
+ return false;
+ }
+
+ switch (data->step) {
+ case STEP_1:
+ ret = __ctsvc_server_bg_contact_delete_step1(data);
+ break;
+ case STEP_2:
+ ret = __ctsvc_server_bg_contact_delete_step2(data);
+ break;
+ case STEP_3:
+ ret = __ctsvc_server_bg_contact_delete_step3(data);
+ break;
+ case STEP_4:
+ ret = __ctsvc_server_bg_contact_delete_step4(data);
+ break;
+ default:
+ ERR("invalid step");
+ if(data->contact_ids)
+ g_slist_free(data->contact_ids);
+ return false;
+ }
+
+ return __ctsvc_server_bg_contact_delete_step(ret, data);
+}
+
+static gpointer __ctsvc_server_bg_delete(gpointer user_data)
+{
+ SERVER_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) {
+ ERR("calloc fail");
+ continue;
+ }
+ callback_data->step = STEP_1;
+
+ ret = contacts_connect2();
+ if (CONTACTS_ERROR_NONE != ret) {
+ SERVER_DBG("%d", ret); + free(callback_data); + continue;
+ } +
+ while(1) {
+ sleep(CTSVC_SERVER_BG_DELETE_STEP_TIME); // sleep 1 sec.
+ if (__ctsvc_server_db_delete_run(callback_data) == false) {
+ SERVER_DBG("end");
+ free(callback_data);
+ break;
+ }
+ }
+ ret = contacts_disconnect2();
+ if (CONTACTS_ERROR_NONE != ret)
+ SERVER_DBG("%d", ret);
+
+ g_mutex_lock(&__ctsvc_server_bg_delete_mutex);
+ SERVER_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()
+{
+ SERVER_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);
+}
+
+void __ctsvc_server_addressbook_deleted_cb(const char *view_uri, void *data)
+{
+ ctsvc_server_bg_delete_start();
+}
+
+int ctsvc_server_bg_add_cb()
+{
+ return contacts_db_add_changed_cb(_contacts_address_book._uri, __ctsvc_server_addressbook_deleted_cb, NULL);
+}
+
+int ctsvc_server_bg_remove_cb()
+{
+ return contacts_db_remove_changed_cb(_contacts_address_book._uri, __ctsvc_server_addressbook_deleted_cb, NULL);
+}
+
diff --git a/server/ctsvc_server_bg.h b/server/ctsvc_server_bg.h new file mode 100644 index 0000000..9ad1064 --- /dev/null +++ b/server/ctsvc_server_bg.h @@ -0,0 +1,27 @@ +/*
+ * 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.
+ *
+ */
+
+#ifndef __CTSVC_SERVER_BG_H__
+#define __CTSVC_SERVER_BG_H__
+
+void ctsvc_server_bg_delete_start();
+int ctsvc_server_bg_add_cb();
+int ctsvc_server_bg_remove_cb();
+
+#endif /* __CTSVC_SERVER_BG_H__ */
diff --git a/server/ctsvc_server_change_subject.c b/server/ctsvc_server_change_subject.c new file mode 100644 index 0000000..34d57fe --- /dev/null +++ b/server/ctsvc_server_change_subject.c @@ -0,0 +1,128 @@ +/*
+ * Contacts Service Helper
+ *
+ * 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
+
+static __thread char *__phone_log_chanaged_info = NULL;
+static __thread unsigned int __phone_log_buf_size = 0;
+
+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) {
+ ERR("pims_ipc_data_create error\n");
+ return false;
+ }
+
+ if (pims_ipc_data_put(indata, data, strlen(data) + 1) != 0) {
+ ERR("pims_ipc_data_put error\n");
+ return false;
+ }
+
+ if (pims_ipc_svc_publish(CTSVC_IPC_SUBSCRIBE_MODULE, (char*)view_uri, indata) != 0) {
+ ERR("pims_ipc_svc_publish error\n");
+ 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);
+ __ctsvc_publish_changes_with_data(_contacts_phone_log._uri, __phone_log_chanaged_info);
+ ctsvc_change_subject_clear_changed_info();
+}
+
+void ctsvc_change_subject_clear_changed_info()
+{
+ free(__phone_log_chanaged_info);
+ __phone_log_chanaged_info = NULL;
+ __phone_log_buf_size = 0;
+
+ free(__person_changed_info);
+ __person_changed_info = NULL;
+ __person_buf_size = 0;
+}
+
+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);
+}
+
+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);
+}
diff --git a/server/ctsvc_server_change_subject.h b/server/ctsvc_server_change_subject.h new file mode 100644 index 0000000..af27d00 --- /dev/null +++ b/server/ctsvc_server_change_subject.h @@ -0,0 +1,31 @@ +/*
+ * Contacts Service Helper
+ *
+ * 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_types.h"
+
+void ctsvc_change_subject_publish_changed_info();
+void ctsvc_change_subject_clear_changed_info();
+
+void ctsvc_change_subject_add_changed_phone_log_id(contacts_changed_e type, int id);
+void ctsvc_change_subject_add_changed_person_id(contacts_changed_e type, int id);
+
+#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 index 0000000..9729deb --- /dev/null +++ b/server/ctsvc_server_sim.c @@ -0,0 +1,667 @@ +/* + * Contacts Service Helper + * + * 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 <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 "internal.h" +#include "ctsvc_struct.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" + +#define PHONE_ADDRESSBOOK_ID 0 + +#define CTSVC_TAPI_SIM_PB_MAX 0xFFFF +//#define CTSVC_SIM_DATA_MAX_LENGTH 1024 + +#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 + +#define CTSVC_2GSIM_NAME TAPI_PB_3G_NAME +#define CTSVC_2GSIM_NUMBER TAPI_PB_3G_NUMBER + +static TapiHandle *ghandle = NULL; +static TelSimPbType_t gsim_type = TAPI_SIM_PB_UNKNOWNN; +static void* greturn_data = NULL; +static int gsim_addressbook_id =0; + +typedef struct { + unsigned int index_max; + unsigned int text_max; + unsigned int used_count; + + unsigned int (*get_index_max)(void *); + unsigned int (*get_text_max)(void *); + unsigned int (*get_unused_count)(void *); + void (*increase_used_count)(void *); + void (*set)(void *,int ,int ,int ); +}sim_file_s; + +static sim_file_s gfile_record[TAPI_PB_MAX_FILE_CNT]; +static GSList *gcontact_records = NULL; +static bool ginit_completed = false; + +static inline unsigned int get_index_max(void *this) +{ + return ((sim_file_s*)this)->index_max; +} + +static inline unsigned int get_unused_count(void *this) +{ + return ((sim_file_s*)this)->index_max - ((sim_file_s*)this)->used_count; +} + +static inline unsigned int get_text_max(void *this) +{ + return ((sim_file_s*)this)->text_max; +} + +static inline void increase_used_count(void *this) +{ + ((sim_file_s*)this)->used_count++; +} + +static inline void set(void *this,int index,int text,int used_count) +{ + ((sim_file_s*)this)->index_max = index; + ((sim_file_s*)this)->text_max = text; + ((sim_file_s*)this)->used_count = used_count; +} +static inline TelSimPbType_t __ctsvc_server_get_sim_type(void) +{ + return gsim_type; +} +static inline void __ctsvc_server_set_contact_records(GSList * list) +{ + gcontact_records = list; +} + +static inline GSList* __ctsvc_server_get_contact_records(void) +{ + h_retvm_if(gcontact_records == NULL, NULL, "gcontact_records is NULL"); + return gcontact_records; +} + +static inline void __ctsvc_server_sim_set_init_completed(bool init) +{ + SERVER_DBG("set ginit_completed = %d ", init); + ginit_completed = init; +} + +bool ctsvc_server_sim_get_init_completed(void) +{ + SERVER_DBG("get complete_init_flag = %d ", ginit_completed); + return ginit_completed; +} +static inline void __ctsvc_server_set_sim_addressbook_id(int id) +{ + gsim_addressbook_id = id; +} +static void __ctsvc_server_init_sim_file(void) +{ + int i= 0; + for(i = 0 ;i <TAPI_PB_MAX_FILE_CNT; i++ ){ + gfile_record[i].get_index_max = get_index_max; + gfile_record[i].get_unused_count = get_unused_count; + gfile_record[i].get_text_max = get_text_max; + gfile_record[i].set = set; + gfile_record[i].increase_used_count = increase_used_count; + gfile_record[i].index_max = 0; + gfile_record[i].text_max = 0; + gfile_record[i].used_count = 0; + } +} +static TapiHandle* __ctsvc_server_get_tapi_handle(void) +{ + if(ghandle == NULL){ + int bReady = 0; + vconf_get_bool(VCONFKEY_TELEPHONY_READY, &bReady); + + if(!bReady) { + SERVER_DBG("telephony is not ready "); + return NULL; + } + else { + ghandle = tel_init(NULL); + h_retvm_if(NULL == ghandle, NULL, "tel_init() Failed"); + } + } + return ghandle; +} + +void ctsvc_server_sim_destroy_contact_record(sim_contact_s *record) +{ + h_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_file_s * __ctsvc_server_sim_get_file_record(TelSimPb3GFileType_t file_type) +{ + return &gfile_record[file_type]; +} +int ctsvc_server_sim_finalize(void) +{ + SERVER_FN_CALL; + GSList *cursor = NULL; + sim_contact_s *record = NULL; + + int ret = 0; + if (ghandle) { + ret = tel_deinit(ghandle); + h_retvm_if(TAPI_API_SUCCESS != ret, CONTACTS_ERROR_SYSTEM, + "tel_deinit() Failed(%d)", ret); + } + + for (cursor=__ctsvc_server_get_contact_records();cursor;cursor=g_slist_next(cursor)){ + record = cursor->data; + __ctsvc_server_set_contact_records(g_slist_remove(__ctsvc_server_get_contact_records(),cursor)); + ctsvc_server_sim_destroy_contact_record(record); + } + + contacts_disconnect2(); + + return CONTACTS_ERROR_NONE; +} + +static void __ctsvc_server_set_sim_type(void) +{ + int err = 0; + TelSimCardType_t cardtype = TAPI_SIM_PB_UNKNOWNN; + err = tel_get_sim_type(__ctsvc_server_get_tapi_handle(), &cardtype); + h_retm_if(err != TAPI_API_SUCCESS,"tel_get_sim_type failed"); + + if(cardtype == TAPI_SIM_CARD_TYPE_USIM) + gsim_type = TAPI_SIM_PB_3GSIM; + else + gsim_type = TAPI_SIM_PB_ADN; +} + +static inline void __ctsvc_server_set_return_data(void* data) +{ + greturn_data = data; +} + +static inline void* __ctsvc_server_get_return_data(void) +{ + h_retvm_if(greturn_data == NULL, NULL, "ghelper_data is NULL"); + return greturn_data; +} + +static sim_contact_s * __ctsvc_server_sim_create_contact_record(TelSimPbRecord_t *sim_record) +{ + sim_contact_s *record = calloc(1,sizeof(sim_contact_s)); + record->sim_index = sim_record->index; + record->next_index = sim_record->next_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_insert_db_num(contacts_record_h *record, char *number) +{ + + int ret; + h_retvm_if(number == NULL,CONTACTS_ERROR_INVALID_PARAMETER, "invalid number"); + + ret = contacts_record_create(_contacts_number._uri, record); + h_retvm_if(ret < CONTACTS_ERROR_NONE,ret, "contacts_record_destroy() Failed(%d)", ret); + ret = contacts_record_set_str(*record, _contacts_number.number, number); + h_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_CELL); + h_retvm_if(ret < CONTACTS_ERROR_NONE,ret, "contacts_record_set_int() Failed(%d)", ret); + return ret; +} + +static inline int __ctsvc_server_insert_db_email(contacts_record_h *record, char *email) +{ + int ret; + + h_retvm_if(email == NULL,CONTACTS_ERROR_INVALID_PARAMETER, "invalid email"); + + ret = contacts_record_create(_contacts_email._uri, record); + h_retvm_if(ret < CONTACTS_ERROR_NONE,ret, "contacts_record_destroy() Failed(%d)", ret); + ret = contacts_record_set_str(*record, _contacts_email.email, email); + h_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_HOME); + h_retvm_if(ret < CONTACTS_ERROR_NONE,ret, "contacts_record_set_int() Failed(%d)", ret); + return ret; +} + +static int __ctsvc_server_insert_contact_to_db(sim_contact_s *record,int* contact_id, int addressbook_id) +{ + SERVER_FN_CALL; + int ret; + char sim_id[20] = {0}; + contacts_record_h contact = NULL; + contacts_record_h name = NULL; + contacts_record_h number = NULL; + contacts_record_h email = NULL; + contacts_record_h nick = NULL; + + h_retvm_if(record == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid paramter : record is NULL"); + h_retvm_if(contact_id == NULL, CONTACTS_ERROR_INVALID_PARAMETER, "Invalid paramter : contact_id is NULL"); + h_retvm_if(record->sim_index <= 0, CONTACTS_ERROR_INVALID_PARAMETER, "The index(%d) is invalid", record->sim_index); + + SERVER_DBG("insert record -> sim_index %d",record->sim_index); + + ret = contacts_record_create(_contacts_contact._uri, &contact); + h_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); + } + } + SERVER_DBG("insert record -> name %s", record->name); + + 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); + } + } + SERVER_DBG("insert record -> nick name %s", record->nickname); + + if (record->number) { + contacts_record_create(_contacts_number._uri, &number); + if (number) { + contacts_record_set_str(number, _contacts_number.number, (char *)record->number); + contacts_record_set_int(number, _contacts_number.type, CONTACTS_NUMBER_TYPE_CELL); + contacts_record_add_child_record(contact, _contacts_contact.number, number); + } + } + SERVER_DBG("insert record ->number %s", record->number); + + ret = __ctsvc_server_insert_db_num(&number, (char *)record->anr1); + if (CONTACTS_ERROR_NONE == ret) + contacts_record_add_child_record(contact, _contacts_contact.number, number); + SERVER_DBG("insert record ->anr1 %s", record->anr1); + + ret = __ctsvc_server_insert_db_num(&number, (char *)record->anr2); + if (CONTACTS_ERROR_NONE == ret) + contacts_record_add_child_record(contact, _contacts_contact.number, number); + SERVER_DBG("insert record ->anr2 %s", record->anr2); + + ret = __ctsvc_server_insert_db_num(&number, (char *)record->anr3); + if (CONTACTS_ERROR_NONE == ret) + contacts_record_add_child_record(contact, _contacts_contact.number, number); + SERVER_DBG("insert record ->anr3 %s", record->anr3); + + ret = __ctsvc_server_insert_db_email(&email, (char *)record->email1); + if (CONTACTS_ERROR_NONE == ret) + contacts_record_add_child_record(contact, _contacts_contact.email, email); + SERVER_DBG("insert record ->email1 %s", record->email1); + + ret = __ctsvc_server_insert_db_email(&email, (char *)record->email2); + if (CONTACTS_ERROR_NONE == ret) + contacts_record_add_child_record(contact, _contacts_contact.email, email); + SERVER_DBG("insert record ->email2 %s", record->email2); + + ret = __ctsvc_server_insert_db_email(&email, (char *)record->email3); + if (CONTACTS_ERROR_NONE == ret) + contacts_record_add_child_record(contact, _contacts_contact.email, email); + SERVER_DBG("insert record ->email3 %s", record->email3); + + ret = __ctsvc_server_insert_db_email(&email, (char *)record->email4); + if (CONTACTS_ERROR_NONE == ret) + contacts_record_add_child_record(contact, _contacts_contact.email, email); + SERVER_DBG("insert record ->email4 %s", record->email4); + + contacts_record_set_int(contact, _contacts_contact.address_book_id, addressbook_id); + ret = contacts_db_insert_record(contact, contact_id); + h_warn_if(ret < CONTACTS_ERROR_NONE, "contacts_db_insert_record() Failed(%d)", ret); + record->contact_id = *contact_id; + SERVER_DBG("inserted contact id = %d",record->contact_id); + contacts_record_destroy(contact, true); + h_warn_if(ret < CONTACTS_ERROR_NONE, "contacts_record_destroy() Failed(%d)", ret); + + return ret; +} + +static void __ctsvc_server_sim_import_read_cb(TapiHandle *handle, int result, void *data, void* user_data) +{ + SERVER_FN_CALL; + int ret = 0; + TelSimPbAccessResult_t access_rt = result; + TelSimPbRecord_t *sim_info = data; + sim_contact_s *record = NULL; + int start_index = 0; + int contact_id =0; + + if(user_data != NULL) + start_index = (int)user_data; + + + if (NULL == sim_info) { + ERR("sim_info is NULL, result = %d", access_rt); + ret = CONTACTS_ERROR_SYSTEM; + goto ERROR_RETURN; + } + + if(access_rt == TAPI_SIM_PB_INVALID_INDEX) { + SERVER_DBG("TAPI_SIM_PB_INVALID_INDEX : start_index = %d",start_index); + start_index++; //search for start index + sim_file_s *file = __ctsvc_server_sim_get_file_record(TAPI_PB_3G_NAME); + if(start_index > file->get_index_max((void*)file)){ + ERR("start_index is invalid start_index = %d, total = %d", start_index,file->get_index_max((void*)file)); + ret = CONTACTS_ERROR_SYSTEM; + goto ERROR_RETURN; + } + ret = tel_read_sim_pb_record(handle, __ctsvc_server_get_sim_type(), start_index, __ctsvc_server_sim_import_read_cb, (void*)start_index); + if(ret != TAPI_API_SUCCESS){ + 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) { + 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_create_contact_record(sim_info); + ret = __ctsvc_server_insert_contact_to_db(record, &contact_id,PHONE_ADDRESSBOOK_ID); + ctsvc_server_sim_destroy_contact_record(record); + if(ret < CONTACTS_ERROR_NONE || contact_id <= 0) { + ERR("__ctsvc_server_insert_or_update_contact_to_db is fail(%d)",ret); + goto ERROR_RETURN; + } + break; + case TAPI_SIM_PB_FDN: + case TAPI_SIM_PB_SDN: + default: + 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) { + SERVER_DBG("NextIndex = %d", sim_info->next_index); + ret = tel_read_sim_pb_record(__ctsvc_server_get_tapi_handle(), sim_info->phonebook_type, + sim_info->next_index, __ctsvc_server_sim_import_read_cb, NULL); + if (TAPI_API_SUCCESS != ret) { + ERR("tel_read_sim_pb_record() Failed(%d)", ret); + ret = CONTACTS_ERROR_SYSTEM; + goto ERROR_RETURN; + } + } + else { + if (__ctsvc_server_get_return_data()) { + ret = ctsvc_server_socket_return(__ctsvc_server_get_return_data(), CONTACTS_ERROR_NONE, 0, NULL); + h_warn_if(CONTACTS_ERROR_NONE != ret, "ctsvc_server_socket_return() Failed(%d)", ret); + __ctsvc_server_set_return_data(NULL); + } + } + return; + +ERROR_RETURN: + if (__ctsvc_server_get_return_data()) { + ret = ctsvc_server_socket_return(__ctsvc_server_get_return_data(), ret, 0, NULL); + h_warn_if(CONTACTS_ERROR_NONE != ret, "ctsvc_server_socket_return() Failed(%d)", ret); + __ctsvc_server_set_return_data(NULL); + } + return; +} + +int ctsvc_server_sim_import(void* data) +{ + SERVER_FN_CALL; + int ret; + + h_retvm_if(false == ctsvc_server_sim_get_init_completed(), CONTACTS_ERROR_SYSTEM,"sim init is not completed"); + h_retvm_if(NULL != __ctsvc_server_get_return_data(), CONTACTS_ERROR_INTERNAL,"Helper is already processing with sim"); + + __ctsvc_server_set_return_data(data); + + sim_file_s *file = __ctsvc_server_sim_get_file_record(TAPI_PB_3G_NAME); + if(file->get_unused_count((void*)file) == file->get_index_max((void*)file)){ + ret = ctsvc_server_socket_return(__ctsvc_server_get_return_data(), CONTACTS_ERROR_NO_DATA, 0, NULL); + h_warn_if(CONTACTS_ERROR_SYSTEM != ret, "helper_socket_return() Failed(%d)", ret); + __ctsvc_server_set_return_data(NULL); + return ret; + } + + ret = tel_read_sim_pb_record(__ctsvc_server_get_tapi_handle(), __ctsvc_server_get_sim_type(), 1, + __ctsvc_server_sim_import_read_cb, NULL); + if (ret != TAPI_API_SUCCESS) { + ERR("tel_read_sim_pb_record = %d",ret); + __ctsvc_server_set_return_data(NULL); + return CONTACTS_ERROR_SYSTEM; + } + + return CONTACTS_ERROR_NONE; +} + +static void __ctsvc_server_sim_sdn_read_cb(TapiHandle *handle, int result, void *data, void *user_data) +{ + SERVER_FN_CALL; + int ret=0; + TelSimPbAccessResult_t sec_rt = result; + TelSimPbRecord_t *sim_info = data; + + h_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) { + SERVER_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, NULL); + h_retm_if(ret != TAPI_API_SUCCESS, "tel_read_sim_pb_record() Failed(%d)", ret); + } + 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); + h_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: + ERR("Unknown storage type(%d)", sim_info->phonebook_type); + goto ERROR_RETURN; + } + + if (sim_info->next_index && CTSVC_TAPI_SIM_PB_MAX != sim_info->next_index) { + SERVER_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, NULL); + if (TAPI_API_SUCCESS != ret) { + ERR("tel_read_sim_pb_record() Failed(%d)", ret); + goto ERROR_RETURN; + } + } + else { + // read SDN done ( success ) + // sim_data = NULL; + ctsvc_server_trim_memory(); + } + return; + +ERROR_RETURN: + // sim_data = NULL; + ctsvc_server_trim_memory(); + return; +} + +int ctsvc_server_sim_read_sdn(void* data) +{ + SERVER_FN_CALL; + int ret, card_changed = 0; + TelSimCardStatus_t sim_status; + + h_retvm_if(NULL != __ctsvc_server_get_return_data(), CONTACTS_ERROR_INVALID_PARAMETER, + "Helper is already processing with sim"); + ret = tel_get_sim_init_info(__ctsvc_server_get_tapi_handle(), &sim_status, &card_changed); + if(TAPI_API_SUCCESS != ret) { + ERR("tel_get_sim_init_info() Failed(%d)", ret); + SERVER_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(); + if(CONTACTS_ERROR_NONE != ret) { + 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(); + if(CONTACTS_ERROR_NONE != ret) { + ERR("__ctsvc_server_delete_SDN_contact() Failed(%d)", ret); + goto ERROR_RETURN; + } + + ret = tel_read_sim_pb_record(__ctsvc_server_get_tapi_handle(), TAPI_SIM_PB_SDN, + 1, __ctsvc_server_sim_sdn_read_cb, NULL); + if(TAPI_API_SUCCESS != ret) { + ERR("tel_read_sim_pb_record() Failed(%d)", ret); + ret = CONTACTS_ERROR_SYSTEM; + goto ERROR_RETURN; + } + } + + return CONTACTS_ERROR_NONE; + +ERROR_RETURN: + ctsvc_server_trim_memory(); + return ret; +} + +static void __ctsvc_server_sim_initialize_cb(TapiHandle *handle, int result, void *data, void *user_data) +{ + SERVER_FN_CALL; + int i=0; + TelSimPbAccessResult_t access_rt = result; + TelSimPbType_t sim_type = __ctsvc_server_get_sim_type(); + + SERVER_DBG("sim_type = %d",sim_type); + if (TAPI_SIM_PB_3GSIM == sim_type) { + TelSimPbCapabilityInfo_t *capa = data; + h_retm_if(capa == NULL, "capa is NULL result =%d",access_rt); + + for (i=0; i < capa->FileTypeCount; i++) { + sim_file_s *file_record = NULL; + int type = capa->FileTypeInfo[i].field_type; + SERVER_DBG("TYPE = %d",type); + file_record = __ctsvc_server_sim_get_file_record(type); + file_record->set(file_record,capa->FileTypeInfo[i].index_max, capa->FileTypeInfo[i].text_max, + capa->FileTypeInfo[i].used_count); + SERVER_DBG(" field_type[%d] : i_max(%d), t_max(%d), un_count(%d)", type, + gfile_record[type].get_index_max(&gfile_record[type]), gfile_record[type].get_text_max(&gfile_record[type]), gfile_record[type].get_unused_count(&gfile_record[type])); + } + } + else if(TAPI_SIM_PB_ADN == sim_type){ + TelSimPbEntryInfo_t *pe = data; + h_retm_if(pe == NULL, "pe is NULL result =%d",access_rt); + sim_file_s *file_record = NULL; + file_record =__ctsvc_server_sim_get_file_record(CTSVC_2GSIM_NAME); + file_record->set(file_record,pe->PbIndexMax,pe->PbTextLenMax,pe->PbIndexMin); + SERVER_DBG(" CTSVC_2GSIM_NAME : i_max(%d), t_max(%d), i_min(%d)", pe->PbIndexMax,pe->PbTextLenMax,pe->PbIndexMin); + + file_record =__ctsvc_server_sim_get_file_record(CTSVC_2GSIM_NUMBER); + file_record->set(file_record,pe->PbIndexMax,pe->PbNumLenMax,pe->PbIndexMin); + SERVER_DBG(" CTSVC_2GSIM_NUMBER : i_max(%d), t_max(%d), i_min(%d)", pe->PbIndexMax,pe->PbNumLenMax,pe->PbIndexMin); + } + else{ + ERR("sim_type [%d]error ", sim_type); + return; + } + __ctsvc_server_sim_set_init_completed(true); + return; +} + +int ctsvc_server_sim_initialize(void) +{ + SERVER_FN_CALL; + contacts_error_e err = CONTACTS_ERROR_NONE; + __ctsvc_server_get_tapi_handle(); + __ctsvc_server_set_sim_type(); + + err = contacts_connect2(); + if(err != CONTACTS_ERROR_NONE ){ + if (ghandle){ + tel_deinit(ghandle); + ghandle = NULL; + } + ERR("contacts_connect2 fail"); + return err; + } + + int ret = TAPI_API_SUCCESS; + TelSimPbType_t sim_type; + TapiHandle *sim_handle; + + __ctsvc_server_init_sim_file(); + + sim_type = __ctsvc_server_get_sim_type(); + sim_handle = __ctsvc_server_get_tapi_handle(); + + if(sim_type == TAPI_SIM_PB_3GSIM) + ret = tel_get_sim_pb_usim_meta_info(sim_handle, __ctsvc_server_sim_initialize_cb, NULL); + else if(sim_type == TAPI_SIM_PB_ADN) + ret = tel_get_sim_pb_meta_info(sim_handle, sim_type, __ctsvc_server_sim_initialize_cb, NULL); + h_retvm_if(ret != TAPI_API_SUCCESS, CONTACTS_ERROR_SYSTEM, "tel_get_sim_(usim)_meta_info =%d",ret); + + return CONTACTS_ERROR_NONE; +} + + diff --git a/server/ctsvc_server_sim.h b/server/ctsvc_server_sim.h new file mode 100755 index 0000000..e9cb5a2 --- /dev/null +++ b/server/ctsvc_server_sim.h @@ -0,0 +1,46 @@ +/* + * Contacts Service Helper + * + * 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__ + +typedef struct { + int sim_index; + int contact_id; + int next_index; + 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_initialize(void); +int ctsvc_server_sim_finalize(void); +int ctsvc_server_sim_import(void* data); +int ctsvc_server_sim_read_sdn(void* data); +bool ctsvc_server_sim_get_init_completed(void); +void ctsvc_server_sim_destroy_contact_record(sim_contact_s *record); + +#endif // __CTSVC_SERVER_SIM_H__ + diff --git a/server/ctsvc_server_socket.c b/server/ctsvc_server_socket.c new file mode 100644 index 0000000..e4355a9 --- /dev/null +++ b/server/ctsvc_server_socket.c @@ -0,0 +1,230 @@ +/* + * Contacts Service Helper + * + * 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 <contacts.h> + +#include "internal.h" +#include "ctsvc_struct.h" +#include "ctsvc_schema.h" +#include "ctsvc_sqlite.h" +#include "ctsvc_socket.h" +#include "ctsvc_server_socket.h" +#include "ctsvc_server_sim.h" + +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) +{ + SERVER_FN_CALL; + int ret; + ctsvc_socket_msg_s msg = {0}; + + // h_retvm_if(CONTACTS_ERROR_SYSTEM == value, value, "Socket has problems"); + h_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)); + + SERVER_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)); + h_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_import_sim(GIOChannel *src) +{ + SERVER_FN_CALL; + int ret; + + ret = ctsvc_server_sim_import(src); + if (CONTACTS_ERROR_NONE != ret) { + ERR("ctsvc_server_sim_import() Failed(%d)", ret); + ctsvc_server_socket_return(src, ret, 0, NULL); + } +} +
+static void __ctsvc_server_socket_get_sim_init_status(GIOChannel *src)
+{
+ SERVER_FN_CALL;
+
+ int ret;
+ ret = ctsvc_server_socket_return_sim_int(src, ctsvc_server_sim_get_init_completed());
+ h_retm_if(CONTACTS_ERROR_NONE != ret, "ctsvc_server_socket_return_sim_int() Failed(%d)", ret);
+}
+
+int ctsvc_server_socket_return_sim_int(GIOChannel *src, int value)
+{
+ SERVER_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);
+ h_retvm_if(CONTACTS_ERROR_NONE != ret, CONTACTS_ERROR_SYSTEM, "ctsvc_server_socket_return() Failed(%d)", ret);
+ INFO("count_str : %s", count_str);
+ ret = __ctsvc_server_socket_safe_write(g_io_channel_unix_get_fd(src), count_str, str_len);
+ h_retvm_if(-1 == ret, CONTACTS_ERROR_SYSTEM, "__ctsvc_server_socket_safe_write() Failed(errno = %d)", errno);
+
+ return CONTACTS_ERROR_NONE;
+} + +static gboolean __ctsvc_server_socket_request_handler(GIOChannel *src, GIOCondition condition, + gpointer data) +{ + int ret; + ctsvc_socket_msg_s msg = {0}; + SERVER_FN_CALL; + + if (G_IO_HUP & condition) { + close(g_io_channel_unix_get_fd(src)); + return FALSE; + } + + ret = __ctsvc_server_socket_safe_read(g_io_channel_unix_get_fd(src), (char *)&msg, sizeof(msg)); + h_retvm_if(-1 == ret, TRUE, "__ctsvc_server_socket_safe_read() Failed(errno = %d)", errno); + + SERVER_DBG("attach number = %d", msg.attach_num); + + switch (msg.type) { + case CTSVC_SOCKET_MSG_TYPE_REQUEST_IMPORT_SIM: + __ctsvc_server_socket_import_sim(src); + break; + case CTSVC_SOCKET_MSG_TYPE_REQUEST_SIM_INIT_COMPLETE:
+ __ctsvc_server_socket_get_sim_init_status(src);
+ break; + default: + ERR("Unknown request type(%d)", msg.type); + break; + } + return TRUE; +} + +static gboolean __ctsvc_server_socket_handler(GIOChannel *src, + GIOCondition condition, gpointer data) +{ + SERVER_FN_CALL; + + GIOChannel *channel; + int client_sockfd, sockfd = (int)data; + struct sockaddr_un clientaddr; + socklen_t client_len = sizeof(clientaddr); + + SERVER_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, __ctsvc_server_socket_request_handler, NULL); + g_io_channel_unref(channel); + + return TRUE; +} + +int ctsvc_server_socket_init(void) +{ + SERVER_FN_CALL; + + int sockfd, 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); + h_retvm_if(-1 == sockfd, CONTACTS_ERROR_SYSTEM, "socket() Failed(errno = %d)", errno); + + ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)); + h_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) + ERR("chown(%s) Failed(%d)", CTSVC_SOCKET_PATH, ret); + + ret = chmod(CTSVC_SOCKET_PATH, CTS_SECURITY_DEFAULT_PERMISSION); + if (0 != ret) + ERR("chmod(%s) Failed(%d)", CTSVC_SOCKET_PATH, ret); + + ret = listen(sockfd, 30); + h_retvm_if(-1 == ret, CONTACTS_ERROR_SYSTEM, "listen() Failed(errno = %d)", errno); + + gio = g_io_channel_unix_new(sockfd); + g_io_add_watch(gio, G_IO_IN, __ctsvc_server_socket_handler, (gpointer)sockfd); + + SERVER_DBG("enter here!!!!!"); + DBG("enter here!!!!!"); + return CONTACTS_ERROR_NONE; +} + diff --git a/server/ctsvc_server_socket.h b/server/ctsvc_server_socket.h new file mode 100644 index 0000000..33b897c --- /dev/null +++ b/server/ctsvc_server_socket.h @@ -0,0 +1,28 @@ +/*
+ * Contacts Service Helper
+ *
+ * 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_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 index 0000000..b0b40f7 --- /dev/null +++ b/server/ctsvc_server_sqlite.c @@ -0,0 +1,421 @@ +/* + * Contacts Service Helper + * + * 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 "internal.h" +#include "contacts.h" +#include "ctsvc_schema.h" +#include "ctsvc_sqlite.h" +#include "ctsvc_notify.h" +#include "ctsvc_normalize.h" +#include "ctsvc_server_utils.h" + +#include "ctsvc_notification.h" +#include "ctsvc_db_plugin_contact_helper.h" +#include "ctsvc_person.h" +#include "ctsvc_phonelog.h" + +static sqlite3 *server_db; + +int ctsvc_server_db_open(sqlite3 **db) +{ + SERVER_FN_CALL; + int ret; + + if (!server_db) { + ret = db_util_open(CTSVC_DB_PATH, &server_db, 0); + h_retvm_if(ret != SQLITE_OK, CONTACTS_ERROR_DB, + "db_util_open() Failed(%d)", ret); + + ret = sqlite3_create_function(server_db, "_CONTACT_DELETE_", 3, SQLITE_UTF8, NULL, + ctsvc_db_contact_delete_callback, NULL, NULL); + h_retvm_if(SQLITE_OK != ret, CONTACTS_ERROR_DB, + "sqlite3_create_function() Failed(%d)", ret); + ret = sqlite3_create_function(server_db, "_DATA_DELETE_", 2, SQLITE_UTF8, NULL, + ctsvc_db_data_delete_callback, NULL, NULL); + h_retvm_if(SQLITE_OK != ret, CONTACTS_ERROR_DB, + "sqlite3_create_function() Failed(%d)", ret); + ret = sqlite3_create_function(server_db, "_PHONE_LOG_DELETE_", 1, SQLITE_UTF8, NULL, + ctsvc_db_phone_log_delete_callback, NULL, NULL); + h_retvm_if(SQLITE_OK != ret, CONTACTS_ERROR_DB, + "sqlite3_create_function() Failed(%d)", ret); + ret = sqlite3_create_function(server_db, "_PERSON_DELETE_", 1, SQLITE_UTF8, NULL, + ctsvc_db_person_delete_callback, NULL, NULL); + h_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) { + ERR("sqlite3_exec() Failed(%d)", ret); + return CONTACTS_ERROR_DB; + } + return CONTACTS_ERROR_NONE; +} + +#define CTS_COMMIT_TRY_MAX 3 +int ctsvc_server_end_trans(bool success) +{ + int ret = -1, i=0; + char *errmsg = NULL; + + if (success) { + ret = sqlite3_exec(server_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(server_db, "COMMIT TRANSACTION", + NULL, NULL, NULL); + } + if (SQLITE_OK != ret) { + ERR("sqlite3_exec() Failed(%d)", ret); + sqlite3_exec(server_db, "ROLLBACK TRANSACTION", + NULL, NULL, NULL); + return CONTACTS_ERROR_DB; + } + } + } + else { + sqlite3_exec(server_db, "ROLLBACK TRANSACTION", NULL, NULL, NULL); + } + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_server_update_default_language(int prev_lang, int new_lang, int second_lang) +{ + SERVER_FN_CALL; + int ret; + sqlite3* db = NULL; + char *errmsg = NULL; + char query[CTS_SQL_MIN_LEN] = {0}; + + ret = ctsvc_server_db_open(&db); + h_retvm_if(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_server_db_open() Failed(%d)", ret); + + ret = ctsvc_server_begin_trans(); + h_retvm_if(ret, ret, "ctsvc_server_begin_trans() Failed(%d)", ret); + + if (prev_lang == second_lang) { + snprintf(query, sizeof(query), "UPDATE %s SET display_name_language=%d WHERE display_name_language =%d" , + CTS_TABLE_CONTACTS, CTSVC_LANG_SECONDARY, CTSVC_LANG_DEFAULT); + } + else { + snprintf(query, sizeof(query), "UPDATE %s SET display_name_language=%d WHERE display_name_language = %d" , + CTS_TABLE_CONTACTS, prev_lang, CTSVC_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); + ctsvc_server_end_trans(false); + ctsvc_server_db_close(); + return CONTACTS_ERROR_DB; + } + + if (new_lang == second_lang) { + snprintf(query, sizeof(query), "UPDATE %s SET display_name_language=%d WHERE display_name_language=%d", + CTS_TABLE_CONTACTS, CTSVC_LANG_DEFAULT, CTSVC_LANG_SECONDARY); + } + else { + snprintf(query, sizeof(query), "UPDATE %s SET display_name_language=%d WHERE display_name_language=%d", + CTS_TABLE_CONTACTS, CTSVC_LANG_DEFAULT, 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); + ctsvc_server_end_trans(false); + ctsvc_server_db_close(); + return CONTACTS_ERROR_DB; + } + + ret = ctsvc_server_set_default_language(new_lang); + if (CONTACTS_ERROR_NONE != ret) { + ctsvc_server_end_trans(false); + ctsvc_server_db_close(); + return ret; + } + ret = ctsvc_server_end_trans(true); + ctsvc_server_db_close(); + + return ret; +} + +int ctsvc_server_update_secondary_language(int prev_lang, int new_lang) +{ + int ret; + sqlite3* db = NULL; + char *errmsg = NULL; + char query[CTS_SQL_MIN_LEN] = {0}; + + ret = ctsvc_server_db_open(&db); + h_retvm_if(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_server_db_open() Failed(%d)", ret); + + ret = ctsvc_server_begin_trans(); + h_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_lang, CTSVC_LANG_SECONDARY); + + 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); + 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_LANG_SECONDARY, 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); + ctsvc_server_end_trans(false); + ctsvc_server_db_close(); + return CONTACTS_ERROR_DB; + } + + ret = ctsvc_server_set_secondary_language(new_lang); + if (CONTACTS_ERROR_NONE != ret) { + ctsvc_server_end_trans(false); + ctsvc_server_db_close(); + return ret; + } + ret = ctsvc_server_end_trans(true); + ctsvc_server_db_close(); + + return ret; +} + +int ctsvc_server_insert_sdn_contact(const char *name, const char *number) +{ +#if 1 + int ret; + sqlite3* db = NULL; + sqlite3_stmt* stmt = NULL; + char query[CTS_SQL_MIN_LEN] = {0}; + + ret = ctsvc_server_db_open(&db); + h_retvm_if(CONTACTS_ERROR_NONE != ret, ret, "ctsvc_server_db_open() Failed(%d)", ret); + + snprintf(query, sizeof(query), "INSERT INTO %s(name, number) VALUES(?,?)", + CTS_TABLE_SDN); + + 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)); + 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); + + ret = sqlite3_step(stmt); + if (SQLITE_DONE != ret) { + ERR("sqlite3_step() Failed(%d)", ret); + sqlite3_finalize(stmt); + ctsvc_server_db_close(); + return CONTACTS_ERROR_DB; + } + sqlite3_finalize(stmt); + + ctsvc_server_db_close(); +#else + contacts_record_h record; + contacts_record_create(_contacts_sdn._uri, &record); + contacts_record_set_str(record, _contacts_sdn.name, name); + contacts_record_set_str(record, _contacts_sdn.number, number); + contacts_db_insert_record(record); + contacts_record_destroy(record, true); +#endif + + return CONTACTS_ERROR_NONE; +} + +int ctsvc_server_delete_sdn_contact(void) +{ + int ret; + sqlite3* db = NULL; + sqlite3_stmt* stmt = NULL; + char query[CTS_SQL_MAX_LEN] = {0}; + + ret = ctsvc_server_db_open(&db); + h_retvm_if(CONTACTS_ERROR_NONE != ret, ret, "helper_db_open() Failed(%d)", ret); + + snprintf(query, sizeof(query), "DELETE FROM %s", CTS_TABLE_SDN); + + 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)); + ctsvc_server_db_close(); + return CONTACTS_ERROR_DB; + } + ret = sqlite3_step(stmt); + if (SQLITE_DONE != ret) { + 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}; + +// char dest[CTS_SQL_MIN_LEN] = {0}; + + ret = ctsvc_server_db_open(&db); + h_retvm_if(CONTACTS_ERROR_NONE != ret, ret, "helper_db_open() Failed(%d)", ret); + + ret = ctsvc_server_begin_trans(); + if(CONTACTS_ERROR_NONE != ret) { + ERR("ctsvc_server_begin_trans() Failed(%d)", ret); + ctsvc_server_db_close(); + return ret; + } + + snprintf(query, sizeof(query), + "SELECT contact_id, display_name, reverse_display_name " + "FROM "CTS_TABLE_CONTACTS" WHERE deleted = 0"); + 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)); + ctsvc_server_end_trans(false); + ctsvc_server_db_close(); + 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) { + ERR("sqlite3_prepare_v2(%s) Failed(%s)", query, sqlite3_errmsg(db)); + sqlite3_finalize(stmt); + ctsvc_server_end_trans(false); + ctsvc_server_db_close(); + return CONTACTS_ERROR_DB; + } + + while (SQLITE_ROW == (ret = sqlite3_step(stmt))) { + + int contact_id = sqlite3_column_int(stmt, 0); + char *display_name = (char*)sqlite3_column_text(stmt, 1); + char *reverse_display_name = (char*)sqlite3_column_text(stmt, 2); + char *sortkey = NULL; + char *reverse_sortkey = NULL; + + + ret = ctsvc_collation_str(display_name, &sortkey); + if (CONTACTS_ERROR_NONE == ret && sortkey) + sqlite3_bind_text(update_stmt, 1, sortkey, strlen(sortkey), SQLITE_STATIC); + + ret = ctsvc_collation_str(reverse_display_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) { + ERR("sqlite3_exec(%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(); + return CONTACTS_ERROR_DB; + } + + sqlite3_reset(update_stmt); + + } + + if (SQLITE_ROW != ret && SQLITE_DONE != ret) { + ERR("sqlite3_step() Failed(%d)", ret); + sqlite3_finalize(update_stmt); + sqlite3_finalize(stmt); + ctsvc_server_end_trans(false); + ctsvc_server_db_close(); + return CONTACTS_ERROR_DB; + } + + sqlite3_finalize(update_stmt); + sqlite3_finalize(stmt); + + ret = ctsvc_server_end_trans(true); + if (CONTACTS_ERROR_NONE == ret) { + int fd = open(CTSVC_NOTI_CONTACT_CHANGED, O_TRUNC | O_RDWR); + if (0 <= fd) + close(fd); + } + ctsvc_server_db_close(); + + return ret; +} diff --git a/server/ctsvc_server_sqlite.h b/server/ctsvc_server_sqlite.h new file mode 100755 index 0000000..80bab7e --- /dev/null +++ b/server/ctsvc_server_sqlite.h @@ -0,0 +1,34 @@ +/* + * Contacts Service Helper + * + * 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_SQLITE_H__ +#define __CTSVC_SERVER_SQLITE_H__ + +#include <sqlite3.h> + +int ctsvc_server_db_open(sqlite3 **db); +int ctsvc_server_db_close(void); +int ctsvc_server_update_default_language(int system_lang, int default_lang, int second_lang); +int ctsvc_server_update_secondary_language(int prev_lang, int new_lang); +int ctsvc_server_insert_sdn_contact(const char *name, const char *number); +int ctsvc_server_delete_sdn_contact(void); +int ctsvc_server_update_collation(); + +#endif // __CTSVC_SERVER_SQLITE_H__ + + diff --git a/server/ctsvc_server_utils.c b/server/ctsvc_server_utils.c new file mode 100755 index 0000000..2de84f7 --- /dev/null +++ b/server/ctsvc_server_utils.c @@ -0,0 +1,197 @@ +/* + * Contacts Service Helper + * + * 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 <contacts.h> +#include <vconf.h> +#include <vconf-keys.h> + +#include "internal.h" +#include "ctsvc_setting.h" +#include "ctsvc_server_utils.h" +#include "ctsvc_server_sim.h" +#include "ctsvc_server_sqlite.h" +#include "ctsvc_localize.h" +#include "ctsvc_normalize.h" + +static const char *CTSVC_SERVER_VCONF_TAPI_SIM_PB_INIT = VCONFKEY_TELEPHONY_SIM_PB_INIT; +static const char *CTSVC_SERVER_VCONF_SYSTEM_LANGUAGE = VCONFKEY_LANGSET; + + +static int default_language = -1; +static int system_language = -1; +static int secondary_language = -1; + +inline int ctsvc_server_set_default_language(int lang) +{ + int ret = vconf_set_int(ctsvc_get_default_language_vconfkey(), lang); + h_retvm_if(ret<0, CONTACTS_ERROR_INTERNAL, "vconf_set_int() Failed(%d)", ret); + + default_language = lang; + return CONTACTS_ERROR_NONE; +} + +inline int ctsvc_server_set_secondary_language(int lang) +{ + int ret = vconf_set_int(ctsvc_get_secondary_language_vconfkey(), lang); + h_retvm_if(ret<0, CONTACTS_ERROR_SYSTEM, "vconf_set_int() Failed(%d)", ret); + + secondary_language = lang; + return CONTACTS_ERROR_NONE; +} + +static void ctsvc_server_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(ctsvc_get_default_language_vconfkey(), &default_language); + h_retm_if(ret<0, "vconf_get_int() Failed(%d)", ret); + } + + + system_language = ctsvc_get_language_type(langset); + DBG("system language(%d, %s)", system_language, langset); + if (system_language != default_language) + ret = ctsvc_server_update_default_language(default_language, system_language, secondary_language); +} + +static void ctsvc_server_change_secondary_language_cb(keynode_t *key, void *data) +{ + int ret = -1; + const char *langset; + int lang_type; + + langset = vconf_keynode_get_str(key); + if (!secondary_language) { + ret = vconf_get_int(ctsvc_get_secondary_language_vconfkey(), &secondary_language); + h_retm_if(ret<0, "vconf_get_int() Failed(%d)", ret); + } + + lang_type = ctsvc_get_language_type(langset); + if (lang_type != secondary_language) + ret = ctsvc_server_update_secondary_language(secondary_language, lang_type); +} + +static void ctsvc_server_update_collation_cb(keynode_t *key, void *data) +{ + ctsvc_server_update_collation(); +} + +static void ctsvc_server_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 = ctsvc_server_sim_read_sdn(NULL); + h_warn_if(CONTACTS_ERROR_NONE != ret, "ctsvc_server_sim_read_sdn() Failed(%d)", ret); + + ret = ctsvc_server_sim_initialize(); + h_warn_if(CONTACTS_ERROR_NONE != ret, "ctsvc_server_sim_initialize() Failed(%d)", ret); + + vconf_ignore_key_changed(CTSVC_SERVER_VCONF_TAPI_SIM_PB_INIT, ctsvc_server_tapi_sim_complete_cb); + } +} +void ctsvc_server_final_configuration(void) +{ + int ret = -1; + + ret = vconf_ignore_key_changed(CTSVC_SERVER_VCONF_SYSTEM_LANGUAGE, ctsvc_server_change_language_cb); + h_retm_if(ret<0,"vconf_ignore_key_changed(%s) Failed(%d)",CTSVC_SERVER_VCONF_SYSTEM_LANGUAGE,ret); + + ret = vconf_ignore_key_changed(VCONFKEY_REGIONFORMAT, ctsvc_server_update_collation_cb); + h_retm_if(ret<0,"vconf_ignore_key_changed(%s) Failed(%d)",VCONFKEY_REGIONFORMAT,ret); + + ctsvc_server_sim_finalize(); +} + +int ctsvc_server_init_configuration(void) +{ + int ret, sim_stat=-1; + const char *langset; + int lang_type; + + ret = vconf_get_int(ctsvc_get_default_language_vconfkey(), &default_language); + if (ret < 0) { + ERR("vconf_get_int(%s) Failed(%d)", ctsvc_get_default_language_vconfkey() ,ret); + default_language = 0; + } + + ret = vconf_get_int(ctsvc_get_secondary_language_vconfkey(), &secondary_language); + if (ret < 0) { + ERR("vconf_get_int(%s) Failed(%d)", ctsvc_get_secondary_language_vconfkey(),ret); + secondary_language = 0; + } + + ret = vconf_notify_key_changed(CTSVC_SERVER_VCONF_SYSTEM_LANGUAGE, + ctsvc_server_change_language_cb, NULL); + h_retvm_if(ret<0, CONTACTS_ERROR_SYSTEM, "vconf_notify_key_changed(%s) Failed(%d)", + CTSVC_SERVER_VCONF_SYSTEM_LANGUAGE, ret); + + ret = vconf_notify_key_changed(VCONFKEY_CONTACTS_SVC_SECONDARY_LANGUAGE, + ctsvc_server_change_secondary_language_cb, NULL); + h_retvm_if(ret<0, CONTACTS_ERROR_SYSTEM, "vconf_notify_key_changed(%s) Failed(%d)", + VCONFKEY_CONTACTS_SVC_SECONDARY_LANGUAGE, ret); + + ret = vconf_notify_key_changed(VCONFKEY_REGIONFORMAT, + ctsvc_server_update_collation_cb, NULL); + h_retvm_if(ret<0, CONTACTS_ERROR_SYSTEM, "vconf_notify_key_changed(%s) Failed(%d)", + VCONFKEY_REGIONFORMAT, ret); + + langset = vconf_get_str(CTSVC_SERVER_VCONF_SYSTEM_LANGUAGE); + h_warn_if(NULL == langset, "vconf_get_str(%s) return NULL", CTSVC_SERVER_VCONF_SYSTEM_LANGUAGE); + system_language = ctsvc_get_language_type(langset); + + langset = vconf_get_str(VCONFKEY_CONTACTS_SVC_SECONDARY_LANGUAGE); + h_warn_if(NULL == langset, "vconf_get_str(%s) return NULL", CTSVC_SERVER_VCONF_SYSTEM_LANGUAGE); + lang_type = ctsvc_get_language_type(langset); + if (secondary_language != lang_type) { + ERR("system lang(%s, %d), default lang(%d)", langset, lang_type, secondary_language); + ctsvc_server_update_secondary_language(secondary_language, lang_type); + } + + if (system_language != default_language) { + ERR("system lang(%s, %d), default lang(%d)", langset, system_language, default_language); + ctsvc_server_update_default_language(default_language, system_language, secondary_language); + } + + ret = vconf_get_int(CTSVC_SERVER_VCONF_TAPI_SIM_PB_INIT, &sim_stat); + if (VCONFKEY_TELEPHONY_SIM_PB_INIT_COMPLETED == sim_stat) { + ret = ctsvc_server_sim_read_sdn(NULL); + h_warn_if(CONTACTS_ERROR_NONE != ret, "ctsvc_server_sim_read_sdn() Failed(%d)", ret); + + ret = ctsvc_server_sim_initialize(); + h_warn_if(CONTACTS_ERROR_NONE != ret, "ctsvc_server_sim_initialize() Failed(%d)", ret); + } + else { + ret = vconf_notify_key_changed(CTSVC_SERVER_VCONF_TAPI_SIM_PB_INIT, + ctsvc_server_tapi_sim_complete_cb, NULL); + h_retvm_if(ret<0, CONTACTS_ERROR_SYSTEM, "vconf_notify_key_changed(%s) Failed(%d)", + CTSVC_SERVER_VCONF_TAPI_SIM_PB_INIT, ret); + } + + 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 index 0000000..38c0cbb --- /dev/null +++ b/server/ctsvc_server_utils.h @@ -0,0 +1,32 @@ +/* + * Contacts Service Helper + * + * 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_init_configuration(void); +void ctsvc_server_final_configuration(void); + +int ctsvc_server_get_default_language(void); +int ctsvc_server_set_default_language(int lang); +int ctsvc_server_set_secondary_language(int lang); + +void ctsvc_server_trim_memory(void); + +#endif // __CTSVC_SERVER_UTILS_H__ + diff --git a/server/internal.h b/server/internal.h new file mode 100755 index 0000000..f99e8fe --- /dev/null +++ b/server/internal.h @@ -0,0 +1,96 @@ +/* + * Contacts Service Helper + * + * 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_INTERNAL_H__ +#define __CTSVC_SERVER_INTERNAL_H__ + +#include <stdio.h> + +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + +// Additional Error +enum { + CTSVC_ERR_NO_DB_FILE = -10000, +}; + +#define SERVER_DLOG_OUT +#define SERVER_DEBUGGING + +#ifdef SERVER_DLOG_OUT +#define LOG_TAG "CONTACTS_SVC_SERVER" +#include <dlog.h> +#define DLOG(prio, fmt, arg...) \ + do { SLOG(prio, LOG_TAG, fmt, ##arg); } while (0) +#define INFO(fmt, arg...) SLOGI("[SERVER] "fmt, ##arg) +#define ERR(fmt, arg...) SLOGE("[SERVER] "fmt, ##arg) +#define DBG(fmt, arg...) SLOGD("[SERVER] "fmt, ##arg) +#else //SERVER_DLOG_OUT +#define PRT(prio, fmt, arg...) \ + do { fprintf((prio?stderr:stdout),"[SERVER] %s(%d): "fmt"\n", __FUNCTION__, __LINE__, ##arg); } while (0) +#define INFO(fmt, arg...) PRT(0, fmt, ##arg) +#define ERR(fmt, arg...) PRT(1, fmt, ##arg) +#define DBG(fmt, arg...) \ + do { \ + printf("\x1b[105;37m[SERVER]\x1b[0m(%s:%d) "fmt"\n", __FUNCTION__, __LINE__, ##arg); \ + } while (0) +#endif //SERVER_DLOG_OUT + +#ifdef SERVER_DEBUGGING +#define SERVER_FN_CALL DBG(">>>>>>>> called") +#define SERVER_FN_END DBG("<<<<<<<< ended") +#define SERVER_DBG(fmt, arg...) DBG(fmt, ##arg) +#else /* SERVER_DEBUGGING */ +#define SERVER_FN_CALL +#define SERVER_FN_END +#define SERVER_DBG(fmt, arg...) +#endif /* SERVER_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 // __CTSVC_SERVER_INTERNAL_H__ + |